我在最近几年的间隙后回到Qt,看起来QML是新的热点"这些日子。在过去,我设法从Qt的文档中获取基于小部件的示例,以便相对轻松地工作,但是......现在我正在尝试学习QML,我是无法填补示例代码中的空白。
具体来说,Qt.QmlStateMachine
的文档说:
以下代码段显示了单击按钮时将完成的状态机:
import QtQuick 2.0
import QtQml.StateMachine 1.0 as DSM
Rectangle {
Button {
anchors.fill: parent
id: button
text: "Finish state"
DSM.StateMachine {
id: stateMachine
initialState: state
running: true
DSM.State {
id: state
DSM.SignalTransition {
targetState: finalState
signal: button.clicked
}
}
DSM.FinalState {
id: finalState
}
onFinished: Qt.quit()
}
}
}
也许我完全天真,但我想我可以在QtCreator中创建一个新的 Qt Quick 应用程序,并将上面的代码段粘贴到main.qml
中。但是,当我这样做时,我立即面临一个错误说:
QQmlApplicationEngine failed to load component
qrc:/main.qml:19 Button is not a type
所以...我查看了QML Button
type的文档,并注意到它位于顶部附近:
导入声明:
import QtQuick.Controls 1.4
因此,我将其添加到main.qml
的顶部并尝试再次运行。并且它可以工作,但是......没有主窗口或任何其他视觉内容。嗯。我想我可以看到(也许)有意义的地方,或许我不应该替换main.qml
的整个内容?所以我决定尝试保留QtCreator提供的原始QML中的Window
组件,将我的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看起来很棒。我很高兴看到我能用声明式状态机框架做些什么!谁能告诉我这个特定的例子我做错了什么?
(如果重要的话,我使用Qt 5.9.2和QtCreator 4.4.1 ......)
更新:在他的回答中,@ eyllanesc在我上面发布的第二个代码片段中指出了一个小错字。我写id: state1
的地方应该是id: state
。
答案 0 :(得分:1)
本文档假定您对以前主题和初始段落有一些基本了解:http://doc.qt.io/qt-5/qtqml-index.html为您提供了应该阅读和学习的主题列表。
和所有语言一样,必须阅读代码的错误并分析其逻辑。
...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
此错误清楚地表明初始状态未被识别,这可能是由2个原因引起的,第一个原因是您尚未建立它,或者第二个原因是您已经建立了不适当的状态,在您的情况下它是第二个原因。
您已建立初始状态:
initialState: state
但状态不存在,我想你想放置state1
initialState: state1
此按钮未显示,因为您已确定其大小与父级的大小相同:anchors.fill: parent
,而Button
的父级是Rectangle
,并且如果未设置Rectangle
,则大小将为0,导致儿子也拥有它。一种可能的解决方案是将Rectangle设置为父级的大小:
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()
}
}
}
}
或不使用Rectangle:
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()
}
}
}