У меня довольно сложная иерархия компонентов и элементов QML. В двух словах:
Существует родительский тип GameGrid
QML, который может делать много разных вещей. То, что он может сделать, зависит от того, в каком состоянии находится GameGrid
. Состояние GameGrid
может быть изменено различными функциями в зависимости от текущего состояния GameGrid
. Всякий раз, когда GameGrid
изменяет состояния, он автоматически запускает код, необходимый для обработки всего этого состояния.
Иногда, при изменении состояния, код, который запускается GameGrid
должен установить состояние GameGrid
на другое значение после завершения обработки.
-
Результат этой операции:
<Неизвестный файл>: QML StateGroup: невозможно применить изменение состояния как часть определения состояния .
Как мне обойти это ограничение или правильно прийти в состояние «play», как только состояние «init» завершит работу?
Я пытался подключение сигналов, функций и назначений.
Единственное, что работает, - это использование отдельного элемента таймера, который впоследствии изменяет состояние. Этот способ слишком сложен, чтобы его реально реализовать в большой кодовой базе, где много состояния и многие изменения этих состояний, иногда асинхронно.
Вот минимальный код для воспроизведения этой ошибки
GameGrid.qml
import QtQuick 2.0
Item {
id: gameGrid
states: [
State {
name: "init"
StateChangeScript {
script: {
console.log("Init actions");
gameGrid.state = "play"; /* causes the error */
}
}
},
State {
name: "play"
StateChangeScript {
script: {
console.log("Play Actions"); /* never does actions */
}
}
}
]
Text {
anchors.centerIn: parent
text: parent.state
}
}
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
GameGrid {
id: grid
anchors.fill: parent
}
Component.onCompleted: {
grid.state = "init";
}
}
main. cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
StateTest.pro
QT += quick
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp
RESOURCES += qml.qrc
QML_IMPORT_PATH =
QML_DESIGNER_IMPORT_PATH =
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target