QTreeList Widget custom selection



  • 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 :)



  • 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)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.