Search code examples
pythonpyqt5qtreeviewqtreewidget

Increase the size of qtreewidget


It turned out to be a problem for me to make a signal for Qtreewidget in PyQT5. You need to increase the size of QTreeWidget when you click "increase" and decrease it when you click again (like a filter in Excel) like this

Code:

 self.tree_countries.setGeometry(QRect(1050, 100, 200, 250))
 self.tree_countries.setHeaderHidden(True)
 self.tree_countries.setStyleSheet("QTreeWidget {\n"
                                   "border: 1px solid #3b3838;\n"
                                   "font: 57 12pt \"Google Sans Medium\";\n"
                                   "color: white;\n"
                                   "background-color: #3b3838\n"
                                   "}\n")
 sql = filter_sql()
 parent = QTreeWidgetItem(self.tree_countries)
 parent.setText(0, "Страна")
 parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
 for country in sql.all_countries():
     country = str(country)
     child = QTreeWidgetItem(parent)
     child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
     child.setText(0, country[2:-3])
     child.setCheckState(0, Qt.Unchecked)
 self.tree_countries.show()

Solution

  • If you want to change the height of the QTreeWidget depending on whether the child items are expanded or collapsed then you must use the expanded and collapsed signals. You must also calculate the desired height.

    from PyQt5 import QtCore, QtWidgets
    
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super().__init__(parent)
    
            self.tree = QtWidgets.QTreeWidget()
            self.tree.header().hide()
    
            root_item = QtWidgets.QTreeWidgetItem(self.tree)
            root_item.setText(0, "root")
            root_item.setFlags(
                root_item.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable
            )
    
            for i in range(10):
                child = QtWidgets.QTreeWidgetItem(root_item)
                child.setFlags(child.flags() | QtCore.Qt.ItemIsUserCheckable)
                child.setText(0, "Child-{}".format(i))
                child.setCheckState(0, QtCore.Qt.Unchecked)
    
            central_widget = QtWidgets.QWidget()
            self.setCentralWidget(central_widget)
            lay = QtWidgets.QVBoxLayout(central_widget)
            lay.addWidget(self.tree)
            lay.addStretch(1)
    
            self.tree.collapsed.connect(self.handle_collapsed)
            self.tree.expanded.connect(self.handle_expanded)
    
        def handle_collapsed(self, index):
            h = self.tree.rowHeight(index) + self.tree.header().height() + 1
            self.adjust_height(h)
    
        def handle_expanded(self):
            h = self.tree.sizeHint().height()
            self.adjust_height(h)
    
        def adjust_height(self, height):
            self.tree.setFixedHeight(height)
    
        def showEvent(self, event):
            index = self.tree.indexFromItem(self.tree.topLevelItem(0))
            if self.tree.isExpanded(index):
                QtCore.QTimer.singleShot(0, self.handle_expanded)
            else:
                QtCore.QTimer.singleShot(
                    0, lambda index=index: self.handle_collapsed(index)
                )
            super().showEvent(event)
    
    
    app = QtWidgets.QApplication([])
    
    w = MainWindow()
    w.show()
    
    app.exec_()