如何有条件地禁用 QML 绑定到 C++ 后端?
Posted
技术标签:
【中文标题】如何有条件地禁用 QML 绑定到 C++ 后端?【英文标题】:How to conditionally disable QML Binding to C++ backend? 【发布时间】:2020-03-08 15:06:07 【问题描述】:我正在为具有大量属性绑定的嵌入式系统开发 QML 应用程序:许多传感器数据显示在应用程序的不同页面中。一次只能看到 1 页。
当我在page 2
上时,page 1
的属性绑定仍在发生,即使在page 1
上将visible
设置为false
。我希望 QML 仅在页面为 visible
时响应绑定更新,因为它会提高性能。
我已尝试使用Binding
元素,如下所述:Binding QML Type 和此处:Prevent QML Property Bindings when QML object isn't visible?,但我注意到绑定仍将在 QML 中更新。
我想知道是否有可能完全消除绑定,如果不是在page 1
。
我尝试使用绑定元素的代码附在下面。我使用了一个切换activated
属性的按钮,而不是多个页面可见/不可见。
main.qml
Rectangle
x: 280
y: 20
width:200
height:150
color:"red"
Text
y: 76
width: 85
height: 67
text: "off"
Binding on text
value:
// I am surprised to find this prints, regardless of value of controlRect.activated
console.log("new value");
sensorData.sensorReading.toFixed(1)
when: controlRect.activated
Rectangle
id: controlRect
x: 20
y: 20
width:200
height:150
property bool activated: true
color:
if (controlRect.activated)
"green"
else
"yellow"
MouseArea
anchors.fill: parent
onClicked:
console.log("State changed to",!parent.activated);
parent.activated = !parent.activated
backend.cpp,在 main.cpp 中实例化
#include "backend.h"
#include <QQmlContext>
Backend::Backend(QQmlApplicationEngine* engine, QObject *parent) :
QObject(parent)
sensorData = new SensorData();
QQmlContext* ctxt(engine->rootContext());
// Connecting back end object instances to front end
ctxt->setContextProperty("sensorData", sensorData);
sensordata.h
#ifndef SENSORDATA_H
#define SENSORDATA_H
#include <QObject>
#include <QTimer>
class SensorData : public QObject
Q_OBJECT
public:
Q_PROPERTY(double sensorReading MEMBER m_sensorReading NOTIFY sensorReadingChanged)
explicit SensorData(QObject *parent = nullptr);
~SensorData()
private:
double m_sensorReading;
double temp;
QTimer m_timer;
signals:
void sensorReadingChanged();
public slots:
void slot_updateReading();
;
#endif // SENSORDATA_H
sensordata.cpp
#include "sensordata.h"
#include <QDebug>
SensorData::SensorData(QObject *parent) :
QObject(parent)
// for simulating sensor data
srand( (unsigned)time(NULL) );
m_timer.setInterval(100);
m_timer.setSingleShot(false);
QObject::connect(&m_timer, &QTimer::timeout, this, &SensorData::slot_updateReading);
m_timer.start();
// simulate my sensor data
void SensorData::slot_updateReading()
m_sensorReading = modf(rand() / 100000.0, &temp);
emit sensorReadingChanged(); // emit for QML binding to update
【问题讨论】:
【参考方案1】:确实,Binding
似乎仍在评估value
属性,但当when
子句为假时,只是没有将其分配给text
属性。我会考虑这个问题,但也许它背后有一个基本原理。
解决方案是使用State
,如下面的代码所示。这也提供了声明当前未读取该值的可能性。
Rectangle
x: 280
y: 20
width:200
height:150
color:"red"
Text
id: readout
y: 76
width: 85
height: 67
text:
console.log("new value"); //does not print when deactivated
sensorData.sensorReading.toFixed(1)
states: [
State
name: "deactivated"
when: !controlRect.activated
PropertyChanges
target: readout
text: "off"
]
【讨论】:
以上是关于如何有条件地禁用 QML 绑定到 C++ 后端?的主要内容,如果未能解决你的问题,请参考以下文章