Qt自定义控件封装
QML 为开发用户界面提供了一个非常强大和灵活的框架。提供的基本元素是低级的,因此您通常需要将用户界面的组件构建成类似小部件的控件。开发一组通用 QML 控件可以大大减少项目的整体开发工作量。
在本系列中(假设您熟悉基本的 QML),我们将从头开始创建一组简约的 QML 控件(即从 QML 原语 Item、 Rectangle、 Text等),它们可以用作您的移动或嵌入式项目中的控件,然后进行修改以适应您的项目的需要(即,这样您就不会从头开始)。
可重复使用的控件
用户界面几乎总是由一组可重复使用的“控件”组成,例如 Button、CheckBox、RadioButton、Switch、Slider 等。这些控件可能被设计为只能在同一个项目中重复使用(例如,屏幕上的两个按钮),或者它们可以是更通用(可定制)的控件,可以在多个项目中重复使用(例如Qt Quick Controls)。
Qt Quick Controls 源代码不打算被修改。相反,开发人员编写单独的“样式代码”进行自定义。在本系列中,我们将采用另一种“通过示例”方法,作为开发人员,您可以 100% 控制每个控件的源代码、外观和行为。
无需编写单独的样式代码(和学习样式 API),您可以直接修改我们控件的源代码。
为了简化它们的本质并使它们保持清晰、简单和可重用,我们创建的控件将遵循以下属性:
- 没有动画:除了Flickable提供的默认滚动动画(例如ListView和GridView)和除非必要(例如 Spinner);但是,您可以添加自己的动画。
- 没有状态和转换:可以添加状态和转换,并且对实现动画很有用。
- 仅 QML(无 C++):这里的重点是 QML 前端;但是,可以添加 C++ 后端。
- 无图像资源(.png、.jpg):确保控件在任何尺寸下看起来都很好,并避免任何版权问题;但是,您可以使用 QML Image元素添加图标。
- 黑白:使控件“无样式”并让您轻松添加配色方案(请参阅下面的样式)和/或图像.png 资产。
- 可调整大小:每个控件都随根项的高度或宽度缩放,以便它在任何尺寸下看起来都很好(因此在任何屏幕尺寸和分辨率上)。
控件
我们将创建的控件列表如下。我们将从一个简单的 Button 开始,然后逐步增加复杂性:
- 按钮Button
- 复选框CheckBox和单选按钮RadioButton
- SwitchButton
- Slider滑块
- 滚动条
- 进度条
- 微调器
- 对话
- 页点
- 标签
- 桌子
- 时间选择器
- 日期选择器
- 条形图
- 折线图
- 饼形图
- 键盘
原语
我们将仅使用下面列出的 QML 原语来构建所有控件:
除了Canvas之外,上述所有原语都在 Qt Quick 1.0 中可用。因此,作为额外的奖励,通过将“import QtQuick 2.0”替换为“import QtQuick 1.0”,我们还可以使用 Qt 4 或qmlviewer在旧代码中使用我们的控件。
造型
上面唯一实际在屏幕上渲染像素的原始项目是Rectangle、Text和Canvas(其余用于布局或用户交互)。Canvas仅用于Rectangle无法处理的几种情况(PieChart 和 LineChart),因此要“样式”(即更改颜色、字体等),Rectangle和Text是您需要修改的唯一项目和/或者可能替换为Image .png 资产。
通过在适当的地方更改Rectangle.color(默认为“白色”)、Rectangle.border.color(默认为“黑色”)和Text.color(默认为“黑色”)来更改颜色。如果您希望在一个地方更改应用程序的字体,而不是在每个Text元素中设置font.family,您可以创建 FontText.qml(如下)并在所有 .qml 文件中使用 FontText 而不是Text :
FontText.qml
import QtQuick 2.0
Text {
font.family: 'Arial'
}
下面是我们的第一个控件:简单且无处不在的 Button,它将让我们了解其余控件将如何开发。每个示例将包括:
- 控件的动画屏幕截图。
- 对如何实施控制的书面描述。
- 控件的源代码(少于 100 行)(可以在 qmlscene 中加载的 .qml 文件),公共和私有部分由注释明确分隔(因为 QML 没有公共或私有关键字)。另请注意,该控件继承了根Item的所有公共属性、方法和信号,其中至少包括Item的那些,例如x、y、width、height、anchors和enabled。
- 文件Test.qml 中的示例用法(即如何创建控件的实例)。
按钮
Button 具有公共文本属性和clicked()信号。它仅由Rectangle、Text和MouseArea组成。Rectangle的边框绘制 Button 的轮廓,而MouseArea管理Button 在按下(“向下状态”)和clicked()信号时的外观。
创建关闭状态的最简单方法是设置根Item的不透明度。其他方法包括设置Rectangle.color或通过Image提供 .png (不建议调整大小)。为了允许调整大小,Rectangle的边框和font.pixelSize与根Item的高度一起缩放,如下所示。
所有 QML Item都有一个enabled属性,我们利用它通过将根Item的不透明度设置为 0.3 (30%) 来提供“禁用状态”,以在启用设置为 false时创建“褪色”外观。
Button.qml
import QtQuick 2.0
Rectangle {
id: root
// public
property string text: 'text'
signal clicked(); // onClicked: print('onClicked')
// private
width: 500; height: 100 // default size
border.color: text? 'black': 'transparent' // Keyboard
border.width: 0.05 * root.height
radius: 0.5 * root.height
opacity: enabled && !mouseArea.pressed? 1: 0.3 // disabled/pressed state
Text {
text: root.text
font.pixelSize: 0.5 * root.height
anchors.centerIn: parent
}
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked: root.clicked() // emit
}
}
Test.qml
import QtQuick 2.0
Button {
text: 'Button'
onClicked: print('Button onClicked')
}
概括
在 QML Controls From Scratch 系列的第一部分中,我们创建了我们的第一个控件:Button。下次我们将创建 CheckBox 和 RadioButton。源代码可以从 这里下载。