Eigene Roles in QListView anwenden

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
AlphaX2
User
Beiträge: 53
Registriert: Dienstag 28. Juni 2011, 10:42

Hallo liebe Leute,

ich hoffe ihr könnt mir helfen. Es geht darum: um es kurz zu machen, wie kann ich auf eigene Roles eines QAbstractModel zugreifen? Ich habe mit setRoleNames eigene Namen gegeben und weiß nur nicht, wie ich darauf zugreifen kann, bzw. wie ich eben meinen QListView's sage, welche Role sie anzeigen müssen, also wie kommt der Role-Name in die data() Methode? ;) Grundlegend möchte ich dann mit einem Model eben verschiedene Infos, in verschiedenen Views, anzeigen können. :)

Ich nehme an man muss das Standard-Delegate ersetzen und dem dann auf den Weg geben was ich will? Gibt es dazu Beispiele, ich konnte leider nix finden. :-/

Hoffe ihr habt einen Link, ein Beispiel oder ähnliches!

Vielen Dank!

AlphaX2
AlphaX2
User
Beiträge: 53
Registriert: Dienstag 28. Juni 2011, 10:42

So,

ich werde meine Frage mal zum Teil selbst beantworten. Im folgenden Beispiel habe ich QML genutzt, keine QListView aus QWidget, dort sollte es eigentlich genauso funktionieren, allerdings dürfte man wohl um ein eigenes Delegate nicht drumherum kommen.

Kurz erklärt: Eigentlich sind die Roles intern nur Zahlen, also wird nach der UserRole (letzte Standard Role) einfach beliebig oft erweitert, was durch +1, +2 ... usw. gemacht werden kann. Anschließend wird ein Dictionary angelegt indem die eigenen "Roles" einen Namen bekommen, mit diesem Namen können sie dann später in QML z.B. angesprochen werden. Damit das klappt muss das dict, der Methode setRoleNames() des Models übergeben werden. Gerade der Teil wird aus der Doc nicht klar, dass hier ein Dict gebraucht wird. In C++ wird übrigens mit einem QByteArray gearbeitet.

Anbei ein einfaches Beispiel mit festen Daten:

Python

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from PySide import QtCore, QtGui, QtDeclarative

class ListModel(QtCore.QAbstractListModel):

    def __init__(self):
        QtCore.QAbstractListModel.__init__(self)

        # Roles entsprechen Integern, daher nach Qt's eigenen Roles erweitern
        self.event_role = QtCore.Qt.UserRole+1
        self.date_role = QtCore.Qt.UserRole+2

        # Namen im Dict, entsprechen jenen Namen die ins (QML) delegate kommen
        roles = {self.event_role: "event", self.date_role: "date"}
        self.setRoleNames(roles)

        # hardcoded, soll nur Funktionsweise zeigen...
        self.dates = ["01.01.2000", "23.02.1988", "25.03.2012"]
        self.events = ["Geburtstag 1", "Geburtstag 2", "Geburtstag 3"]


    # Methode muss bei Ableitungen überschrieben werden
    def rowCount(self, index=QtCore.QModelIndex()):
        return len(self.dates)


    # Methode muss bei Ableitungen überschrieben werden
    def data(self, index, role=QtCore.Qt.DisplayRole):

        # aus Index aktuelle Reihe lesen um Daten ansprechen zu können
        i = index.row()

        # auf eigene Roles prüfen und entsprechend reagieren
        if role == self.event_role:
            return self.events[i]
        elif role == self.date_role:
            return self.dates[i]
        else:
            return None


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)

    # Model Objekt erzeugen
    model = ListModel()

    view = QtDeclarative.QDeclarativeView()

    # Model für QML zugänglich machen, MUSS vor setzen des QML-Files passieren!
    view.rootContext().setContextProperty("myModel", model)
    view.setSource("main.qml")
    view.show()

    sys.exit(app.exec_())



QML

Code: Alles auswählen

import QtQuick 1.1

Rectangle {
    width: 360
    height: 360

    ListView {
        anchors.fill: parent
        // entsprechend dem Namen, mit dem das Model zugänglich gemacht wurde
        model: myModel    

        delegate: Text {
            /* sehr einfaches delegate, die Namen können 
            *  wie im dict angegeben angesprochen werden!
            */
            text: event+" | "+date
        }
    }
}
Ich hoffe das Beispiel ist verständlich, sollte ich es demnächst mit QWidget verwenden, werde ich es entsprechend ergänzen! :)

AlphaX2
Antworten