使用QAbstractListMod从python访问QML中的list元素

2024-10-01 09:32:26 发布

您现在位置:Python中文网/ 问答频道 /正文

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

  1. 使用QML进行视图设计
  2. 控制器和模型部分主要使用python。你知道吗

因此,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?

上面的代码工作得很好,通过QQmlApplicationEnginerootContext().setContextProperty(...)工作(我使用了来自how to insert/edit QAbstractListModel in python and qml updates automatically?的答案和python文档的Qt作为方向)将列表从python公开给QML。你知道吗

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

  1. 我如何从QML访问实例化MyList中的特定元素,就像我使用get(index)方法访问这个元素一样,如果它是本机qmllistmodel?你知道吗
  2. 如何实现get(index)方法?你知道吗

我仍然在搜索和期待一个涉及python和QML的解决方案。 谢谢你的帮助!你知道吗


Tags: nameselfidgetindexreturndefqt
1条回答
网友
1楼 · 发布于 2024-10-01 09:32:26

只有一些类型的变量可以导出到QML,其中包括str、int、float、list,但是对于字典,它必须作为QVariant导出。你知道吗

另一方面,如果要从QML访问方法,则必须分别使用@pyqtlot或@Slot decorator(如果使用的是PyQt5或PySide2),以指示在本例中为int的输入数据类型和result参数的输出类型。你知道吗

主.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_())

主.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

加号:

只有一些基本类型是直接接受的,而不是DIST的情况,在这些情况下,可以使用qString和QValueList(用于列表或元组),但是在PyStr2中没有q变体,因此可以通过将它们作为字符串传递给C++来指示类型:“q变体”。在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.

(我的重点)

相关问题 更多 >