gpt4 book ai didi

python - 使用 QAbstractListModel 从 python 访问 QML 中的列表元素

转载 作者:行者123 更新时间:2023-12-01 06:50:38 27 4
gpt4 key购买 nike

我是 Qt 的初学者,我正在通过以下方式创建应用程序:

  1. 使用 QML 进行 View 设计,
  2. 使用python主要用于 Controller 和模型部分。

因此,QML 需要与 python 对象进行交互。

我的问题:我通过以下(简化的)代码在 python 中创建了一个 QAbstractListModel:

class MyList(QAbstractListModel):

_myCol1 = Qt.UserRole + 1
_myCol2 = Qt.UserRole + 2


def __init__(self, parent=None):
super().__init__(parent)
self.myData= [
{
'id': '01',
'name': 'test1',
},
{
'id': '02',
'name': 'test2',
}
]

def data(self, index, role=Qt.DisplayRole):
row = index.row()
if role == MyList._myCol1:
return self.myData[row]['id']
if role == MyList._myCol2:
return self.myData[row]['name']

def rowCount(self, parent=QModelIndex()):
return len(self.myData)

def roleNames(self):
return {
MyList._myCol1: b'id',
MyList._myCol2: b'name'
}

def get(self, index):
# How to implement this?

上面的代码工作正常,并通过 QQmlApplicationEngine 将列表从 python 公开到 QML,并且 rootContext().setContextProperty(...) 有效(我使用了答案来自 how to insert/edit QAbstractListModel in python and qml updates automatically? 和 Qt for Python 文档作为方向)。

如果使用 QML ListModel,我可以使用 object get(index) 函数,如文档 https://doc.qt.io/qt-5/qml-qtqml-models-listmodel.html 中所述。 。但是:

  1. 如何从 QML 访问实例化 MyList 中的特定元素,因为如果它是 native QML ListModel,我会使用 get(index) 方法来访问该元素?
  2. 如何实现get(index)方法?

我仍在搜索并期待一个涉及 python 和 QML 的解决方案。感谢您的帮助!

最佳答案

只有某些类型的变量可以导出到 QML,其中包括 str、int、float、list,但如果是字典,则必须将其导出为 QVariant。

另一方面,如果您想从 QML 访问方法,那么如果您使用 PyQt5 或 PySide2,则必须分别使用 @pyqtSlot 或 @Slot 装饰器,指示输入数据的类型,在本例中为 int 和结果参数的输出类型。

ma​​in.py

from PySide2 import QtCore, QtGui, QtQml


class MyList(QtCore.QAbstractListModel):
col1 = QtCore.Qt.UserRole + 1
col2 = QtCore.Qt.UserRole + 2

def __init__(self, parent=None):
super().__init__(parent)
self.myData = [{"id": "01", "name": "test1",}, {"id": "02", "name": "test2",}]

def data(self, index, role=QtCore.Qt.DisplayRole):
row = index.row()
if index.isValid() and 0 <= row < self.rowCount():
if role == MyList.col1:
return self.myData[row]["id"]
if role == MyList.col2:
return self.myData[row]["name"]

def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.myData)

def roleNames(self):
return {MyList.col1: b"id", MyList.col2: b"name"}

@QtCore.Slot(int, result='QVariant')
def get(self, row):
if 0 <= row < self.rowCount():
return self.myData[row]


if __name__ == "__main__":
import os
import sys

app = QtGui.QGuiApplication(sys.argv)

current_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)))
qml_file = os.path.join(current_dir, "main.qml")

model = MyList()

engine = QtQml.QQmlApplicationEngine()
engine.rootContext().setContextProperty("listmodel", model)
engine.load(QtCore.QUrl.fromLocalFile(qml_file))

sys.exit(app.exec_())

ma​​in.qml

import QtQuick 2.13
import QtQuick.Controls 2.13

ApplicationWindow{
id: root
visible: true
width: 640
height: 480
ListView{
id: view
anchors.fill: parent
model: listmodel
delegate: Text{
text: model.id + " " + model.name
}
}
Component.onCompleted: {
var obj = listmodel.get(0)
console.log(obj["id"])
console.log(obj["name"])
}
}

输出:

qml: 01
qml: test1

加号:

仅直接接受一些基本类型,而 dict 则不然,在这些情况下,您可以使用 QVariant 和 QVariantList (用于列表或元组),但在 PySide2 中没有 QVariant,因此您可以在中指示类型C++ 将它们作为字符串传递:“QVariant”。 docs中表明了什么:

QVariant

As QVariant was removed, any function expecting it can receive any Python object (None is an invalid QVariant). The same rule is valid when returning something: the returned QVariant will be converted to the its original Python object type.

When a method expects a QVariant::Type the programmer can use a string (the type name) or the type itself.

(强调我的)

关于python - 使用 QAbstractListModel 从 python 访问 QML 中的列表元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59023295/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com