qt - 属性绑定稍后更新事件框架
问题描述
我有一个暴露给 QML 的 C++ 对象作为myObject
. 这个 C++ 对象有一个Q_PROPERTY
:
Q_PROPERTY (bool myProperty READ getMyPropert NOTIFY myPropertyChanged)
在 QML 中,我将其用作 a 中的守卫,SignalTransition
如下所示:
property bool foo: myObject.myProperty
SignalTransition {
targetState: someState
signal: someSignal
onTriggered: console.info("foo: " + foo)
onTriggered: console.info("myObject.myProperty: " + myObject.myProperty)
}
输出如下:
foo: false
myObject.myProperty: true
稍后的事件框架也foo
将变为true
。
这种行为正常吗?
编辑:
这是一个工作示例:
MyClass.h:
#pragma once
#include <QObject>
class MyClass : public QObject {
Q_OBJECT
Q_PROPERTY(bool myProperty_1 READ getMyProperty_1 NOTIFY myClassChanged)
Q_PROPERTY(bool myProperty_2 READ getMyProperty_2 NOTIFY myClassChanged)
public:
static void initQML();
MyClass();
bool getMyProperty_1();
bool getMyProperty_2();
Q_INVOKABLE void setMyProperty(bool value);
signals:
void myClassChanged();
private:
bool m_MyProperty_1;
bool m_MyProperty_2;
};
我的类.cpp:
#include "MyClass.h"
#include <QtQml>
#include <QDebug>
#include <QMetaType>
/*static*/ void MyClass::initQML() {
qmlRegisterType<MyClass>("Test", 1, 0, "MyClass");
}
MyClass::MyClass() : m_MyProperty_1(false), m_MyProperty_2(false) {
qDebug() << "Constructor called.";
}
bool MyClass::getMyProperty_1() {
return m_MyProperty_1;
}
bool MyClass::getMyProperty_2() {
return m_MyProperty_2;
}
void MyClass::setMyProperty(bool value) {
m_MyProperty_1 = value;
m_MyProperty_2 = value;
myClassChanged();
}
主.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "MyClass.h"
int main(int argc, char *argv[])
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
// Init
MyClass::initQML();
// Main loop
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
main.qml:
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQml.StateMachine 1.0 as QtQml_StateMachine
import Test 1.0
ApplicationWindow {
visible: true
width: 480
height: 272
Component.onCompleted: _stateMachine.start()
// UI
Button {
text: "Switch"
onClicked: {
console.info("Switch pressed with setter")
myClass.setMyProperty(true)
}
}
// StateMachine
property MyClass myClass: MyClass {}
QtQml_StateMachine.StateMachine {
id: _stateMachine
initialState: _defaultState
onStarted: console.info("_stateMachine started")
onExited: console.info("_stateMachine exited")
QtQml_StateMachine.State {
id: _defaultState
property bool myProperty_1: myClass.myProperty_1
property bool myProperty_2: myClass.myProperty_2
onMyProperty_1Changed: console.info("onMyProperty_1Changed: " + myProperty_1)
onMyProperty_2Changed: console.info("onMyProperty_2Changed: " + myProperty_2)
onEntered: console.info("_defaultState entered")
onExited: console.info("_defaultState exited")
// Doesn't work:
QtQml_StateMachine.SignalTransition {
targetState: _nextState
signal: _defaultState.myProperty_1Changed
guard: _defaultState.myProperty_2
onTriggered: console.info("myProperty_2")
}
// Works:
// QtQml_StateMachine.SignalTransition {
// targetState: _nextState
// signal: _defaultState.myProperty_1Changed
// guard: myClass.myProperty_2
// onTriggered: console.info("myClass.myProperty_2")
// }
}
QtQml_StateMachine.State {
id: _nextState
onEntered: console.info("_nextState entered")
onExited: console.info("_nextState exited")
}
}
}
如果您使用评论SignalTransition
它的工作原理。如果您使用另一个,它将无法正常工作。
解决方案
问题是存在竞争条件,因为代理 C++ 对象的属性以具有单独的Changed
信号。这是由于 QML 中的直接连接。
更新按以下顺序进行:
myClassChanged
-> 设置:m_MyProperty_1
(C++) -> 信号myProperty_1Changed
(QML) -> 转换并击中守卫,然后 -> 设置:m_MyProperty_2
(C++) -> 信号m_MyProperty_2Changed
(QML)
如此myProperty_1
赛跑myProperty_2
。
推荐阅读
- r - 有没有办法让 y 轴位于镜像图的中间?
- azure-devops - AZ CLI- 列出 devops 用户
- java - 使用 Apache Ignite 缓存 MySQL 数据库
- yugabyte-db - YugabyteDB 中的最大表大小?
- reactjs - jsx-pdf :根元素必须解析为
, 实际上解析为 undefined - python - “[ERROR] OSError: [Errno 38] Function not implemented” - 通过 Lambda 访问趋势 deepsecurity.ComputersApi
- typescript - 如何将一个函数的返回类型用作另一个函数的参数类型?
- blazor - ASP.NET Core Blazor Server 其他安全方案
- vue-component - 找不到与路径匹配的位置 - Vue 3 + Vue Router 4
- python - dask.bag.read_text 中的 files_per_partitions 关键字