This is a Python 3.9 script that pulls data from a MySQL database and converts it to a list of named tuples and then passing it to PyQt6.QTreeWidget
.
It has to be a list
of namedtuples
, because I am going to store lists of tags packed in strings dumped from json.dumps
in single fields, then using json.loads
to unpack the lists. This way, filter by tags can easily done with issubset
method.
This will be the main interface of a GUI music player project I am working on, though it is still bare bones, at least the tree hierarchy part is complete.
This is the glimpse of the database:
This is what the window looks like:
And here is the code:
import sys
import mysql.connector
from collections import namedtuple
from PyQt6.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem
song = namedtuple('song', 'artist title album')
app = QApplication(sys.argv)
conn = mysql.connector.connect(user='Estranger', password=********, host='127.0.0.1', port=3306, database='Music')
cursor = conn.cursor()
cursor.execute('select artist, title, album from songs')
songs = [song(*i) for i in cursor.fetchall()]
conn.commit()
tree = QTreeWidget()
tree.resize(1280,720)
tree.setWindowTitle('tree')
frame = tree.frameGeometry()
center = tree.screen().availableGeometry().center()
frame.moveCenter(center)
tree.move(frame.topLeft())
tree.setColumnCount(4)
tree.setHeaderLabels(['Name', 'Artist', 'Album', 'Title'])
entries = []
for p in sorted(set([_.artist for _ in songs])):
artist = QTreeWidgetItem([p])
for a in sorted(set([_.album for _ in songs if _.artist == p])):
album = QTreeWidgetItem([a, p, a])
for s in [_.title for _ in songs if _.artist == p and _.album == a]:
song = QTreeWidgetItem([s, p, a, s])
album.addChild(song)
artist.addChild(album)
entries.append(artist)
tree.insertTopLevelItems(0, entries)
tree.show()
sys.exit(app.exec())
(Password obscured for obvious reasons)
I adapted my code from here: https://doc.qt.io/qtforpython-6/tutorials/basictutorial/treewidget.html
The code there:
import sys
from PySide6.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem
data = {"Project A": ["file_a.py", "file_a.txt", "something.xls"],
"Project B": ["file_b.csv", "photo.jpg"],
"Project C": []}
app = QApplication()
tree = QTreeWidget()
tree.setColumnCount(2)
tree.setHeaderLabels(["Name", "Type"])
items = []
for key, values in data.items():
item = QTreeWidgetItem([key])
for value in values:
ext = value.split(".")[-1].upper()
child = QTreeWidgetItem([value, ext])
item.addChild(child)
items.append(item)
tree.insertTopLevelItems(0, items)
tree.show()
sys.exit(app.exec())
In the example, the data is already hierarchical, it is a dictionary structured like a tree, but my data is a list of named tuples which is kind of flat and more suitable for a table.
But I prefer using a tree-like view to present the data.
Because my data is flat, and the example code structure needs the data to be hierarchical, I used list comprehensions plus cast to set
plus sorted
function to make the hierarchy on the fly, which generates a lot of loops overhead, which is silly.
I am really new to this, this is my first attempt at creating a GUI program, I have Google searched for days and haven't find a way to populate a QTreeView
or QTreeWidget
with data from a flat list, so I wrote my own.
My question is, what is a smarter, more efficient way to achieve the same result (populate a tree-like structure with data from a list of named tuples), and how can I use QTreeView
instead of QTreeWidget
(if there is any difference)?
Any help is appreciated.