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)