python - floating QDockWidget does not close when parentWidget closes -


i have 2 open mainwindows: mainwindowwithbutton , mainwindowwithdock. later contains qdockwidget.

is behaviour: when users makes dockwidget floatable , closes mainwindowwithdock, dockwidget doesn't close.

should behaviour: when users makes dockwidget floatable , closes mainwindowwithdock, dockwidget closes well.

notes:

  • reason "is behaviour": floating dockwidget seems independent it's parent
  • i cannot listen onclose / reject (as give false information in particular case.
  • the mainwindow not emit clear signals it's behaviour
  • it important, dockwidget closes before mainwindow closed. otherwise focus goes unexpected

example code :

from pyqt4 import qtcore, qtgui pyqt4 import qtcore, qtgui pyqt4.qtgui import qapplication, qdialog, qmainwindow import sys  try:     _fromutf8 = qtcore.qstring.fromutf8 except attributeerror:     def _fromutf8(s):         return s  try:     _encoding = qtgui.qapplication.unicodeutf8     def _translate(context, text, disambig):         return qtgui.qapplication.translate(context, text, disambig, _encoding) except attributeerror:     def _translate(context, text, disambig):         return qtgui.qapplication.translate(context, text, disambig)  class ui_mainwindowwithbutton(object):     def setupui(self, mainwindowwithbutton):         mainwindowwithbutton.setobjectname(_fromutf8("mainwindowwithbutton"))         mainwindowwithbutton.resize(567, 384)         self.centralwidget = qtgui.qwidget(mainwindowwithbutton)         self.centralwidget.setobjectname(_fromutf8("centralwidget"))         mainwindowwithbutton.setcentralwidget(self.centralwidget)      def retranslateui(self, mainwindowwithbutton):         mainwindowwithbutton.setwindowtitle(_translate("mainwindowwithbutton", "mainwindow", none))  class ui_mainwindowwithdock(object):     def setupui(self, mainwindowwithdock):         mainwindowwithdock.setobjectname(_fromutf8("mainwindowwithdock"))         mainwindowwithdock.resize(509, 316)         self.centralwidget = qtgui.qwidget(mainwindowwithdock)         self.centralwidget.setobjectname(_fromutf8("centralwidget"))         mainwindowwithdock.setcentralwidget(self.centralwidget)          # # # # # # # # # # # # # # # # # # # # # #         # # #     setup dock      # # # # # # # # #         # # # # # # # # # # # # # # # # # # # # # #         self.thedock = qtgui.qdockwidget(mainwindowwithdock)         self.thedock.setobjectname(_fromutf8("thedock"))         self.dockwidgetcontents = qtgui.qwidget(self.thedock)         self.dockwidgetcontents.setobjectname(_fromutf8("dockwidgetcontents"))         self.thedock.setwidget(self.dockwidgetcontents)         mainwindowwithdock.adddockwidget(qtcore.qt.dockwidgetarea(2), self.thedock)          self.retranslateui(mainwindowwithdock)         qtcore.qmetaobject.connectslotsbyname(mainwindowwithdock)      def retranslateui(self, mainwindowwithdock):         mainwindowwithdock.setwindowtitle(_translate("mainwindowwithdock", "mainwindow", none))  class mainwindowwithbuttondlg(qmainwindow):     pass  class mainwindowwithdockdlg(qmainwindow):     pass  def main():     app = qapplication(sys.argv)      windowwithdockui = ui_mainwindowwithdock()     windowwithdock = mainwindowwithdockdlg()     windowwithdockui.setupui(windowwithdock)     windowwithdock.show()     app.exec()      # dock widget should closed      ui = ui_mainwindowwithbutton()     window = mainwindowwithbuttondlg()     ui.setupui(window)     window.show()     app.exec()    if __name__ == '__main__':     main() 

reject method of original source. here have qdialog qmainwindow it's central widget - therefore becomes qmainwindow in sense(from anki addcards.py (scroll bottom):

def reject(self):     if not self.canclose(): # way of calling problem: might leave method without doing         return     remhook('reset', self.onreset)     remhook('currentmodelchanged', self.onmodelchange)     clearaudioqueue()     self.removetempnote(self.editor.note)     self.editor.setnote(none)     self.modelchooser.cleanup()     self.deckchooser.cleanup()     self.mw.maybereset()     savegeom(self, "add")     aqt.dialogs.close("addcards")     qdialog.reject(self) 

you can use event-filter monitor events of given window. before window closes, always post close-event. doesn't matter whether window has modified normal closing process or not. if , when closes, accept property of corresponding close-event guaranteed true. so, if watch event, can check see if accepted, , act accordingly.

the main problem solve how find right window watch. @ time dock-widget created, may not accessible. 1 approach wait until parent of dock-widget first shown, top-level window , install event-filter on that. doing things way means dock-widget never needs know window dependant upon.

below working demo of approach based on example (with of irrelevant stuff removed):

import sys pyqt4 import qtcore, qtgui pyqt4.qtgui import qapplication, qdialog, qmainwindow  class eventwatcher(qtcore.qobject):     def __init__(self, parent):         qtcore.qobject.__init__(self, parent)         parent.installeventfilter(self)      def eventfilter(self, source, event):         if source self.parent():             if event.type() == qtcore.qevent.show:                 target = source.parent()                 while target.parent() not none:                     target = target.parent()                 print('found target window: %r' % target)                 source.removeeventfilter(self)                 target.installeventfilter(self)         elif event.type() == qtcore.qevent.close:             source.closeevent(event)             print('test filter accepted: %s' % event.isaccepted())             if event.isaccepted():                 self.parent().close()             return true         return qtcore.qobject.eventfilter(self, source, event)  class ui_mainwindowwithdock(object):     def setupui(self, mainwindowwithdock):         self.thedock = qtgui.qdockwidget(mainwindowwithdock)         mainwindowwithdock.adddockwidget(qtcore.qt.dockwidgetarea(2), self.thedock)         # add event watcher         eventwatcher(self.thedock)  class mainwindowwithdockdlg(qmainwindow):     pass  # mock-up class testing class mockdialog(qdialog):     def __init__(self):         qdialog.__init__(self)         windowwithdock = mainwindowwithdockdlg()         windowwithdockui = ui_mainwindowwithdock()         windowwithdockui.setupui(windowwithdock)         layout = qtgui.qvboxlayout(self)         layout.addwidget(windowwithdock)         self.canclose = false      def reject(self):         if not self.canclose:             self.canclose = true             return         qdialog.reject(self)      def closeevent(self, event):         qdialog.closeevent(self, event)         print('test close accepted: %s' % event.isaccepted())  def main():     app = qapplication(sys.argv)      dialog = mockdialog()     dialog.show()     app.exec_()      # dock widget should closed      window = qmainwindow()     window.show()     app.exec_()  if __name__ == '__main__':     main() 

Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -