I'm trying to get a QTreeWidget built dynamically from a list like below.
list = ['pear.green', 'banana.yellow', 'banana.green', 'apple.green', 'apple.red']
Here is a mock up I hardcoded to demonstrate what I would like build dynamically.
apple_item = QtWidgets.QTreeWidgetItem(self.list)
apple_item.setText(0, "apple")
apple_item.setFont(0, self.TOP_LEVEL_TREE_ITEM_FONT)
apple_green_item = QtWidgets.QTreeWidgetItem(apple_item)
apple_green_item.setText(0, "green")
apple_red_item = QtWidgets.QTreeWidgetItem(apple_item)
apple_red_item.setText(0, "red")
banana_item = QtWidgets.QTreeWidgetItem(self.list)
banana_item.setText(0, "banana")
banana_item.setFont(0, self.TOP_LEVEL_TREE_ITEM_FONT)
banana_green_item = QtWidgets.QTreeWidgetItem(banana_item)
banana_green_item.setText(0, "green")
banana_yellow_item = QtWidgets.QTreeWidgetItem(banana_item)
banana_yellow_item.setText(0, "yellow")
pear_item = QtWidgets.QTreeWidgetItem(self.list)
pear_item.setFont(0, self.TOP_LEVEL_TREE_ITEM_FONT)
pear_item.setText(0, "pear")
pear_green_item = QtWidgets.QTreeWidgetItem(pear_item)
pear_green_item.setText(0, "green")
This comes down to constructing the tree structure from the list items, and then adding them dynamically to the QTreeWidget
.
For this you can first loop the list, and find the .
in the string. The part before it is the top category and the part after it is the subcategory. You can store them in a dictionary with the top categories as keys and the subcategories as values.
Note that in the code below I added a try-except block in case there is no .
in the list item, then the full item becomes the top category and the subcategory is empty.
This leads to the following dictionary:
{'pear': ['green'], 'banana': ['yellow', 'green'], 'apple': ['green', 'red'], 'peach': []}
Afterwards you can do a second loop over this dictionary. In the code below the loop is over the sorted keys to get them in alphabetical order in the tree widget. Now you create a dynamic item for each top category with (also dynamic) subitems for the list of subcategories (which can be empty, like for peach in the example). Adding the items and subitems is done in the same way as in your mockup, but just using the same variables item
and subitem
in a loop.
Full code:
from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QTreeWidget, QTreeWidgetItem
class TreeWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
treeWidget = QTreeWidget(self)
treeWidget.setColumnCount(2)
treeWidget.setHeaderHidden(True)
mylist = ['pear.green', 'banana.yellow', 'banana.green', 'apple.green', 'apple.red', 'peach']
categories = dict()
for item in mylist:
try:
pos = item.index(".")
topcat = item[:pos]
subcat = [item[pos+1:]]
except ValueError:
topcat = item
subcat = []
if topcat in categories:
categories[topcat].extend(subcat)
else:
categories[topcat] = subcat
for topcat in sorted(categories):
item = QTreeWidgetItem(treeWidget)
item.setText(0, topcat)
for subcat in categories[topcat]:
subitem = QTreeWidgetItem(item)
subitem.setText(0, subcat)
self.setCentralWidget(treeWidget)
app = QApplication([])
mainWin = TreeWindow()
mainWin.show()
app.exec()
Result: