【问题标题】:QML: How can the state of an item be assigned when the state of a different item changes? (How can I work around the state assignment limitations?)QML:当不同项目的状态发生变化时,如何分配项目的状态? (如何解决状态分配限制?)
【发布时间】:2020-01-26 07:19:28
【问题描述】:

我有一个相当复杂的 QML 组件和项目层次结构。 简而言之:

有一个父 GameGrid QML 类型可以做很多不同的事情。它可以做的事情取决于 GameGrid 当前处于什么状态。 GameGrid 的状态可以通过不同的函数来更改,具体取决于当前状态GameGrid。每当 GameGrid 更改状态时,它会自动触发处理该状态所有内容所需的代码。

有时,在更改状态时,由 GameGrid 运行的代码必须在完成处理后将 GameGrid 状态设置为不同的值。

-

这个操作的结果是:

:QML StateGroup:无法将状态更改应用为状态定义的一部分。

如何在“init”状态完成工作后解决此限制或正确进入“播放”状态?

我尝试过连接信号、函数和分配。

唯一可行的方法是使用一个单独的 Timer 项目,该项目之后会更改状态.. 这种方式过于复杂,无法在有许多状态和对这些状态的许多更改(有时是异步的)的大型代码库中实际实现。

这是重现此错误的最少代码


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

【问题讨论】:

    标签: qt qml qt5


    【解决方案1】:

    在 GameGrid 中定义转换以更改状态机中的状态。

    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 */
                    }
                }
            }
        ]
    
        transitions: Transition { }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-07
      • 1970-01-01
      • 2022-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      相关资源
      最近更新 更多