我正在用QML创建一个绘图组件。我的QML组件的结构如下所示:
Rectangle {
id: canvas
objectName: "myPlot"
Rectangle {
id: plot
PlotArea {
id: pa
} // this is my c++ QQuickItem
MouseArea {} // for handling interaction with the plot, like zooming
XAxis{}
YAXis{}
}
}
这里PlotArea
是我的c ++类。我需要与C ++中的这个QML组件进行交互,更准确地说,我需要调用PlotArea
的成员函数来向绘图添加数据。通常的方法是使用findChild<QObject*>("objectName")
,但由于组件将被重用,我无法提供PlotArea
和对象名称。
如果我有指向PlotArea
的指针,如何访问"myPlot"
?我试过了
QObject *plot = rootObjects.value(0)->findChild<QObject*>("plotObject");
PlotArea * myplot = (plot->findChild<PlotArea*>("pa"));
但这不起作用。但是,如果我这样做,那么上述方法是有效的
PlotArea {
id: pa
objectName: "pa"
} // this is my c++ QQuickItem
但是我想知道这是否安全,因为我的应用程序中会有服务PlotAreas,并且所有这些都有#34; pa&#34;。
答案 0 :(得分:5)
除非您正在编写单元测试,否则不应该使用C ++与QML交互。有关说明,请参阅this documentation。
更好的方法是将C ++类型公开给QML。
例如,您可以注册将绘图数据添加为singleton的C ++类:
qmlRegisterSingletonType<PlotDataAdder>("App", 1, 0, "PlotDataAdder", plotDataAdderCreationFunction);
然后你可以用QML做到这一点:
import App 1.0
PlotArea {
id: plotArea
Component.onCompleted: PlotDataAdder.addData(plotArea)
}
这是一种必要的方法。
如果在您的情况下可行,您可以使用qmlRegisterType()
以声明方式执行此操作:
qmlRegisterType<PlotDataSource>("App", 1, 0, "PlotDataSource");
然后,在QML中:
import App 1.0
Window {
PlotDataSource {
id: plotDataSource
}
PlotArea {
id: plotArea
plotData: plotDataSource
}
}
你说情节数据是由硬件动态生成的,所以这种方法在这种情况下会起作用,而使用单例的第一种方法会更难。
或者,如果您无法按需创建C ++类(例如,如果它来自第三方库),请使用setContextProperty()
:
engine.rootContext()->setContextProperty("plotDataSource", plotDataSource);
然后,在QML中:
import App 1.0
Window {
PlotArea {
id: plotArea
plotData: plotDataSource
}
}
答案 1 :(得分:1)
下面的代码只是解决问题的一种方法,但不是正确的答案,因为它会弄乱QML对象的所有权。 PlotArea
从QML
引擎生成,但在C ++端使用。要正确解决问题,建议重新设计PlotArea
。
C ++:
QObject* test = engine.rootObjects()[0]->findChild<QObject*>("test");
PlotArea* plotArea = test->property("plotArea").value<PlotArea*>();
QML:
Item{
objectName: "test"
property var plotArea : plotArea
Item{
PlotArea{
id: plotArea
}
}
}