猿问

无法从 python 引用现有 QML 元素

我不会从 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 imports

from PyQt5.QtQml import QQmlApplicationEngine

from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QMessageBox

from PyQt5.QtWidgets import QComboBox, QPushButton

from PyQt5 import QtWidgets, QtGui

from PyQt5.QtGui import QIcon

from PyQt5.QtCore import QObject


app = 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_())


MYYA
浏览 102回答 1
1回答

holdtom

首先,QML Item Combobox 不是 QtWidgets QComboBox,因此您不应该使用该类进行过滤,这就是您的尝试失败的原因。从 python(或 C++)访问 QML 元素也是不好的做法,因为生命周期不受管理(例如,可以删除并重新创建相同“id”的对象而不通知),相反,您必须创建允许交换信息的 QObject ,例如对于 QComboBox,您可以创建一个模型:main.pyimport osimport sys# qt importsfrom PyQt5.QtCore import pyqtProperty, pyqtSlot, QObject, QUrlfrom PyQt5.QtGui import QGuiApplication, QStandardItem, QStandardItemModelfrom PyQt5.QtQml import QQmlApplicationEngineCURRENT_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()主.qmlimport QtQuick.Window 2.15import QtQuick.Controls 2.15Window {    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"   }}
随时随地看视频慕课网APP

相关分类

Python
我要回答