我有一个暴露于QML的C ++对象,myObject
。此C ++对象具有Q_PROPERTY
:
Q_PROPERTY (bool myProperty READ getMyPropert NOTIFY myPropertyChanged)
在QML中,我将其用作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;
};
MyClass.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();
}
main.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
,则可以使用。如果您使用另一个,则无法使用。
答案 0 :(得分:0)
问题在于,由于代理C ++对象的属性以具有单独的Changed
信号,因此存在竞争条件。这是由于QML中的直接连接。
此更新按以下顺序工作:
myClassChanged
->设置:m_MyProperty_1
(C ++)->信号myProperty_1Changed
(QML)->过渡并触发后卫,然后->设置:m_MyProperty_2
( C ++)->信号m_MyProperty_2Changed
(QML)
所以myProperty_1
与myProperty_2
比赛。