Search code examples
pythonpyqtpyqt5qdockwidgetqlayout

Applying a layout to a QDockWidget in PyQt5


I'm trying to create a docked interface in PyQt5, creating a BoxLayout contining my various widgets, and then applying this layout to the QDockWidget.

My approach so far has been:

self.layout = QtWidgets.QBoxLayout(2)
self.layout.addWidget(self.widget_one)
self.layout.addWidget(self.widget_two)
self.docked = QtWidgets.QDockWidget()
self.docked.setLayout(self.layout)
self.docked.show()

I'm currently getting an error as follows:

QWidget::setLayout: Attempting to set QLayout "" on QDockWidget "", 
which already has a layout

However, in my code above I can't see where I have added a layout previously, and can't find anything in the documentation to aid me in fixing this.

Where have I gone wrong in my approach?


Solution

  • QDockWidget already have a default layout so that generates this error, the correct thing is to add an empty widget and in that widget place the layout you want:

    self.layout = QtWidgets.QBoxLayout(2)
    self.layout.addWidget(self.widget_one)
    self.layout.addWidget(self.widget_two)
    self.docked = QtWidgets.QDockWidget()
    self.dockedWidget = QtWidgets.QWidget()
    self.docked.setWidget(self.dockedWidget)
    self.dockedWidget.setLayout(self.layout)
    self.docked.show()
    

    Example:

    class DockDemo(QMainWindow):
        def __init__(self, parent=None):
            super(DockDemo, self).__init__(parent)
            self.setCentralWidget(QTextEdit())
    
            self.docked = QDockWidget("Dockable", self)
            self.addDockWidget(Qt.LeftDockWidgetArea, self.docked)
            self.dockedWidget = QWidget(self)
            self.docked.setWidget(self.dockedWidget)
            self.setWindowTitle("Dock demo")
            self.dockedWidget.setLayout(QVBoxLayout())
            for i in range(5):
                self.dockedWidget.layout().addWidget(QPushButton("{}".format(i)))
    
    
    if __name__ == '__main__':
        import sys
        app = QApplication(sys.argv)
        ex = DockDemo()
        ex.show()
        sys.exit(app.exec_())
    

    Screenshot:

    enter image description here