启动时强制信号/插槽连接尚未可见的QML项目

时间:2016-01-06 18:25:03

标签: c++ qt qml

在用于编写GUI代码的Qt QML语言中,QML元素(如果我理解的话)在它们变得可见之前并未实际创建。 (编辑:当QML引擎加载时,听起来元素是创建的,但看起来除非元素可见,否则不会建立信号/插槽连接。)

我有一些QML元素(来自QtChartsLineSeries个对象)随时间记录一些数据,我希望他们在我的应用启动后立即开始记录数据,即使{ {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的回答和评论。

1 个答案:

答案 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;
                }
            }
        }
    }
}

Tabbasically just Loaders,因此他们拥有Loader的所有API,包括active属性。此属性可让您知道何时加载该选项卡。在那个阶段之前,它无法进入。

当标签变为活动状态时,我们将ChartView重新显示给它,以便它显示在正确的位置,然后显示它。

从调试输出中可以看出,ChartView是在启动时创建的。您可以将其移动到其他位置以控制何时加载,或者......使用Loader。 :)

编辑:根据此答案和评论中的讨论,OP创建了一个small working example,演示了如何预先加载和重新替换持久性项目。