How can I collect all Qtreeview items so i can then iterate over them and apply necessary changes like display text updates, or color changes?
Is there an easy way to collect all of them using the 'match' method?
def get_checked(self):
model = self.treeview.model()
checked = model.match(
model.index(0, 0), QtCore.Qt.CheckStateRole,
QtCore.Qt.Checked, -1,
QtCore.Qt.MatchExactly | QtCore.Qt.MatchRecursive)
for index in checked:
item = model.itemFromIndex(index)
print(item.text())
test code:
from PySide import QtGui, QtCore
from PySide import QtSvg, QtXml
import sys
class Person:
def __init__(self, name="", children=None):
self.name = name
self.children = children if children else []
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.resize(300, 400)
self.init_ui()
def init_ui(self):
# Setup Tabs Widget
# self.treeview = QtGui.QTreeView()
self.treeview = QtGui.QTreeView()
self.treeview.setHeaderHidden(True)
self.treeview.setUniformRowHeights(True)
self.treeview.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.model = QtGui.QStandardItemModel()
self.treeview.setModel(self.model)
self.action = QtGui.QAction('Print', self)
self.action.setShortcut('F5')
self.action.triggered.connect(self.get_checked)
fileMenu = QtGui.QMenu("&File", self)
fileMenu.addAction(self.action)
self.menuBar().addMenu(fileMenu)
# Setup central widget
self.setCentralWidget(self.treeview)
# populate data
self.populate_people()
self.treeview.expandAll()
def populate_people(self):
parent = Person("Kevin", [
Person("Tom", [Person("Sally"), Person("Susan")]),
Person("Snappy", [Person("John"), Person("Kimmy"),
Person("Joe")]),
Person("Chester", [Person("Danny"), Person("Colleen")])
]
)
self.create_nodes(parent, self.model)
def create_nodes(self, node, parent):
tnode = QtGui.QStandardItem()
tnode.setCheckable(True)
tnode.setData(QtCore.Qt.Unchecked, role=QtCore.Qt.CheckStateRole)
tnode.setData(node.name , role=QtCore.Qt.DisplayRole)
tnode.setData(node, role=QtCore.Qt.UserRole) # store object on item
parent.appendRow(tnode)
for x in node.children:
self.create_nodes(x, tnode)
def get_checked(self):
print "collecting..."
def main():
app = QtGui.QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Here is a recursive solution (requires Python >= 3.3):
def iterItems(self, root):
def recurse(parent):
for row in range(parent.rowCount()):
for column in range(parent.columnCount()):
child = parent.child(row, column)
yield child
if child.hasChildren():
yield from recurse(child)
if root is not None:
yield from recurse(root)
Alternative recursive solution (for Python2/Python3):
def iterItems(self, root):
def recurse(parent):
if root is not None:
for row in range(parent.rowCount()):
for column in range(parent.columnCount()):
child = parent.child(row, column)
yield child
if child.hasChildren():
for item in recurse(child):
yield item
return recurse(root)
And here is an iterative solution (for Python2/Python3):
def iterItems(self, root):
if root is not None:
stack = [root]
while stack:
parent = stack.pop(0)
for row in range(parent.rowCount()):
for column in range(parent.columnCount()):
child = parent.child(row, column)
yield child
if child.hasChildren():
stack.append(child)
(NB: this solution gives a more predictable ordering, and is a little faster)
Usage:
root = self.treeview.model().invisibleRootItem()
for item in self.iterItems(root):
print(item.text())
The root
argument can be any item in a QStandardItemModel
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With