标题栏中带有小部件的 QDockWidget 无法折叠

QDockWidget with widgets in titlebar can't be collapsed

我有一个 QDockWidget,我在它的标题栏上放了一些小部件,就像在这个 MRE 中一样:

from PySide6.QtCore import Qt
from PySide6.QtWidgets import (QWidget, QCheckBox, QMainWindow, QLabel, QDockWidget, QApplication, QHBoxLayout,
                               QSizePolicy)


class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        central_widget = QLabel("Window stuff!")
        self.setCentralWidget(central_widget)

        self.dock = QDockWidget()

        self.docker_layout = QHBoxLayout()
        self.docker_layout.setContentsMargins(0, 0, 0, 0)
        self.docker_layout.setAlignment(Qt.AlignLeft)

        container = QWidget()
        container.setLayout(self.docker_layout)
        label = QLabel("Docker name")
        label.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.dock.setTitleBarWidget(container)

        # Widgets creation:
        self.docker_layout.addWidget(label)
        self.check_1 = QCheckBox("Check 1")
        self.docker_layout.addWidget(self.check_1)
        self.check_2 = QCheckBox("Check 2", checked=True)
        self.docker_layout.addWidget(self.check_2)
        self.check_3 = QCheckBox("Check 3", checked=True)
        self.docker_layout.addWidget(self.check_3)
        self.check_4 = QCheckBox("You cant hide me haha!", checked=True)
        self.docker_layout.addWidget(self.check_4)

        self.dock.setTitleBarWidget(container)

        self.addDockWidget(Qt.RightDockWidgetArea, self.dock)

        self.dock_content = QLabel("Dock stuff!")
        self.dock.setWidget(self.dock_content)

        self.show()


if __name__ == "__main__":
    app = QApplication([])
    window = MainWindow()
    app.exec()

但是正如您在下面的 giph 中看到的那样,由于侧边栏中的小部件,停靠栏不可折叠。我怎样才能让小部件离开屏幕并自由调整扩展坞的大小?

这取决于停靠栏小部件根据标题栏小部件设置最小宽度的事实:如果未设置明确的最小宽度,则使用 minimumSizeHint() 返回的宽度。

一个可能的解决方案是将布局子类化并重新实现 minimumWidth()setGeometry()

第一个确保标题栏可以调整到更小的宽度,而第二个通过完全忽略给定的几何图形来布置项目。

结果,显然,标题栏的那部分将被隐藏。

class IgnoreWidthLayout(QHBoxLayout):
    def minimumSize(self):
        return QSize(80, super().minimumSize().height())

    def setGeometry(self, geometry):
        geometry.setWidth(super().minimumSize().width())
        super().setGeometry(geometry)

class MainWindow(QMainWindow):
    def __init__(self):
        # ...
        self.docker_layout = IgnoreWidthLayout()

注意:

  1. 在这种情况下不需要在标签上设置 Minimum 大小策略(您可能应该需要 Maximum,考虑到 QSizePolicy 标志的名称一开始并不直观);
  2. 您正在调用 setTitleBarWidget 两次;
  3. 在布局上设置对齐方式通常没什么用(在这种特定情况下几乎没有用):它不会告诉 child 项目的对齐方式,它指定布局管理器将要对齐的方式一旦它被设置在 parent 小部件上或添加到另一个布局中;