Comment créer un modèle QAbstractListModel dans PyQt et l'utiliser avec un ListView QML?PyQt et QML - Comment créer un modèle de données personnalisé
Répondre
Vous devez définir ses noms de rôle pour pouvoir l'utiliser dans QML;
http://doc.qt.io/qt-4.8/qabstractitemmodel.html#setRoleNames
ont pas utilisé PyQT mais vous pouvez trouver un échantillon de travail minimal ici: http://doc.qt.nokia.com/stable/qdeclarativemodels.html
Si vous examinez l'échantillon, y compris la class Animal {...}
vous verrez que vous devez définir des rôles pour les différents champs que vous souhaitez fournir. Et vous devez au minimum définir la fonction data() en retournant la valeur de champ correspondante pour un index donné. Vous aurez également besoin de vos propres méthodes personnalisées pour insérer et supprimer éventuellement. J'espère que cela aide ...
Si quelqu'un d'autre cherche une réponse, j'ai fait une petite application qui se connecte à une base de données d'acteurs avec une sous-classe de QAbstractListModel et affiche les vignettes dans QGridView basé sur l'exemple @fgungor posté . (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
}
}
}
}
je l'ai essayé, mais ça n'a pas marché pour moi. Peut-être que j'ai eu quelque chose de mal ... – reshefm
Le lien semble être arrêté le 21/07/13 – samoz
Les réponses ne sont pas en rapport avec Python! –