Home > PyQt5, python > PyQt5: QColumnView

PyQt5: QColumnView

16 Maggio 2019

Torna all’indice degli appunti

QColumnView

Il ColumnView widget è simile ad un ListWidget, solo che solitamente contiene elementi
che contengono a loro volta altri elementi (child).
Ogni sottoelemento viene piazzato orizzontalmente in un altro List Widget.
Questo tipo di visualizzazione è chiamata anche Cascade List.
La classe QColumnView è una delle classi Model/View, stuttura portante del framework model/view di Qt.
Ne deriva che QColumnView implementa l’interfaccia QAbstractItemView, necessaria alla visualizzazione corretta di modelli di tipo QAbstractItemModel.

Facciamo riferimento ad un tree-model, per meglio capire il funzionamento del QColumnView.
Creaiamo un struttura gerarchica con 3 squadre di calcio e 3 giocatori per ognuna di essa

>>> from PyQt5.QtGui import QStandardItem, QStandardItemModel
>>> d_team = {"Inter": ["Handanovic", "D'Ambrosio", "De Vrij"],
...           "Milan": ["Donnarumma", "Calabria", "Romagnoli"],
...           "Juev": ["Szczezny", "De Sciglio", "Chiellini"]}
... 
>>> model = QStandardItemModel()
>>> for row, team in enumerate(d_team.keys()):
...     model.setItem(row, 0, QStandardItem(team))
...     item = model.item(row, 0)
...     for rrow, player in enumerate(d_team.get(item.text())):
...         item.setChild(rrow, 0, QStandardItem(player))

Poi creiamo un oggetto QColumnView al quale passiamo il nostro model con il metodo setModel(QStandardItemModel):

>>> from PyQt5.QtWidgets import QApplication, QColumnView
>>> app = QApplication([])
>>> cw = QColumnView()
>>> cw.setModel(model)

LARGHEZZA DELLE COLONNE

La larghezza delle colonne è settabile con il metodo setColumnWidth(QList) dove QList è una lista di int, uno per ogni colonna, partendo dalla prima. Se la lista non contiene numeri sufficienti, verranno modificate solo le colonne corrispondenti. Se i numeri sono troppi, verranno memorizzati per le future colonne aggiunte. Per ottenere invece la lista delle larghezze delle colonne, si utilizza il metodo columnWidths:

>>> cw.columnWidths()
[256]
>>> cw.setColumnWidths([120, 120])
>>> cw.columnWidths()
[120]

Nota:
Perchè appare solo una colonna?
Perchè al momento è attiva solo la prima, la seconda, quella che contiene i giocatori, non essendo stata attivata con un click, è nascosta.
Quando la colonna verrà visualizzata, allora assumerà la larghezza assegnata in precedenza.

E’ possibile anche togliere dalle colonne i >Grip Resize, ovvero le freccette che permettono di modificare la larghezza della colonna.
Il metodo per abilitarle o disabilitarle, è setGripResize(bool), di default sono presenti.

Ecco un codice minimale d’esempio:

from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QWidget, QApplication, QBoxLayout, QColumnView
from PyQt5.QtGui import QStandardItem, QStandardItemModel
import sys


class MainWindow(QMainWindow):
    def __init__(self, parent=None, model=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle("QColumnView Example")
        self.central_widget = FormWidget(parent=self, model=model) 
        self.setCentralWidget(self.central_widget)
        self.resize(400, 100)


class FormWidget(QWidget):
    def __init__(self, parent, model=None):
        super(FormWidget, self).__init__(parent)
        layout = QBoxLayout(QBoxLayout.TopToBottom)
        self.setLayout(layout)
        self.column_view = QColumnView()
        self.column_view.setModel(model)
        self.column_view.setColumnWidths([120, 120, 120])
        self.column_view.clicked.connect(self.on_data)
        self.column_view.setResizeGripsVisible(False)
        layout.addWidget(self.column_view)

    def on_data(self):
        print("[SIG] Column widths: %s" % self.column_view.columnWidths())


class CustomModel(QStandardItemModel):
    def __init__(self):
        super(CustomModel, self).__init__()
        self.setVerticalHeaderItem(0, QStandardItem("Team"))
        self.setVerticalHeaderItem(1, QStandardItem("Player"))

    def generate_tree(self):

        d_team = {"Inter": ["Handanovic", "D'Ambrosio", "De Vrij"],
                  "Milan": ["Donnarumma", "Calabria", "Romagnoli"],
                  "Juve": ["Szczezny", "De Sciglio", "Chiellini"]}
        for row, team in enumerate(d_team.keys()):
            self.setItem(row, 0, QStandardItem(team))
            item = self.item(row, 0)
            for rrow, player in enumerate(d_team.get(item.text())):
                item.setChild(rrow, 0, QStandardItem(player))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    model = CustomModel()
    model.generate_tree()
    main_window = MainWindow(parent=None, model=model)
    main_window.show()
    sys.exit(app.exec_())

Torna all’indice degli appunti

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