[PyQt] QDockWidget sizing behavior

John Wiggins jwiggins at enthought.com
Mon Oct 11 15:17:21 BST 2010


Hello,

I'm laying out part of the UI for my app using a QMainWindow with no central
widget and 4 dock widgets. I'd like the dock widgets to be sized
proportionally to each other but they seem to ignore the value returned by
sizeHint(). Am I missing something?

- John

Here's a concrete example illustrating my problem:

import cPickle
import os.path
import sys
from PyQt4 import QtGui, QtCore

class _ViewContainer(QtGui.QMainWindow):
    """ This class is a container for a view that allows an initial size
    (specified as a tuple) to be set.
    """
    def __init__(self, size, main_window):
        QtGui.QMainWindow.__init__(self)
        # Save the size and main window.
        self._width, self._height = size
        self._main_window = main_window
        # set a minimum size to quiet Qt
        self.setMinimumSize(100, 100)
        self.setSizePolicy(QtGui.QSizePolicy.Preferred,
QtGui.QSizePolicy.Preferred)

    def minimumSizeHint(self):
        try:
            return self.centralWidget().minimumSizeHint()
        except AttributeError:
            return super(_ViewContainer, self).minimumSizeHint()

    def sizeHint(self):
        sh = self.centralWidget().sizeHint()
        if self._width > 0:
            if self._width > 1:
                w = self._width
            else:
                w = self._main_window.width() * self._width
            sh.setWidth(int(w))
        if self._height > 0:
            if self._height > 1:
                h = self._height
            else:
                h = self._main_window.height() * self._height
            sh.setHeight(int(h))
        return sh


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")

MainWindow.resize(QtCore.QSize(QtCore.QRect(0,0,800,600).size()).expandedTo(MainWindow.minimumSizeHint()))

        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0,0,800,21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)

        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow",
"MainWindow",
                                                                None,
QtGui.QApplication.UnicodeUTF8))


class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.createDockWindows()

    def closeEvent(self, event):
        self.saveLayout()
        super(MainWindow, self).closeEvent(event)

    def createDockWidget(self, name, size):
        dock = QtGui.QDockWidget(name, self)
        child = QtGui.QLabel(name)
        vc = _ViewContainer(size, self)
        dock.setWidget(vc)
        dock.setObjectName(name)
        self._qt4_adjust_widget_layout(child)
        dock.widget().setCentralWidget(child)

        return dock;

    def createDockWindows(self):
        dock1 = self.createDockWidget("Dock1", (0.5, 0.75))
        self.addDockWidget(QtCore.Qt.TopDockWidgetArea, dock1)
        dock2 = self.createDockWidget("Dock2", (0.5, 0.75))
        self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, dock2)
        dock3 = self.createDockWidget("Dock3", (0.5, 0.25))
        self.splitDockWidget(dock2, dock3, QtCore.Qt.Horizontal)
        dock4 = self.createDockWidget("Dock4", (0.5, 0.25))
        self.splitDockWidget(dock1, dock4, QtCore.Qt.Horizontal)

    def saveLayout(self):
        filename = './layout.dat'
        f = file(filename, 'w')
        state = str(self.saveState())
        cPickle.dump((0,state), f)
        f.close()

    def restoreLayout(self):
        filename = './layout.dat'
        if os.path.exists(filename):
            f = file(filename, 'r')
            vers, state = cPickle.load(f)
            f.close()
            self.restoreState(state)

    @staticmethod
    def _qt4_adjust_widget_layout(w):
        lay = w.layout()
        if lay is not None:
            lay.setAlignment(QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
            lay.setContentsMargins(0, 0, 0, 0)


def main():
    app = QtGui.QApplication(sys.argv)
    mainwindow = MainWindow()
    mainwindow.restoreLayout()
    mainwindow.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20101011/c6d47d99/attachment-0001.html>


More information about the PyQt mailing list