Issue
I have a QDockWidget and I have put some widgets on it's titlebar like in this 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()
But as you can see in the following giph, the dock is not collapsable due to the widgets in the sidebar. How can I allow the widgets to get out of screen and resize the dock freely?
Solution
That depends by the fact that the dock widget sets the minimum width based on that of the title bar widget: if no explicit minimum width is set, then the width returned by minimumSizeHint()
is used.
A possible solution is to subclass the layout and reimplement both minimumWidth()
and setGeometry()
.
The first ensures that the title bar can be resized to a smaller width, while the second lays outs the items by ignoring the given geometry at all.
The result is, obviously, that part of the title bar will be hidden.
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()
Note that:
- setting the
Minimum
size policy on the label is not required in this situation (and you probably should needMaximum
instead, consider that QSizePolicy flags have names that are unintuitive at first); - you're calling
setTitleBarWidget
twice; - setting the alignment on the layout has usually little use (and is almost useless in this specific case): it doesn't tell the alignment of the child items, it specifies the alignment that layout manager will have once it's set on a parent widget or added to another layout;
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.