Question

When I minimize the application window on Windows XP and restore it later, the dock will be hidden. This has to do with view menu which has toggles to set visibility and of course is connected by signals.

I hope this will save someone a few hours of debugging.

Here is a full functional example with both wrong and right code:

# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui

class Ui_QMainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.resize(200, 200)
        self.menubar = QtGui.QMenuBar(self)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 27))
        self.menuMenu = QtGui.QMenu(self.menubar)
        self.setMenuBar(self.menubar)
        self.dock = QtGui.QDockWidget(self)
        self.dock.setObjectName("dock")
        self.dockContents = QtGui.QWidget()
        self.dockContents.setObjectName("dockContents")
        self.dock.setWidget(self.dockContents)
        self.addDockWidget(QtCore.Qt.DockWidgetArea(4), self.dock)
        self.action = QtGui.QAction(self)
        self.action.setCheckable(True)
        self.action.setChecked(True)
        self.action.setObjectName("action")
        self.menuMenu.addAction(self.action)
        self.menubar.addAction(self.menuMenu.menuAction())

        self.setWindowTitle("Example of dock remaining minimized")
        self.menuMenu.setTitle("Menu")
        self.dock.setWindowTitle("I'm a dock")
        self.action.setText("Dock visibility")

        if True:
            # This is NOT working on Windows XP.
            # Minimize the window and restore again, the dock is gone.
            # Other than that it works.
            QtCore.QObject.connect(self.action,
                                   QtCore.SIGNAL("toggled(bool)"),
                                   self.dock.setVisible)
            QtCore.QObject.connect(self.dock,
                                   QtCore.SIGNAL("visibilityChanged(bool)"),
                                   self.action.setChecked)
        else:
            # This DOES work, but boy it looks nasty, writing useless
            # per dock is not nice.
            QtCore.QObject.connect(self.action,
                                   QtCore.SIGNAL("triggered()"),
                                   self.toggle_dock)
            QtCore.QObject.connect(self.dock,
                                   QtCore.SIGNAL("visibilityChanged(bool)"),
                                   self.action.setChecked)

    def toggle_dock(self):
        self.dock.setVisible(not self.dock.isVisible())

def main():
    app = QtGui.QApplication(sys.argv)
    ui = Ui_QMainWindow()
    ui.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()
Was it helpful?

Solution

There is a much simpler way to do this, using QDock.toggleViewAction. This function returns a ready-made action that handles the checked state automatically.

So your code would become simply:

    self.action = self.dock.toggleViewAction()
    self.action.setObjectName("action")
    self.menuMenu.addAction(self.action)
    self.menubar.addAction(self.menuMenu.menuAction())

    self.setWindowTitle("Example of dock remaining minimized")
    self.menuMenu.setTitle("Menu")
    self.dock.setWindowTitle("I'm a dock")
    self.action.setText("Dock visibility")

and you can then get rid of all the signal handling.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top