Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    QTreeList Widget custom selection

    Language Bindings
    2
    2
    2672
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • C
      cg-cnu last edited by

      hello everyone,
      My first post here.. not sure if this is the right side of the forum to post. Please feel free to move this to the correct subforum.

      I am new to Qt and was writing a ui for "mari":http://www.thefoundry.co.uk/products/mari/ which uses pythonQt.

      I am using QTreeWidgetItem to list some data in a python dictionary, for which I need a custom selection. I want to be able to select multiple child items but should only select one parent item at a time.

      I am using list.setSelectonMode (QAbstractItemView.ExtendedSelection) which basically makes the whole list as extened selection. But I want only the children to be Extended selection and the parent to be single selection.

      Is there any way I can do that...
      Thanks for your time :)

      1 Reply Last reply Reply Quote 0
      • jazzycamel
        jazzycamel last edited by

        The following is a simple attempt at what I think you want. This will allow the user to select multiple child items which have the same parent (top level item) but will only allow parents to be selected individually. It works by connecting to the "QTreeWidget":http://qt-project.org/doc/qt-4.8/qtreewidget.html itemSelectionChanged signal and inspecting newly selected indexes and comparing there relationship (if any) to the to the previously selected indexes, selecting and deselecting as appropriate:

        @
        from PyQt4.QtGui import *
        from PyQt4.QtCore import *

        class TreeWidget(QTreeWidget):
        diff=staticmethod(lambda l1,l2: filter(lambda x: x not in l1, l2))

        def __init__(self, parent=None, **kwargs):
            QTreeWidget.__init__(
                self,
                parent,
                selectionMode=QTreeWidget.ExtendedSelection,
                itemSelectionChanged=self._itemSelectionChanged,
                **kwargs)
        
            self._selected=[]
        
        @pyqtSlot()
        def _itemSelectionChanged(self):
            si=self.selectedIndexes()
        
            added=TreeWidget.diff(self._selected, si)
        
            block=self.blockSignals(True)
        
            self.selectionModel().clearSelection()
        
            for add in added:
                if add.parent().isValid():
                    # Must be a child item as it has a valid parent
                    for index in self._selected:
                        parent=add.parent()
                        if (not index.parent().isValid()) or (index.parent()!=parent) or index==parent:
                            try: si.remove(index)
                            except ValueError: pass
        
                else:
                    # Invalid parent therefore it is a toplevel (parent) item
                    for index in self._selected:
                        try: si.remove(index)
                        except ValueError: pass
            
            for i in si: self.selectionModel().select(i, QItemSelectionModel.Select)
            self._selected=si
        
            self.blockSignals(block)
        

        class Widget(QWidget):
        def init(self, parent=None, **kwargs):
        QWidget.init(self, parent, **kwargs)

            l=QVBoxLayout(self)
        
            self._tree=TreeWidget(self, columnCount=1)
            l.addWidget(self._tree)
        
            for i in xrange(3):
                pItem=QTreeWidgetItem(self._tree, ['Parent {0}'.format(i)])
                self._tree.addTopLevelItem(pItem)
        
                for j in xrange(3):
                    cItem=QTreeWidgetItem(pItem, ['Child {0}.{1}'.format(i,j)])
                    pItem.addChild(cItem)
        

        if name=="main":
        from sys import argv, exit

        a=QApplication(argv)
        w=Widget()
        w.show()
        w.raise_()
        exit(a.exec_())
        

        @

        Hope this helps ;o)

        For the avoidance of doubt:

        1. All my code samples (C++ or Python) are tested before posting
        2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
        1 Reply Last reply Reply Quote 0
        • First post
          Last post