gpt4 book ai didi

python - 来自 QML 的 PyQt5 类型转换

转载 作者:行者123 更新时间:2023-12-01 07:43:16 25 4
gpt4 key购买 nike

我正在尝试从 python 填充 QML 列表模型,按下按钮后,我想获取我之前设置的项目。

我遇到了类型转换问题,我得到的是 QObject 而不是 python 字典。

创建一个被推送到 QML 根上下文的类。 pySignal 由 QML javascript 代码调用

import sys
import os

from PyQt5.QtCore import QObject, QUrl
from PyQt5.QtCore import pyqtSignal, pyqtSlot
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlComponent, QJSValue
from PyQt5.QtQml import QQmlEngine, QQmlComponent


class PythonContext(QObject):

pySignal = pyqtSignal(QJSValue)

def __init__(self, parent=None):
QObject.__init__(self, parent)

self.pySignal.connect(self.onPySignal)

@pyqtSlot(QJSValue)
def onPySignal(self, param):
obj = param.toVariant()
print('onPySignal', obj)
print(dir(obj))


if __name__ == '__main__':

app = QGuiApplication(sys.argv)
engine = QQmlEngine()

pyContext = PythonContext()

ctxt = engine.rootContext()
ctxt.setContextProperty('py', pyContext)

component = QQmlComponent(engine)
component.loadUrl(QUrl('qml_signals.qml'))

obj = component.create()

obj.addListItem({'pk': 1, 'name': 'One'})
obj.addListItem({'pk': 2, 'name': 'Two'})
obj.addListItem({'pk': 3, 'name': 'Three'})

engine.quit.connect(app.quit)

sys.exit(app.exec_())

QML 文件本身仅包含一个带有 ComboBox 和按钮的应用程序窗口。按下按钮会调用 pySignal 发射,并应将 ComboBox 当前选择的项目发送到 Python 上下文。

QML:

import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.12
import QtQuick.Dialogs 1.3

ApplicationWindow {

title: "PyQT5 QML Signals dictionary"

visible: true
width: 400
height: 400

function addListItem(param) {
lm.append(param)
if(lmSelector.count == 1) {
lmSelector.currentIndex = 0
}
}

ColumnLayout {
anchors.fill: parent

ComboBox {
id: lmSelector
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter

textRole: "name"

model: ListModel {
id: lm
}
}

Button {
text: "button"
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
onClicked: {
var selectedObject = lm.get(lmSelector.currentIndex)

console.log("button clicked" + selectedObject.name)

/* this does not work */
py.pySignal(selectedObject)

/* but this does and gives the desired output */
py.pySignal({ name: selectedObject.name, pk: selectedObject.pk})
}
}
}
}

输出:

onPySignal <PyQt5.QtCore.QObject object at 0x03CA4710>

我期望的是:

onPySignal {'name': 'One', 'pk': 1.0}

最佳答案

即使您将数据等字典传递给 ListModel,它也会将其存储在 QObjects 中,以便您可以实现所需的绑定(bind)。因此,get() ListModel的方法返回一个对象(QObject):

object get(int index)

如果您想恢复字典,则必须将该对象转换为 JSON,然后从 JSON 转换为字典:

// ...
/* this work */
py.pySignal(JSON.parse(JSON.stringify(selectedObject)))
// ...

输出:

onPySignal {'name': 'One', 'pk': 1}
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
onPySignal {'name': 'One', 'pk': 1.0}
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

关于python - 来自 QML 的 PyQt5 类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56582892/

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