Search code examples
pythonpyside2

How to execute a function on click of empty area of QTreeWidget


I am using Python3.6 and PySide2

I have a treewidget-A populated with employee list. on click on employee (treewidget-A item) a another treeWidget-B will populate.

Now if I click on empty area (deselect item) but treeWidget-B still showing last clicked employee item details.

This is to populate treewidget items

self.treeWidget_A.itemClicked.connect(self.populate_employee)
self.treeWidget_A.currentItemChanged.connect(self.populate_employee)

How to execute clear_employee_data() function on click on empty area of QtreeWidget ?

def clear_employee_data(self):
    self.treeWidget_B.clear()

Solution

  • You have to detect the click and verify that there is not an item:

    from PySide2 import QtCore, QtWidgets
    
    class TreeWidget(QtWidgets.QTreeWidget):
        emptyClicked = QtCore.Signal()
    
        def __init__(self, parent=None):
            super(TreeWidget, self).__init__(parent)
            for i in range(2):
                it = QtWidgets.QTreeWidgetItem(self, ["item-{}".format(i)])
                for j in range(3):
                    child_it = QtWidgets.QTreeWidgetItem(it, ["item-{}-{}".format(i, j)])
            self.expandAll()
    
        def mousePressEvent(self, event):
            super(TreeWidget, self).mousePressEvent(event)
            if not self.indexAt(event.pos()).isValid():
                self.emptyClicked.emit()
    
    @QtCore.Slot()
    def on_empty_clicked():
        print("clicked")
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        w = TreeWidget()
        w.emptyClicked.connect(on_empty_clicked)
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())
    

    With Qt Designer use eventfilter:

    from PySide2 import QtCore, QtGui, QtWidgets
    
    from design import Ui_MainWindow
    
    class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
        emptyClicked = QtCore.Signal()
    
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            self.setupUi(self)
            self.treeWidget_A.viewport().installEventFilter(self)
            self.emptyClicked.connect(self.on_emptyClicked)
    
        def eventFilter(self, obj, event):
            if obj is self.treeWidget_A.viewport() and event.type() == QtCore.QEvent.MouseButtonPress:
                if not self.treeWidget_A.indexAt(event.pos()).isValid():
                    self.emptyClicked.emit()
            return super(MainWindow, self).eventFilter(obj, event)
    
        @QtCore.Slot()
        def on_emptyClicked(self):
            print("empty")
    
    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        w = MainWindow()
        w.show()
        sys.exit(app.exec_())