Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从Qt的文档中运行QML状态机示例?_Qt_Qml_Qt5 - Fatal编程技术网

如何从Qt的文档中运行QML状态机示例?

如何从Qt的文档中运行QML状态机示例?,qt,qml,qt5,Qt,Qml,Qt5,在中断了几年之后,我最近又回到了Qt,现在看来QML是新的热门。在过去,我设法从Qt的文档中获得基于小部件的示例,使其相对容易地工作,但是。。。现在,我正在尝试学习QML,但在消除示例代码中的漏洞方面遇到了困难 具体而言,这些文件的内容如下: 以下代码段显示了单击按钮后将完成的状态机: 也许我太天真了,但我想我可以在QtCreator中创建一个新的Qt快速应用程序,并将上面的代码片段粘贴到main.qml中。但是,当我这样做时,我会立即遇到一个错误,即: QQmlApplicationEngin

在中断了几年之后,我最近又回到了Qt,现在看来QML是新的热门。在过去,我设法从Qt的文档中获得基于小部件的示例,使其相对容易地工作,但是。。。现在,我正在尝试学习QML,但在消除示例代码中的漏洞方面遇到了困难

具体而言,这些文件的内容如下:

以下代码段显示了单击按钮后将完成的状态机:

也许我太天真了,但我想我可以在QtCreator中创建一个新的Qt快速应用程序,并将上面的代码片段粘贴到main.qml中。但是,当我这样做时,我会立即遇到一个错误,即:

QQmlApplicationEngine failed to load component
qrc:/main.qml:19 Button is not a type
所以。。。我看了一下文档,发现上面写着:

导入语句:导入QtQuick.Controls 1.4

因此,我将其添加到main.qml的顶部,并尝试再次运行。它“有效”,但是。。。没有主窗口或任何其他视觉内容。嗯。我想我可以看出这有什么意义,也许我不应该替换main.qml的全部内容?因此,我决定尝试保留QtCreator提供的原始QML中的窗口组件,将main.QML文件更改为如下所示:

import QtQuick 2.8                                                                                                                                                                                                                                            
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQml.StateMachine 1.0 as DSM

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Rectangle {
        Button {
            anchors.fill: parent
            id: button
            text: "Finish state"
            DSM.StateMachine {
                id: stateMachine
                initialState: state
                running: true
                DSM.State {
                    id: state1
                    DSM.SignalTransition {
                        targetState: finalState
                        signal: button.clicked
                    }
                }
                DSM.FinalState {
                    id: finalState
                }
                onFinished: Qt.quit()
            }
        }
    }
}
完成此操作后,我运行时会看到一个主窗口,但它是空的。嗯。。。那里不应该至少有一个按钮吗

不管怎么说,我不是那么聪明,在花了将近90分钟的时间才弄明白这一点。Qt的文档作者似乎假设了我根本不具备的QML基本知识水平,因此我无法“填补空白”。这真是太可惜了,因为QML看起来棒极了。我特别兴奋地看到我能用声明性状态机框架做些什么!有人能告诉我这个例子有什么不对吗

如果重要的话,我正在使用Qt5.9.2和QtCreator 4.4.1


更新:在他的回答中,@eyllanesc指出了我上面发布的第二段代码中的一个小错误。在我写id:state1的地方,它应该是id:state。

文档假定对前面的主题有一些基本的了解,在最初的段落中:为您提供了一个您应该阅读和学习的主题列表

和所有语言一样,人们必须阅读代码的错误并分析其逻辑

...main.qml:17:13: QML StateMachine: No initial state set for StateMachine
QStateMachine::start: No initial state set for machine. Refusing to start.
.../main.qml:19: ReferenceError: state is not defined
此错误清楚地表明初始状态未被识别,这可能是由两个原因造成的,第一个原因是您未建立初始状态,第二个原因是您建立了不适当的状态,在您的情况下,这是第二个原因

您已建立初始状态:

initialState: state
但是州不存在,我想你想把州1

initialState: state1
按钮未显示,因为您已确定其大小与父项:anchors.fill:parent的大小相同,并且按钮的父项为矩形,如果未设置矩形,则大小将为0,从而使子项也具有该大小。一种可能的解决方案是建立一个与父对象大小相同的矩形:

import QtQuick 2.8                                                                                                                                                                                                                                            
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQml.StateMachine 1.0 as DSM

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Rectangle {
        anchors.fill: parent
        Button {
            anchors.fill: parent
            id: button
            text: "Finish state"
            DSM.StateMachine {
                id: stateMachine
                initialState: state1
                running: true
                DSM.State {
                    id: state1
                    DSM.SignalTransition {
                        targetState: finalState
                        signal: button.clicked
                    }
                }
                DSM.FinalState {
                    id: finalState
                }
                onFinished: Qt.quit()
            }
        }
    }
}
或不使用矩形:

import QtQuick 2.8                                                                                                                                                                                                                                            
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQml.StateMachine 1.0 as DSM

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Button {
        anchors.fill: parent
        id: button
        text: "Finish state"
        DSM.StateMachine {
            id: stateMachine
            initialState: state1
            running: true
            DSM.State {
                id: state1
                DSM.SignalTransition {
                    targetState: finalState
                    signal: button.clicked
                }
            }
            DSM.FinalState {
                id: finalState
            }
            onFinished: Qt.quit()
        }
    }
}

你的问题是什么?如果您的问题是:是否有一些通用策略可用于从Qt的文档工作中生成QML代码片段?这太宽泛了,所以在SO中脱离主题。@eyllanesc,我理解您的观点,但我不同意。我知道QT的小部件,我可以写一个两段的摘要,描述文档中的C++片段往往会被忽略,并解释用户通常需要提供什么来将它们转换成工作代码。但我不太了解QML,所以我在这里请求其他人提供这些信息。如前所述,我坚信我的问题是可以回答的。但是,如果有帮助,我将接受关于如何运行问题中发布的QML代码段的特定问题的答案。请更改或改进问题,我已发布了一个解决特定问题的回复,并就如何更正未来错误提供了建议。您理解并执行QtWidgets文档的示例,因为您知道它的逻辑,您必须这样做,并从QML中学习。@ellyanesc,谢谢,我完全明白您的意思了。我将澄清这一点,并提出关于状态机示例的问题。在我让它工作之后,我会在几分钟内接受你的答案。谢谢你帮我弄明白这一点,我现在可以开始玩声明性FSM框架了!我最终接受了你的建议,不使用矩形组件。对于遇到这个问题的其他人,我建议跳过我从Qt文档复制的简单示例,直接转到,因为这样更容易看到发生了什么。第一个示例只是在单击按钮时退出,因此它是框架功能的一个不太引人注目的演示。
import QtQuick 2.8                                                                                                                                                                                                                                            
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQml.StateMachine 1.0 as DSM

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Button {
        anchors.fill: parent
        id: button
        text: "Finish state"
        DSM.StateMachine {
            id: stateMachine
            initialState: state1
            running: true
            DSM.State {
                id: state1
                DSM.SignalTransition {
                    targetState: finalState
                    signal: button.clicked
                }
            }
            DSM.FinalState {
                id: finalState
            }
            onFinished: Qt.quit()
        }
    }
}