Qt 6介绍
Qt Quick
Qt Quick 是 Qt6中使用的用户界面技术的总称。它是在Qt 4引入的,现在扩展到Qt 6。Qt Quick 本身就是几种技术的集合:
- QML-用于用户界面的标记语言
- JavaScript-动态脚本语言
- Qt C + ±高度可移植的增强型 c + + 库
与 HTML 类似,QML 是一种标记语言。它由很多标记组成,在 Qt Quick 中称为类型,这些标记用花括号括起来: Item {}
。它是为了创建用户界面、提高速度和方便开发人员阅读而从头开始设计的。可以使用 JavaScript 代码进一步增强用户界面。使用 Qt C + + ,Qt Quick 很容易通过您自己的原生功能进行扩展。简而言之,声明式 UI 称为前端,原生部分称为后端。这允许您将应用程序的计算密集型和原生操作与用户界面部分分离开来。
在一个典型的项目中,前端是用 QML/JavaScript 开发的。后端代码采用 Qt C + + 开发,与系统进行交互,完成繁重的工作。这允许在更面向设计的开发人员和功能性开发人员之间进行自然的分离。通常,后端使用 Qt Test (Qt 单元测试框架)进行测试,并导出供前端开发人员使用。
Digesting a User Interface 消化用户界面
让我们使用 Qt Quick 创建一个简单的用户界面,它展示了 QML 语言的一些方面。最后,我们将有一个带有旋转叶片的纸风车。
我们从一个名为 main.qml 的空文档开始。我们所有的 QML 文件都有后缀.qml。作为一种标记语言(如 HTML) ,QML 文档需要且只需要一种根类型。在我们的示例中,这是基于背景图像几何形状的带有宽度和高度的 Image 类型:
import QtQuick
Image {
id: root
source: "images/background.png"
}
由于 QML 不限制根类型的类型选择,所以我们使用 Image 类型,并将源属性设置为背景图像作为根。
提示
每种类型都有属性。例如,图像具有宽度和高度属性,每个属性包含一个像素计数。它还具有其他属性,如 source。由于图像类型的大小是从图像大小自动导出的,所以我们不需要自己设置宽度和高度属性。
大多数标准类型都位于Qt Quick模块中,该模块通过.qml文件开头的import语句导入。
id 是一个特殊的可选属性,其中包含一个标识符,可用于引用文档中其他地方的关联类型。重要提示: id 属性在设置后不能更改,也不能在运行时设置。使用 root 作为 root 类型的 id 是本书中使用的一种约定,目的是使引用最顶端的类型在较大的 QML 文档中是可预测的。
前景元素在用户界面中表示杆和风车,被作为单独的图像包括在内。
我们想把杆水平居中放置在背景中,但是垂直方向朝底部偏移。然后我们要把风车放在背景中间。
虽然这个初学者的例子只使用图像类型,随着我们的进步,您将创建更复杂的由许多不同的类型组成的用户界面。
Image {
id: root
...
Image {
id: pole
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
source: "images/pole.png"
}
Image {
id: wheel
anchors.centerIn: parent
source: "images/pinwheel.png"
}
...
}
为了把风车放在中间,我们使用了一个叫做anchor
(锚)的复杂属性。锚定允许您指定父对象和兄弟对象之间的几何关系。例如,将我放在另一个类型(anchors.centerIn: father
)的中心。两端分别有左、右、上、下、居中、填充、垂直居中和水平居中关系。自然,当两个或更多的锚一起使用时,它们应该相互补充: 例如,将一个类型的左侧锚定在另一个类型的顶部是没有意义的。
对于风车,锚定只需要一个简单的锚。
提示
有时候你会想要做一些小的调整,例如,将一个类型稍微偏离中心。这可以通过
anchors.HorizontalCenterOffset
或者anchors.verticalCenterOffset
来完成。类似的调整属性也可用于所有其他锚点。有关锚属性的完整列表,请参阅文档。
提示
将图像放置为根类型(Image)的子类型说明了声明性语言的一个重要概念。你按照图层和分组的顺序描述用户界面的视觉外观,最上面的图层(我们的背景图片)首先绘制,子图层在它的上面,在包含类型的本地坐标系中绘制。
为了使展示更有趣一点,让我们使现场互动。这个想法是当用户在场景中的某个地方按下鼠标时旋转轮子。
我们使用MouseArea
类型并使其覆盖根类型的整个区域。
Image {
id: root
...
MouseArea {
anchors.fill: parent
onClicked: wheel.rotation += 90
}
...
}
当用户在其覆盖的区域内单击鼠标时,鼠标区域发出信号。您可以通过重写 onClick
函数来连接到这个信号。当一个信号被连接时,这意味着它所对应的函数(或多个函数)在信号发出时被调用。在这种情况下,我们说当鼠标点击鼠标区域时,id 为wheel(即风车图像)的类型应该旋转 + 90度。
提示
这种技术适用于每个信号,命名约定在标题大小写为on + SignalName。而且,当属性的值发生变化时,所有属性都会发出信号。对于这些信号,命名约定是
`on${property}Changed`
例如,如果一个 width 属性被更改,您可以使用 onWidthChanged: print (width)
观察它。
每当用户点击id为wheel的图片控件它就旋转,但旋转是在一次跳跃中进行的,而不是随着时间的流动运动。我们可以使用动画实现平滑的运动。动画定义了一段时间内属性更改的发生方式。为了实现这一点,我们使用 Animation 类型的行为属性。该行为为应用于该属性的每个更改指定定义的属性的动画。换句话说,只要属性发生更改,就会运行动画。这只是在 QML 中做动画的许多方法之一。
Image {
id: root
Image {
id: wheel
Behavior on rotation {
NumberAnimation {
duration: 250
}
}
}
}
现在,每当wheel的旋转属性改变,它将使用动画时间为250毫秒的NumberAnimation
,所以每90度转弯将采取250毫秒,产生一个不错的平稳旋转。
提示
你不会真的看到风车模糊。这只是为了指示旋转。(assets文件夹中有一个模糊的风车,如果你想试验一下的话。)
现在,这个风车看起来好多了,表现也很好,同时提供了对 Qt Quick 编程如何工作的基础知识的一个非常简短的了解。