在用于编写GUI代码的Qt QML语言中,QML元素(如果我理解的话)在它们变得可见之前并未实际创建。 (编辑:当QML引擎加载时,听起来元素是创建的,但看起来除非元素可见,否则不会建立信号/插槽连接。)
我有一些QML元素(来自QtCharts
的LineSeries
个对象)随时间记录一些数据,我希望他们在我的应用启动后立即开始记录数据,即使{ {1}}包含每个系列的元素不会立即可见(用户必须导航到包含这些元素的页面)。
这可能吗?
一种方法可能是将每个数据系列本身保存在全局QML对象中包含ChartView
的某种QVariantList
中,然后将其动态分配给所需的QPointF
对象。父LineSeries
被实例化。这可以使用ChartView::createSeries
,但我相信填充新系列的唯一方法是调用ChartView
并将其传递给我的C ++后端中的某种ChartView::series()
方法填充系列。
编辑:不确定这是否相关,但我用于导航的GUI元素(即Q_INVOKABLE
在启动时不可见的原因)是{{ 1}}。 ChartView
个对象不是顶级TabView
页面;他们有几个级别了。
编辑2:下面的答案似乎应该工作,但是当我尝试实现它时,我得到了相当无用的错误ChartView
。我put together a minimal (non-)working example here(使用TabView
来运行它;我使用的是Qt 5.5。)
编辑3:上述非工作版本为fixed by simply adding a property alias,感谢Mitch的回答和评论。
答案 0 :(得分:2)
Qt Quick中的项目是在QML引擎加载它们所在的QML时立即创建的(即使它们默认为不可见)。此规则的例外是动态加载其内容的项目,例如Loader
。
在您的编辑中,您说您正在使用TabView
。我认为你的设置是这样的:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
ApplicationWindow {
title: qsTr("Hello World")
width: 800
height: 700
visible: true
TabView {
id: sv
anchors.fill: parent
Tab {
title: "Page 1"
}
Tab {
title: "Page 2"
ChartView {}
}
}
}
尝试将其更改为以下内容:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
ApplicationWindow {
title: qsTr("Hello World")
width: 800
height: 700
visible: true
ChartView {
id: chartView
color: "red"
anchors.fill: parent
visible: false
Component.onCompleted: print("Monitoring data...")
}
TabView {
id: sv
anchors.fill: parent
Tab {
id: tab1
title: "Page 1"
}
Tab {
id: tab2
title: "Page 2"
onActiveChanged: {
if (active) {
chartView.parent = tab2;
chartView.visible = true;
}
}
}
}
}
Tab
是basically just Loader
s,因此他们拥有Loader
的所有API,包括active
属性。此属性可让您知道何时加载该选项卡。在那个阶段之前,它无法进入。
当标签变为活动状态时,我们将ChartView
重新显示给它,以便它显示在正确的位置,然后显示它。
从调试输出中可以看出,ChartView
是在启动时创建的。您可以将其移动到其他位置以控制何时加载,或者......使用Loader
。 :)
编辑:根据此答案和评论中的讨论,OP创建了一个small working example,演示了如何预先加载和重新替换持久性项目。