将属性注入到 QML 组件中



我对Qt/PyQt相当陌生,目前正在为一些基本功能而苦苦挣扎。我正在尝试做的是从python动态加载QML-Views(*.qml)文件并动态替换特定内容。例如,选中一个复选框,并将当前视图的一部分替换为另一个 qml 文件。首先,我想通过 PyQt 提供这个逻辑,但似乎 StackView 是一个更好的主意(pyqt 中的多个 qml 文件)。

但是,在这种情况下,我无法将属性注入到我的 QML 文件中。我只能将属性注入到根上下文中。但是,这限制了我的QML视图的使用,因为我一次只能使用一个视图(相同类型)。我想将属性动态注入到 QML 视图中,并使它们仅对这个特定视图可见。在这种情况下,我可以多次使用相同的视图,在后端使用多个对象来捕获信号。

这是我的SimpleMainWindow.qml文件(主视图:

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
import QtQuick.Controls 1.4
ApplicationWindow {
id: window
visible: true
width: 640
height: 480
title: qsTr("Hello World")
objectName : "WINDOW"
property ApplicationWindow appWindow : window
}

这是我尝试加载的文件(TestViewButton.qml):

import QtQuick 2.9
import QtQuick.Controls 1.4
Button {
id: test
text: "test"
objectName : "Button"
onClicked: {
configurator.sum(1, 2)
configurator.info("TestOutput")
}
}

Python 文件加载 QML-View (组件)

from PyQt5.QtCore import QObject, QUrl
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine, QQmlComponent
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load("qml/SimpleMainWindow.qml")
engine.quit.connect(app.quit)
rootWindow = engine.rootObjects()[0].children()[0].parent()
# create component
component = QQmlComponent(engine)
component.loadUrl(QUrl("qml/TestViewButton.qml"))
configurator = SignalHandler()
component.setProperty("configurator", configurator)
itm = component.create()
itm.setParentItem(rootWindow.children()[0])
itm.setProperty("configurator", configurator)
app.exec_()

以及我用来处理来自视图的信号的 python 对象 (SignalHandler.py):

from PyQt5.QtCore import QObject, pyqtSlot
class SignalHandler(QObject):
@pyqtSlot(int, int)
def sum(self, arg1, arg2):
print("Adding two numbers")
@pyqtSlot(str)
def info(self, arg1):
print("STR " + arg1)

按钮加载正常(顺便说一下,有没有更好的方法来识别我想添加按钮的父级,没有使用 findChild 查看任何内容)。不起作用的是 component.setProperty...。.part。如果我在引擎的 rootContext 中设置该属性,它可以正常工作(调用信号处理程序方法)。已经检查了类似的主题(例如从另一个 qml 文件动态加载 qml 组件并访问该组件的 qml 类型属性......

这可能吗,还是我在这里弄错了什么?

谢谢

据我了解,您只想在TestViewButton.qml中加载配置对象,并且在SimpleMainWindow.qml中不可见。

为此,TestViewButton.qml加载时必须有自己的QQmlContext,而不是rootContext()

为了测试我的响应并观察该行为,我们将创建一个类似的按钮来尝试使用configurator,如果按下它,它应该抛出一个错误,指出该属性不存在,但如果加载的按钮被QQmlComponent按下应该正常完成其工作。

qml/SimpleMainWindow.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
import QtQuick.Controls 1.4
ApplicationWindow {
id: window
visible: true
width: 640
color: "red"
height: 480
title: qsTr("Hello World")
Button {
x: 100
y: 100
text: "ApplicationWindow"
onClicked: {
console.log("ApplicationWindow")
configurator.sum(1, 2)
configurator.info("TestOutput")
}
}
}

正如我之前评论的那样,我添加了具有新上下文的组件:

if __name__ == "__main__":
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
configurator = SignalHandler()
engine.load("qml/SimpleMainWindow.qml")
engine.quit.connect(app.quit)
rootWindow = engine.rootObjects()[0]
content_item = rootWindow.property("contentItem")
context = QQmlContext(engine)
component = QQmlComponent(engine)
component.loadUrl(QUrl("qml/TestViewButton.qml"))
itm = component.create(context)
context.setContextProperty("configurator", configurator)
itm.setProperty("parent", content_item)
sys.exit(app.exec_())

最后,我们得到以下输出:

qml: Component
Adding two numbers
STR TestOutput
qml: ApplicationWindow
file:///xxx/qml/SimpleMainWindow.qml:20: ReferenceError: configurator is not defined
qml: Component
Adding two numbers
STR TestOutput
qml: ApplicationWindow
file:///xxx/qml/SimpleMainWindow.qml:20: ReferenceError: configurator is not defined

我们观察所需行为的地方。完整的示例可以在以下链接中找到。

相关内容

  • 没有找到相关文章

最新更新