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