Qt Quick 常用控件入门:Window、Button、CheckBox 与 RadioButton

📅 2026/7/5 2:33:25 👁️ 阅读次数 📝 编程学习
Qt Quick 常用控件入门:Window、Button、CheckBox 与 RadioButton

Qt Quick 常用控件入门:Window、Control、Button、CheckBox 与 RadioButton

2. 本节学习目标

本节主要学习以下内容:

  • WindowApplicationWindow的作用区别
  • Qt Quick 控件的基本继承关系
  • Control在控件体系中的作用
  • Button的常用属性、信号和自定义样式
  • CheckBox的状态处理和样式自定义
  • RadioButton的使用场景和样式自定义
  • Qt Quick 默认控件为什么在真实项目中经常需要重写样式

3. Qt Quick 控件的整体关系

在 Qt Quick 中,很多常用控件都来自QtQuick.Controls模块。

从继承关系上可以简单理解为:

QObject -> Item -> Control -> AbstractButton -> Button -> CheckBox -> RadioButton

这里有几个关键点:

  • QObject是 Qt 对象体系的基础。
  • Item是 QML 可视化对象的基础类型。
  • Control是 Qt Quick Controls 中多数控件的基类。
  • AbstractButton是按钮类控件的抽象基类。
  • ButtonCheckBoxRadioButton都属于按钮体系。

补充理解:

QML 和 QWidget 都属于 Qt 技术体系,但它们是两套不同的 UI 开发方式。QWidget 更偏传统桌面软件开发,而 QML 更偏声明式界面开发,常用于移动端、嵌入式、车载 HMI 和动态 UI 场景。

4. Window:Qt Quick 的顶级窗口

4.1 Window 是什么

Window是 Qt Quick 中用于创建顶级窗口的类型。一个 QML 程序想要显示出来,通常需要一个窗口作为最外层承载对象。

可以把Window理解成整个 QML 界面的外壳。

示例代码:

import QtQuick Window { width: 1024 height: 600 visible: true title: "Qt Quick Demo" }

常用属性:

  • width:窗口宽度
  • height:窗口高度
  • visible:是否显示窗口
  • title:窗口标题
  • flags:窗口标志位,比如是否显示标题栏

初学者最容易忘的是:

visible: true

如果没有设置visible: true,程序可能已经运行了,但是窗口不会显示出来。

4.2 无标题栏窗口

在桌面应用中,窗口默认会有标题栏。但在嵌入式、车载 HMI、触摸屏项目中,界面通常是全屏或无边框的。

常见写法:

import QtQuick Window { width: 1024 height: 600 visible: true flags: Qt.FramelessWindowHint }

Qt.FramelessWindowHint表示创建无边框窗口。

在车载 HMI 项目中,如果整个屏幕都由 QML 界面接管,就经常会使用无标题栏窗口。

4.3 closing 信号

当窗口关闭时,会触发closing信号。可以在这个信号中做退出前处理,比如保存数据、记录日志、释放资源等。

示例:

import QtQuick Window { width: 1024 height: 600 visible: true onClosing: function(close) { console.log("window is closing") } }

在普通桌面程序里,onClosing比较常见;在车载 HMI 中,窗口本身通常不会频繁关闭,更多是页面切换和状态切换。

5. ApplicationWindow:更完整的应用窗口

ApplicationWindowWindow的子类,它在Window的基础上增加了更完整的应用窗口结构。

它常见的能力包括:

  • menuBar
  • header
  • footer

使用ApplicationWindow时需要导入:

import QtQuick.Controls

示例代码:

import QtQuick import QtQuick.Controls ApplicationWindow { width: 1024 height: 600 visible: true title: "Application Window Demo" header: ToolBar { Label { text: "Header" anchors.centerIn: parent } } footer: ToolBar { Label { text: "Footer" anchors.centerIn: parent } } }

ApplicationWindow更适合带菜单栏、工具栏、状态栏的桌面应用结构。

不过在移动端、嵌入式、车载 HMI 项目中,很多时候不会直接使用传统桌面式结构,而是自己用Window + Item + Loader + 自定义组件搭建页面系统。

6. Control:Qt Quick 控件的基类型

6.1 Control 的作用

Control是 Qt Quick Controls 中很多控件的基类。

一般情况下,我们不会直接这样写:

Control { }

因为Control本身更像一个控件基础框架。它提供了一些通用能力,比如内容区域、背景、内边距等,但具体可见效果通常由子类控件实现。

实际开发中更常用的是:

Button {} CheckBox {} RadioButton {} Label {} TextField {}

6.2 contentItem、background、padding、inset

理解Control,重点要理解几个概念。

contentItem表示控件内容区域。比如按钮中的文字、复选框旁边的文本,都可以通过contentItem自定义。

background表示控件背景。比如按钮的矩形底色、圆角、图片背景等。

padding表示内容区域和控件边界之间的内边距,常见属性包括:

  • topPadding
  • bottomPadding
  • leftPadding
  • rightPadding

inset表示背景和控件边界之间的偏移,常见属性包括:

  • topInset
  • bottomInset
  • leftInset
  • rightInset

这部分对自定义样式非常重要。

很多时候控件看起来“不居中”“文字贴边”“图标和文字间距不对”,本质上都是contentItembackgroundpadding没处理好。

7. Button:最常用的按钮控件

7.1 Button 是什么

Button是 UI 开发中最常用的控件之一,用于响应点击、按下、释放、长按等操作。

简单示例:

import QtQuick import QtQuick.Controls Button { text: "确定" onClicked: { console.log("button clicked") } }

Button继承自AbstractButton,所以很多按钮相关属性和信号其实来自AbstractButton

7.2 Button 常用属性

常用属性包括:

  • width:按钮宽度
  • height:按钮高度
  • enabled:是否可用
  • text:按钮显示文本
  • down:按钮是否处于按下状态
  • autoRepeat:是否开启长按重复触发
  • autoRepeatInterval:长按重复触发间隔

示例:

Button { width: 160 height: 48 text: "长按测试" autoRepeat: true autoRepeatInterval: 200 onClicked: { console.log("clicked") } }

enabled很常用。当设置为false时,按钮不可点击,也不会响应点击事件。

Button { text: "不可点击" enabled: false }

7.3 Button 常用信号

按钮常见信号包括:

  • pressed
  • released
  • clicked
  • doubleClicked
  • pressAndHold
  • toggled

示例:

Button { text: "按钮" onPressed: { console.log("pressed") } onReleased: { console.log("released") } onClicked: { console.log("clicked") } onPressAndHold: { console.log("press and hold") } }

一般情况下,信号触发顺序可以理解为:

pressed -> released -> clicked

如果是长按,则中间可能触发:

pressed -> pressAndHold -> released -> clicked

在桌面平台中,双击比较常见,比如双击打开应用;但在嵌入式触摸屏、车载 HMI 中,通常不建议依赖双击,因为触摸屏上的双击体验不稳定,也不利于安全交互。

7.4 自定义 Button 样式

真实项目中,很少直接使用默认按钮样式。尤其是车载 HMI,按钮通常来自 UI 设计稿,需要自己定义背景、圆角、图片、文字样式和状态变化。

一个简单的圆角按钮示例:

Button { id: root width: 180 height: 56 text: "播放" background: Rectangle { radius: 8 color: root.down ? "#2E7D32" : "#43A047" } contentItem: Text { text: root.text color: "white" font.pixelSize: 20 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } }

这个例子中:

  • background控制按钮背景。
  • contentItem控制按钮文字。
  • root.down判断按钮是否处于按下状态。

7.5 播放/暂停按钮状态切换

课程中提到了一个播放器按钮示例:点击按钮后,在播放和暂停之间切换,并显示不同图片。

可以用一个布尔属性保存状态:

Button { id: playButton width: 80 height: 80 property bool playing: false background: Image { anchors.fill: parent source: playButton.playing ? "pause.png" : "play.png" fillMode: Image.PreserveAspectFit } contentItem: Item {} onClicked: { playing = !playing } }

这个例子的核心思想是:

状态变化 -> 属性变化 -> 图片变化 -> UI 自动刷新

这也是 QML 很重要的写法。不要总想着手动刷新界面,而是让界面绑定到状态。

8. CheckBox:复选框控件

8.1 CheckBox 是什么

CheckBox是复选框,用于表示选中或未选中。

常见场景:

  • 设置页中开启或关闭某个功能
  • 多选配置项
  • 协议勾选
  • 车辆功能开关

简单示例:

import QtQuick import QtQuick.Controls CheckBox { text: "开启自动大灯" onCheckedChanged: { console.log("checked:", checked) } }

8.2 checked 与 checkState

CheckBox常用两个状态相关属性:

  • checked:是否选中,布尔值
  • checkState:更完整的枚举状态

checkState通常有三种状态:

  • Qt.Unchecked
  • Qt.PartiallyChecked
  • Qt.Checked

普通项目里最常用的是选中和未选中,也就是二态复选框。

示例:

CheckBox { text: "自动连接" checked: true onCheckedChanged: { console.log("auto connect:", checked) } }

如果只是关心选中状态变化,优先使用:

onCheckedChanged

8.3 自定义 CheckBox 样式

课程重点强调了CheckBox自定义样式的必要性。

Qt Quick 自带的CheckBox样式依赖平台,视觉效果比较基础。真实产品中,UI 设计师通常会给出明确的选中图标、未选中图标、禁用状态和文字颜色要求。

在 QML 中,常用indicator自定义复选框前面的勾选区域。

示例:

CheckBox { id: checkBox text: "记住选择" indicator: Rectangle { width: 24 height: 24 radius: 4 border.width: 2 border.color: checkBox.checked ? "#1E88E5" : "#999999" color: checkBox.checked ? "#1E88E5" : "transparent" Text { anchors.centerIn: parent text: checkBox.checked ? "✓" : "" color: "white" font.pixelSize: 18 } } contentItem: Text { text: checkBox.text color: checkBox.enabled ? "white" : "#777777" font.pixelSize: 20 leftPadding: checkBox.indicator.width + 12 verticalAlignment: Text.AlignVCenter } }

这个例子中:

  • indicator控制左侧复选框图标。
  • contentItem控制右侧文字。
  • checked决定选中样式。
  • enabled决定禁用样式。

如果项目里有图片资源,也可以用Image替代Rectangle

9. RadioButton:单选框控件

9.1 RadioButton 是什么

RadioButton是单选按钮。它和CheckBox很像,但使用场景不同。

CheckBox适合多选:

可同时选择 A、B、C

RadioButton适合单选:

只能在 A、B、C 中选一个

常见场景:

  • 语言选择
  • 主题选择
  • 驾驶模式选择
  • 单位选择,比如 km/h 或 mph

示例:

Column { RadioButton { text: "中文" checked: true } RadioButton { text: "English" } RadioButton { text: "Deutsch" } }

同一个父级下的多个RadioButton通常会表现出互斥选择效果。如果项目结构复杂,也可以配合ButtonGroup明确管理一组单选按钮。

9.2 RadioButton 常用属性与信号

RadioButton也继承自AbstractButton,所以常用属性和CheckBox类似:

  • width
  • height
  • enabled
  • text
  • checked
  • checkState

状态变化时可以这样处理:

RadioButton { text: "中文" onCheckedChanged: { if (checked) { console.log("language: zh_CN") } } }

注意:

单选按钮一般只关心“被选中”的时刻,所以常见写法是:

if (checked) { // 执行选中后的逻辑 }

否则取消选中时也会触发一次状态变化,容易误处理。

9.3 自定义 RadioButton 样式

RadioButton的自定义思路和CheckBox类似,也是重点改indicatorcontentItem

示例:

RadioButton { id: radio text: "舒适模式" indicator: Rectangle { width: 24 height: 24 radius: 12 border.width: 2 border.color: radio.checked ? "#00C853" : "#999999" color: "transparent" Rectangle { width: 12 height: 12 radius: 6 anchors.centerIn: parent visible: radio.checked color: "#00C853" } } contentItem: Text { text: radio.text color: radio.enabled ? "white" : "#777777" font.pixelSize: 20 leftPadding: radio.indicator.width + 12 verticalAlignment: Text.AlignVCenter } }

这里用两个圆形Rectangle组成单选框:

  • 外层圆表示按钮边框。
  • 内层圆表示选中状态。
  • visible: radio.checked控制内层圆是否显示。

10. 常见问题与踩坑

问题 1:Window 写了但窗口不显示

现象:

程序运行了,但是看不到窗口。

原因:

可能忘记写:

visible: true

解决:

Window { width: 1024 height: 600 visible: true }

复习时记住:

Window是顶级窗口,但默认不一定显示,初学时先检查visible

问题 2:默认控件样式不好看

现象:

ButtonCheckBoxRadioButton默认样式和设计稿差距很大。

原因:

Qt Quick Controls 的默认样式偏通用,不一定适合车载 HMI 或产品级界面。

解决:

根据控件类型自定义:

  • Button:重点改backgroundcontentItem
  • CheckBox:重点改indicatorcontentItem
  • RadioButton:重点改indicatorcontentItem

复习时记住:

真实项目里,控件默认样式通常只是功能验证用,最终大多要按 UI 设计稿重写。

问题 3:Button 的 clicked、pressed、released 分不清

现象:

不知道应该把逻辑写在onClickedonPressed还是onReleased

原因:

这些信号关注的时机不同。

解决:

  • 点击完成后执行逻辑:用onClicked
  • 按下瞬间改变视觉状态:用onPressed或绑定down
  • 松手时处理:用onReleased
  • 长按逻辑:用onPressAndHoldautoRepeat

复习时记住:

大多数普通按钮业务逻辑写在onClicked就够了。

问题 4:CheckBox 和 RadioButton 不知道怎么选

现象:

设置页里不知道该用复选框还是单选框。

原因:

两者都是按钮体系控件,但选择语义不同。

解决:

  • 可以同时选择多个:用CheckBox
  • 一组选项只能选一个:用RadioButton

示例:

是否开启自动大灯:CheckBox 语言选择:RadioButton

11. 小结

这节课的主线很清楚:

先从顶层窗口Window讲起,再介绍更完整的ApplicationWindow,然后进入 Qt Quick Controls 的基础类型Control,最后讲三个最常用的按钮体系控件:ButtonCheckBoxRadioButton

需要重点掌握的是:

  • Window是顶级窗口,初学时记得设置visible: true
  • ApplicationWindow更偏桌面应用窗口结构。
  • Control是很多控件的基类,理解它有助于理解自定义样式。
  • Button是最常用控件,重点掌握属性、信号和样式重写。
  • CheckBox用于多选或开关类选项。
  • RadioButton用于一组选项中的单选。
  • 真实产品开发中,默认控件样式通常无法满足需求,自定义样式是重点。

对车载 HMI 或嵌入式界面开发来说,最重要的不是“会拖一个按钮出来”,而是能把按钮、状态、图片、文字、禁用态、选中态、按下态都封装成稳定可复用的组件。

12. 复习清单

  • Window的作用是什么?
  • 为什么Window经常要写visible: true
  • ApplicationWindowWindow多了哪些结构?
  • 为什么 Qt Quick 更偏移动端、嵌入式和 HMI?
  • ControlItemQObject之间大概是什么继承关系?
  • contentItembackground分别负责什么?
  • paddinginset有什么区别?
  • Button常用属性有哪些?
  • pressedreleasedclicked的触发关系是什么?
  • autoRepeat适合什么场景?
  • 如何自定义一个 Button 的背景和文字?
  • CheckBoxcheckedcheckState有什么区别?
  • CheckBoxindicator通常用来改什么?
  • RadioButtonCheckBox的使用场景区别是什么?
  • 为什么真实项目里经常不用默认控件样式?
  • 如果要做车载 HMI 设置页,哪些控件适合封装成自定义组件?