我是Qt的初学者,我通过以下方式创建应用程序:
因此,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
和rootContext().setContextProperty(...)
将列表从python公开到QML(我使用了how to insert/edit QAbstractListModel in python and qml updates automatically?和Python文档的Qt的答案作为方向)
如果使用QML ListModel
,则可以使用文档https://doc.qt.io/qt-5/qml-qtqml-models-listmodel.html中所述的object get(index)
函数。但是:
get(index)
方法来执行此元素一样?get(index)
方法?我仍在寻找并期望有一个有关python和QML的解决方案。 谢谢您的帮助!
答案 0 :(得分:1)
只有某些类型的变量可以导出到QML,其中包括str,int,float,list,但对于字典,必须将其导出为QVariant。
另一方面,如果要从QML访问方法,则分别使用PyQt5或PySide2时,必须使用@pyqtSlot或@Slot装饰器,以指示在这种情况下输入数据的类型为int和结果参数的输出类型。
main.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_())
main.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
随着QVariant被删除,任何期望它的函数 可以接收任何Python对象(没有一个是无效的QVariant)。相同 返回某条规则时有效:返回的QVariant将是 转换为其原始Python对象类型。
当方法需要QVariant :: Type时,程序员可以使用 字符串(类型名称)或类型本身。
(重点是我的)