Frage

Wie soll ich ein QAbstractListModel in PyQt erstellen und verwenden Sie es mit einem QML Listview?

War es hilfreich?

Lösung

Sie müssen es die Rollennamen festlegen zu können, um es in QML verwenden;

http://doc.qt.io/qt-4.8/qabstractitemmodel. html # setRoleNames

Andere Tipps

Haben Sie nicht PyQT verwendet, aber Sie können eine minimale Arbeitsprobe finden Sie hier: http: / /doc.qt.nokia.com/stable/qdeclarativemodels.html

Wenn Sie die Probe einschließlich der class Animal {...} überprüfen Sie werden sehen, dass Sie Rollen für die verschiedenen Felder definieren, müssen Sie liefern wollen. Und bei einem Minimum müssen Sie die Daten () Funktion Rückgabe des entsprechenden Feldwert für einen gegebenen Index definieren. Auch werden Sie Ihre eigenen Methoden zum Einsetzen und Entfernen benötigen möglicherweise. Hoffe, das hilft ...

Wenn jemand anderes nach einer Antwort suchen, habe ich eine kleine Anwendung, dass eine Verbindung zu einer Datenbank von Akteuren mit einer Unterklasse von QAbstractListModel und zeigt die Thumbnails in QGridView am Beispiel @fgungor gebucht. (PyQt5)

main.py :

import sys, models
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQuick import QQuickView

if __name__ == '__main__':

    # Prints QML errors
    def handleStatusChange(status):
        if status == QQuickView.Error:
            errors = appLabel.errors()
            if errors:
                print (errors[0].description())



    myApp = QApplication(sys.argv)
    appLabel = QQuickView()
    appLabel.statusChanged.connect(handleStatusChange)
    model = models.ActorModel(DB_PATH)
    ctxt = appLabel.rootContext()
    ctxt.setContextProperty('myModel', model)
    appLabel.setSource(QUrl('./qml/main/main.qml'))

    try:
        sys.exit(myApp.exec_())
    except:
        print("Exiting")

models.py :

import db
from PyQt5.QtCore import QAbstractListModel, Qt, pyqtSlot


class ActorModel(QAbstractListModel):
    NameRole = Qt.UserRole + 1
    ThumbRole = Qt.UserRole + 2

    _roles = {NameRole: b"name", ThumbRole: b"thumb"}

    def __init__(self, db_path):
        super(ActorModel, self).__init__()
        self._actors = []
        self._db = db.Database(db_path)


    def update(self, search_term):
        self.beginResetModel()
        self._actors = self._db.actor_search(search_term)
        self.endResetModel()

    # Reacts to onTextChanged event of searchBar (in QML code)
    @pyqtSlot(str)
    def search_input(self,search_input):
        if len(search_input) > 3:
            print (search_input)
            self.update(search_input)

    def rowCount(self, parent=None, *args, **kwargs):
        return len(self._actors)

    def data(self, QModelIndex, role=None):
        row = QModelIndex.row()
        if role == self.NameRole:
            return self._actors[row]["name"]

        if role == self.ThumbRole:
            return self._actors[row]["thumbnail"]

    def roleNames(self):
        return self._roles

db.py:

import sqlite3


class Database:

    def __init__(self, db_path):
        self.db_path = db_path
        self.sqlite_db = sqlite3.connect(self.db_path)
        self.sqlite_db.row_factory = sqlite3.Row
        self.cursor = self.sqlite_db.cursor()

    def actor_search(self, actor_name):
        self.cursor.execute('SELECT Actors.Id,Actors.Name,Actors.thumbnail AS thumbnail FROM Actors '
                                'WHERE Actors.Name LIKE \'%{}%\' ORDER BY Actors.Name'.format(actor_name))
        return self.cursor.fetchall()

main.qml:

import QtQuick 2.8
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1

Window {
    id: root
    visible: true
    title: 'Actor Exploer'
    width: 1280
    height: 720

    ColumnLayout {
        id: mainLayout
        anchors.fill: parent

        Row {
            Layout.fillWidth: true

            TextArea {
                id: searchBar
                placeholderText: "Input actor name"
                Layout.fillWidth: true
                width: 600
                onTextChanged: myModel.search_input(searchBar.text)                
            }


        }

        GridView {

            id: gridView
            keyNavigationWraps: true
            Layout.fillWidth: true
            Layout.fillHeight: true
            cellWidth: 220
            cellHeight: 320

            model: myModel // QML connection to python model
            delegate: Rectangle {
                id: thumb_frame
                height: 330
                width: 200
                Image {
                    id: actorThumb
                    asynchronous: true
                    source: "file:///" + thumb  // Access to the ThumbRole in ActorModel in our python code
                    smooth: true
                    sourceSize.width: 200
                    sourceSize.height: 300
                    height: 300
                    width: 200
                    anchors.left: thumb_frame.left
                    anchors.top: thumb_frame.top

                    onStatusChanged: {
                        if (actorThumb.status == Image.Error)
                            actorThumb.source = 'PLACEHOLDER_IMAGE_PATH'
                    }
                }

                Text {
                    anchors.top: actorThumb.bottom
                    anchors.horizontalCenter: actorThumb.horizontalCenter
                    text: name // Access to the NameRole in ActorModel in our python code
                }


        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top