Как создать QAbstractListModel в PyQt и использовать его с QML ListView?PyQt и QML - Как создать пользовательскую модель данных
ответ
Вам нужно указать имена ролей, чтобы использовать их в QML;
http://doc.qt.io/qt-4.8/qabstractitemmodel.html#setRoleNames
Не использовал PyQT, но вы можете найти минимальный рабочий образец здесь: http://doc.qt.nokia.com/stable/qdeclarativemodels.html
Если вы осмотрите образец в том числе и class Animal {...}
вы увидите, что вы должны определить роли для разных поля, которые вы хотите предоставить. И как минимум вы должны определить функцию data(), возвращающую соответствующее значение поля для данного индекса. Также вам понадобятся ваши собственные методы для вставки и удаления. Надеюсь, это поможет ...
Если кто-то еще ищет ответ, я сделал небольшое приложение, которое подключается к базе данных актеров с подклассом QAbstractListModel и отображает миниатюры в QGridView на основе приведенного примера @fgungor . (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
}
}
}
}
Я попробовал это, но это не работает для меня. Может быть, у меня что-то не так ... – reshefm 2010-12-07 14:43:34