为了账号安全,请及时绑定邮箱和手机立即绑定

无法从 python 引用现有 QML 元素

无法从 python 引用现有 QML 元素

MYYA 2023-12-29 10:21:06
我不会从 python 动态创建元素,我只是想访问 qml 文件中已声明的现有元素。我使用 findChild 来获取 QObject 引用并连接到信号。这工作正常,但是当我尝试更具体并获取像 QComboBox 这样的小部件(不是 QObject)时,我总是得到 None。我是否遗漏了一些东西或者 findChild 不适合与小部件一起使用?这是我的简单 qml 代码:Window {    visible:true    width:600    height:400    Button {        id: clickMe        objectName: "clickMe"        x: 244        y: 263        text: qsTr("click me!")    }   ComboBox {       id: comboBox       objectName: "comboBox"       x: 199       y: 157       width: 200   }}这是我的Python代码:# qt importsfrom PyQt5.QtQml import QQmlApplicationEnginefrom PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QMessageBoxfrom PyQt5.QtWidgets import QComboBox, QPushButtonfrom PyQt5 import QtWidgets, QtGuifrom PyQt5.QtGui import QIconfrom PyQt5.QtCore import QObjectapp = QApplication(sys.argv)engine = QQmlApplicationEngine()engine.load('main.qml')win = engine.rootObjects()[0]win.show()# this does work because it is QObject:clickMe = win.findChild(QObject, "clickMe")clickMe.clicked.connect(Foo)# this does not work, I get None so can't add items to the combobox:comboBox = win.findChild(QComboBox, "comboBox")comboBox.addItem("a")sys.exit(app.exec_())
查看完整描述

1 回答

?
holdtom

TA贡献1805条经验 获得超10个赞

首先,QML Item Combobox 不是 QtWidgets QComboBox,因此您不应该使用该类进行过滤,这就是您的尝试失败的原因。从 python(或 C++)访问 QML 元素也是不好的做法,因为生命周期不受管理(例如,可以删除并重新创建相同“id”的对象而不通知),相反,您必须创建允许交换信息的 QObject ,例如对于 QComboBox,您可以创建一个模型:


main.py


import os

import sys


# qt imports

from PyQt5.QtCore import pyqtProperty, pyqtSlot, QObject, QUrl

from PyQt5.QtGui import QGuiApplication, QStandardItem, QStandardItemModel

from PyQt5.QtQml import QQmlApplicationEngine


CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))



class Manager(QObject):

    def __init__(self, parent=None):

        super().__init__(parent)

        self._model = QStandardItemModel()


    @pyqtProperty(QObject, constant=True)

    def model(self):

        return self._model


    @pyqtSlot()

    def foo(self):

        print("clicked")



def main():

    app = QGuiApplication(sys.argv)


    manager = Manager()


    engine = QQmlApplicationEngine()

    engine.rootContext().setContextProperty("manager", manager)


    filename = os.path.join(CURRENT_DIR, "main.qml")


    engine.load(QUrl.fromLocalFile(filename))


    item = QStandardItem("a")

    manager.model.appendRow(item)


    sys.exit(app.exec_())



if __name__ == "__main__":

    main()

主.qml


import QtQuick.Window 2.15

import QtQuick.Controls 2.15



Window {

    visible:true

    width:600

    height:400


    Button {

        id: clickMe

        x: 244

        y: 263

        text: qsTr("click me!")

        onClicked: manager.foo()

    }

   ComboBox {

       id: comboBox

       x: 199

       y: 157

       width: 200

       model: manager.model

       textRole: "display"

   }

}


查看完整回答
反对 回复 2023-12-29
  • 1 回答
  • 0 关注
  • 84 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信