从 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 是同步事件吗?的主要内容,如果未能解决你的问题,请参考以下文章