I have a QTreeWidget inside a QGroupBox. If the branches on the tree expand or collapse the QGroupBox should resize rather than show scrollbars. The QGroupBox is in a window with no layout manager as in the full application the user has the ability to drag and resize the GroupBox around the window.
The code below almost does this. I have subclassed QTreeWidget and set its size hint to follow that of the viewport (QAbstractScrollClass) it contains. The viewport sizehint does respond to the changes in the tree branch expansion unlike the tree sizehint. I've then subclassed QGroupBox to adjust its size to the sizehint in its init method.
This part all works. When the gui first comes up the box matches the size of the expanded branches of the tree. Changing the expanded state in code results in the correctly sized box.
I then connected the TreeWidget's signals for itemExpanded and itemCollapsed to a function that calls box.adjustSize(). This bit doesn't work. The sizehint for the box stays stubbornly at the size first set when the box was first shown regardless of the user toggling the branches.
I've looked at size policies etc, and have written a nasty hacks that will work in some situations, but I'd like to figure out how to do this properly.
In the real app the adjustSize will be done I expect with signals but I've simplified here.
import sys
from PyQt5.QtWidgets import (
QApplication,
QWidget,
QGroupBox,
QVBoxLayout,
QTreeWidget,
QTreeWidgetItem,
)
from PyQt5.QtCore import QSize
class TreeWidgetSize(QTreeWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
def sizeHint(self):
w = QTreeWidget.sizeHint(self).width()
h = self.viewportSizeHint().height()
new_size = QSize(w, h + 10)
print(f"in tree size hint {new_size}")
return new_size
class GroupBoxSize(QGroupBox):
def __init__(self, title):
super().__init__(title)
print(f"box init {self.sizeHint()}")
self.adjustSize()
def test(item):
print(f"test sizehint {box.sizeHint()}")
print(f"test viewport size hint {tw.viewportSizeHint()}")
box.adjustSize()
app = QApplication(sys.argv)
win = QWidget()
win.setGeometry(100, 100, 400, 250)
win.setWindowTitle("No Layout Manager")
box = GroupBoxSize(win)
box.setTitle("fixed box")
box.move(10, 10)
layout = QVBoxLayout()
box.setLayout(layout)
l1 = QTreeWidgetItem(["String A"])
l2 = QTreeWidgetItem(["String B"])
for i in range(3):
l1_child = QTreeWidgetItem(["Child A" + str(i)])
l1.addChild(l1_child)
for j in range(2):
l2_child = QTreeWidgetItem(["Child B" + str(j)])
l2.addChild(l2_child)
tw = TreeWidgetSize()
tw.setColumnCount(1)
tw.setHeaderLabels(["Column 1"])
tw.addTopLevelItem(l1)
tw.addTopLevelItem(l2)
l1.setExpanded(False)
layout.addWidget(tw)
tw.itemExpanded.connect(test)
tw.itemCollapsed.connect(test)
win.show()
sys.exit(app.exec_())