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