Home > PyQt5, python > PyQt5: QStandardItemModel

PyQt5: QStandardItemModel

9 Maggio 2019

Torna all’indice degli appunti

QStandardItemModel

Il QStandardItemModel è una classe che fornisce un modello generico per l’immagazzinamento di dati personalizzati.
Come il QStandardItem, anche il QStandardItemModel fa parte delle classi Model/View, classi cardine del framework Model/View.
Viene comunemente utilizzato come repository per i tipi di dato standard di Qt.
Gli elementi di un QStandardItemModel sono ovviamente oggetti QStandardItem.
Il QStandardItemModel implementa un’interfaccia QAbstractItemModel, ovvero il model può essere usato per fornire i dati in ogni view che supporti tale interfaccia, come ad esempio QListView, QTableView e QTreeView.

Se la nostra esigenza è di avere una lista o un albero, per prima cosa dobbiamo creare un oggetto QStandardItemModel ed usare i metodi appendRow(QStandardItem) e appendColumn(QStandardItem), per aggiungere elementi al model.
Se invece abbiamo necessità di una tabella, la possiamo dimensionare con i metodi setRowCount e setColumnCount.
Per aggiungere un elemento alla tabella useremo il metodo setItem(row, column, QStandarItem.
Per inserire elementi possiamo usare i metodi insertRow(row, [QStanrdItems]) e insertColumn(column, [QStandardItems]), mentre per eliminare elementi sono disponibili i metodi removeRow(row) e removeColumn(column).
Tutti questi metodi sono già stati affrontati negli appunti inerenti il QStandardItem.
Per rimuovere tutti gli elementi dal model si utilizza il metodo clear

Per accedere ad un elemento si utilizza il metodo item(row, column) e per cercarne più di uno, il metodo findItems(string, Qt.MatchFlags)

Vediamo ad esempio come creare una tabella:

>>> from PyQt5.QtGui import QStandardItemModel, QStandardItem
>>> model = QStandardItemModel()
>>> model.setRowCount(4)
>>> model.setColumnCount(4)
>>> for row in range(model.rowCount()):
...     for column in range(model.columnCount()):
...         model.setItem(row, column, QStandardItem("row {}, column {}".format(row, column))) 

Per recuperare gli elementi possiamo, come già accennato, utilizzare il metodo item(row, column):

>>> model.item(0, 0)
<PyQt5.QtGui.QStandardItem object at 0x03667F80>
>>> model.item(0, 0).text()
'row 0, column 0'
>>> model.item(2, 2).text()
'row 2, column 2'
>>> for row in range(4):
...     for column in range(4):
...         print(model.item(row, column).text())
...         
row 0, column 0
row 0, column 1
row 0, column 2
row 0, column 3
row 1, column 0
row 1, column 1
row 1, column 2
row 1, column 3
row 2, column 0
row 2, column 1
row 2, column 2
row 2, column 3
row 3, column 0
row 3, column 1
row 3, column 2
row 3, column 3

o findItems(text, Qt.MatchFlag, col=0) utilizzando i Qt.MatchFlags, che sono qui riassunti:

Costante Valore Descrizione
Qt.MatchExactly 0 Esegue un controllo di corrispondenza QVariant-based
Qt.MatchFixedString 8 Esegue un controllo di corrispondenza sulla stringa (string-based). Per avere una ricerca case-sensitive bisogna specificare il flag MatchCaseSensitive.
Qt.MatchContains 1 Il termine di ricerca è contenuto nell’elemento.
Qt.MatchStartsWith 2 Il termine di ricerca corrisponde all’inizio dell’elemento.
Qt.MatchEndsWith 3 Il termine di ricerca corrisponde con la fine dell’elemento.
Qt.MatchCaseSensitive 16 La ricerca è case sensitive.
Qt.MatchRegExp 4 Esegue una ricerca string-based usando una espressione regolare cometermine di ricerca.
Qt.MatchWildcard 5 Esegue una ricerca string-based usando una stringa con wildcards come termine di ricerca.
Qt.MatchWrap 32 Esegue un wrap around, ovvero quando la ricerca raggiunge l’ultimo elemento del model, ricomincia dal primo finchè non raggiunge nuovamente la fine.
Qt.MatchRecursive 64 Cerca sull’intera gerarchia.

Di default la ricerca viene effettuata sulla colonna 0, per cercare su un’altra colonna, bisogna specificarla:

>>> from PyQt5.QtCore import Qt
>>> model.findItems("row 2", Qt.MatchStartsWith)
[<PyQt5.QtGui.QStandardItem object at 0x03A35120>]
>>> model.findItems("row", Qt.MatchStartsWith)
[<PyQt5.QtGui.QStandardItem object at 0x035ABDF0>, <PyQt5.QtGui.QStandardItem object at 0x035ABEE0>, <PyQt5.QtGui.QStandardItem object at 0x0347A080>, <PyQt5.QtGui.QStandardItem object at 0x0347A1C0>]
>>> items = model.findItems("row", Qt.MatchStartsWith)
>>> for item in model.findItems("row", Qt.MatchStartsWith): print(item.text())
... 
row 0, column 0
row 1, column 0
row 2, column 0
row 3, column 0
>>> for item in model.findItems("row", Qt.MatchStartsWith, 1): print(item.text())
... 
row 0, column 1
row 1, column 1
row 2, column 1
row 3, column 1

INVISIBLE ROOT ITEM

Con il metodo invisibleRootItem di model, otteniamo il root item che ci carantisce un accesso agli elementi di tipo TOP-LEVEL. Questo metodo viene usato quando si ha a che fare con i tree-models.

>>> root = model.invisibleRootItem()
>>> root.hasChildren()
True
>>> root.child(1, 2)
<PyQt5.QtGui.QStandardItem object at 0x035ABF80>

INDEX from ITEM

Il metodo indexFromItem(QStandardItem) ritorna l’oggetto QModelIndex relativo a quell’item, nel model di riferimento.

>>> item = root.child(1, 1)
>>> modelindex = model.indexFromItem(item)
>>> modelindex
<PyQt5.QtCore.QModelIndex object at 0x033F5B70>
>>> item = root.child(1, 1)
>>> modelindex = model.indexFromItem(item)
>>> modelindex
<PyQt5.QtCore.QModelIndex object at 0x033F5B70>
>>> modelindex.internalId()
9929232

internalId è l’indice dell’item passato come argomento, all’interno del model

ITEM from INDEX

Il passaggio inverso a quello precedente, si ottiene con il metodo itemFromIndex(QModelIndex), che ritorna l’oggetto QStandardItem corrispondente all’oggetto QModelIndex passato come argomento:

>>> model.itemFromIndex(modelindex)
<PyQt5.QtGui.QStandardItem object at 0x035ABF30>
>>> item = model.itemFromIndex(modelindex)
>>> item.text()
'row 1, column 1'
>>> item.font()
<PyQt5.QtGui.QFont object at 0x033F5B30>

HEADERS

E’ possibile settare gli headers orizzontali e verticali della tabella intrinseca al model, con i metodi setHorizontalHeaderLabels([labels]) e setVerticalHeaderLabels([labels]).
Come si nota,l’argomento passato ai metodi, è una lista di labels e qualora dovessero essere più labels, delle righe o colonne disponibili, questo comporterà l’aumento delle stesse.
Non comporterà però una sostituzione della posizione degli item, nelle rispettive righe/colonne.

>>> model.setHorizontalHeaderLabels(["column 1", "column 2", "column 3", "column 4"])
>>> model.item(0, 0).text()
'row 0, column 0'
>>> model.horizontalHeaderItem(0)
<PyQt5.QtGui.QStandardItem object at 0x0347A6C0>
>>> model.horizontalHeaderItem(0).text()
'column 1'
>>> model.item(0, 0).text()
'row 0, column 0'

Come si nota l’item di riga 0 e colonna 0 è rimasto al suo posto.
L’item header può venire impostato anche con il metodo setHorizontalHeaderItem(column, QStandardItem) per la colonna

>>> model.setHorizontalHeaderItem(0, QStandardItem("New Column 1"))
>>> model.horizontalHeaderItem(0).text()
'New Column 1'

e setVerticalHeaderItem(row, QStandardItem), per la riga:

>>> model.setVerticalHeaderItem(0, QStandardItem("Row 1"))
>>> model.verticalHeaderItem(0).text()
'Row 1'

Torna all’indice degli appunti

Categorie:PyQt5, python Tag: ,
I commenti sono chiusi.