从 C++ 向 QML 发出信号以读取 Q_PROPERTY 是同步事件吗?

Posted

技术标签:

【中文标题】从 C++ 向 QML 发出信号以读取 Q_PROPERTY 是同步事件吗?【英文标题】:Is emitting a signal from C++ to QML for reading a Q_PROPERTY a synchronous event? 【发布时间】:2013-12-11 02:33:46 【问题描述】:

使用 Qt 5.1 我有这个:

Q_PROPERTY(float d1 MEMBER data1 NOTIFY datas_changed_signal)
Q_PROPERTY(float d2 MEMBER data2 NOTIFY datas_changed_signal)

....

void setOBJ(nobj)
        obj=nobj; //these are pointers to a data structure
        data1=nobj->data1(); //assign to member of this class
        data2=nobj->data2();

        emit datas_changed_signal();
    

我的班级收到一个指向某些数据的指针nobj,然后我希望我的 QML 能够访问这些数据。实际上nobj 包含的数据项远不止2个,但为了简单起见,我在这里表示。

我想知道一些事情。首先,当setOBJ 被频繁、快速地调用时会发生什么。在再次调用setOBJ 之前,QML 是否会收到通知但不会读取MEMBER(data1 或 data2)? QML 会因此错过一些更新吗?例如,如果它是异步的,就会发生这种情况。或者,每次发出高于它的信号时,我是否总是指望 QML 获取数据?

其次,在我看来,在创建中间数据成员以存储来自传入对象 nobj 的数据时,这里存在一些不必要的开销。我尝试了这个:

    Q_PROPERTY(float d1 MEMBER obj->data1() NOTIFY datas_changed_signal)

但 MOC 似乎不喜欢以这种方式使用Q_PROPERTY(无法编译)。会有类似的选择吗?

更新:我发现this method (link) 似乎是 Q_PROPERTY 的可行替代方案,用于将数据从 C++ 发送到 QML,我可以将我的数据片段作为参数发送到 QML 函数。这是一个不错的选择吗?

【问题讨论】:

【参考方案1】:

默认情况下,信号和槽是同步实现的,并且即使异步实现甚至跨越线程边界也总是按顺序处理。所以您不必担心您的 QML 会以错误的顺序获取信号。

事实上,默认情况下,信号实际上会立即触发所有绑定的目标代码。即,这个:

emit datas_changed_signal();

几乎就像打电话:

slotFunction1();
slotFunction2();
...

事实上,任何附加的 QML javascript (onDatas_changed_signal) 都会被立即调用。

信号和槽是向 QML 发送数据的首选方式,因为它为独立于 C++ 底层模型的 QML 提供了更大的支持,所以我会坚持使用属性、信号和槽。您的 QML 代码有一天可能需要扩展,并且在更改属性时会发生多件事,如果您通过属性而不是直接调用 QML 函数来完成,这将变得简单而巧妙。

【讨论】:

我刚刚做了一个测试,使用 Q_PROPERTY 从 C++ 向 QML 发送相同的数据,并通过可调用的方法发送相同的数据。我的数据经常变化,可调用的方法没有数据丢失。但是使用 onDataMember 更改信号时的 Q_PROPERTY 会丢弃大量数据;我真的怀疑幕后正在进行某种排队操作,并且 C++ 数据可能会在 QML 看到它之前发生变化。 您确定您的插槽会在数据更改时被调用吗? 一般来说,在我看来,在使用 QML 时可能需要更多地考虑同步性(不仅仅是使用业务逻辑内部的信号),因为 QML 经常调用本机 GUI 功能(具有在处理其他信号之前您可能需要允许完成的状态(例如模态)。同步问题的症状可能是不同平台上的不同行为。

以上是关于从 C++ 向 QML 发出信号以读取 Q_PROPERTY 是同步事件吗?的主要内容,如果未能解决你的问题,请参考以下文章

从一个进程向另一个 C++ 发出信号

来自 C++ 插件的 QML 类型仅发出一次信号

QML 插槽中未收到 C++ 信号

从写入器向读取器发出信号时正确使用 ReentrantReadWriteLock?

将 qml 信号连接到 Qt

如何从 QML 连接 C++ 对象的破坏信号?