04-Qt控件详解.md 88 KB


title: Qt控件详解 tags: [

嵌入式Linux,
Qt,
Qt Widgets,
控件,
QPushButton,
QToolButton,
QRadioButton,
QCheckBox,
QCommandLinkButton,
QDialogButtonBox,
QComboBox,
QFontComboBox,
QLineEdit,
QTextEdit,
QPlainTextEdit,
QSpinBox,
QDoubleSpinBox,
QTimeEdit,
QDateEdit,
QDateTimeEdit,
QDial,
QScrollBar,
QSlider,
QKeySequenceEdit,
QLabel,
QCalendarWidget,
QLCDNumber,
QProgressBar,
QFrame,
QTextBrowser,
QGraphicsView,
I.MX6U,

] created: 2026-09-18 updated: 2026-09-18

pdf_ref: "《【正点原子】I.MX6U嵌入式Qt开发指南V1.2》第七章 Qt控件 7.1 按钮、7.2 输入窗口部件、7.3 显示窗口部件、7.4 显示窗口部件之浏览器;例程 Embedded-Qt-Tutorial/Qt/01/04_qpushbutton~28_qgraphicsview"

Qt控件详解

💡 关联知识:[[05-Qt应用开发/03-信号与槽]]、[[05-Qt应用开发/05-布局容器与模型视图]];延伸阅读:[[编程学习项目/使用Qt和C++构造UI界面/8. 常用控件]]

本篇覆盖《I.MX6U嵌入式Qt开发指南》第七章的前半部分:按钮类(7.1)、输入窗口部件(7.2)、显示窗口部件(7.3)、浏览器类(7.4),共 27 个控件。每个控件都按“控件简介 → 常用属性与信号 → 用法示例(完整源码)→ 运行效果”组织,代码取自配套例程 04_qpushbutton ~ 28_qgraphicsview,去掉版权后可直接编译。


0. 全章总览

0.1 控件继承关系

Qt 的控件几乎都从 QWidget 派生。理解继承关系,就能明白一个控件为什么能使用父类的属性和信号。

classDiagram
    class QObject
    class QWidget
    class QAbstractButton
    class QPushButton
    class QToolButton
    class QRadioButton
    class QCheckBox
    class QCommandLinkButton
    class QDialogButtonBox
    class QAbstractSpinBox
    class QSpinBox
    class QDoubleSpinBox
    class QDateTimeEdit
    class QTimeEdit
    class QDateEdit
    class QAbstractSlider
    class QDial
    class QScrollBar
    class QSlider
    class QFrame
    class QLabel
    class QLCDNumber
    class QProgressBar
    class QAbstractScrollArea
    class QTextEdit
    class QPlainTextEdit
    class QTextBrowser
    class QGraphicsView

    QObject <|-- QWidget
    QWidget <|-- QAbstractButton
    QAbstractButton <|-- QPushButton
    QAbstractButton <|-- QToolButton
    QAbstractButton <|-- QRadioButton
    QAbstractButton <|-- QCheckBox
    QPushButton <|-- QCommandLinkButton
    QWidget <|-- QDialogButtonBox
    QWidget <|-- QAbstractSpinBox
    QAbstractSpinBox <|-- QSpinBox
    QAbstractSpinBox <|-- QDoubleSpinBox
    QAbstractSpinBox <|-- QDateTimeEdit
    QDateTimeEdit <|-- QTimeEdit
    QDateTimeEdit <|-- QDateEdit
    QWidget <|-- QAbstractSlider
    QAbstractSlider <|-- QDial
    QAbstractSlider <|-- QScrollBar
    QAbstractSlider <|-- QSlider
    QWidget <|-- QFrame
    QFrame <|-- QLabel
    QFrame <|-- QLCDNumber
    QWidget <|-- QProgressBar
    QWidget <|-- QAbstractScrollArea
    QAbstractScrollArea <|-- QTextEdit
    QTextEdit <|-- QPlainTextEdit
    QTextEdit <|-- QTextBrowser
    QAbstractScrollArea <|-- QGraphicsView

0.2 本章控件索引

分组 控件 一句话作用 例程
按钮 QPushButton 下压按钮,执行命令或触发事件 04
按钮 QToolButton 工具按钮,通常显示图标,用于工具栏 05
按钮 QRadioButton 单选按钮,一组内多选一 06
按钮 QCheckBox 复选按钮,可多选多,支持三态 07
按钮 QCommandLinkButton 命令链接按钮,带描述文本与箭头 08
按钮 QDialogButtonBox 对话框标准按钮盒 09
输入 QComboBox 下拉组合框 10
输入 QFontComboBox 字体组合框 11
输入 QLineEdit 单行文本编辑框 12
输入 QTextEdit 富文本编辑框 13
输入 QPlainTextEdit 纯文本编辑框 14
输入 QSpinBox 整数微调框 15
输入 QDoubleSpinBox 浮点微调框 16
输入 QTimeEdit / QDateEdit / QDateTimeEdit 时间/日期/日期时间编辑 17
输入 QDial 圆形范围控制(拨盘) 18
输入 QScrollBar 滚动条 19
输入 QSlider 滑动条 20
输入 QKeySequenceEdit 快捷键序列录入 21
显示 QLabel 显示文本或图像 22
显示 QCalendarWidget 月历,选择日期 23
显示 QLCDNumber LCD 风格数字显示 24
显示 QProgressBar 进度条 25
显示 QFrame 框架基类,可画水平/垂直线 26
浏览器 QTextBrowser 带超文本导航的文本浏览器 27
浏览器 QGraphicsView 图形视图框架,可视化场景 28

1. 按钮类

Qt 内置六种按钮部件,都直接或间接继承 QAbstractButton

  • QPushButton:下压按钮,继承 QAbstractButton,被 QCommandLinkButton 继承,通常用于执行命令或触发事件。
  • QToolButton:工具按钮,继承 QAbstractButton,通常放在工具栏,显示图标,支持自动浮起。
  • QRadioButton:单选按钮,继承 QAbstractButton,成组出现,提供“多选一”。
  • QCheckBox:复选按钮,继承 QAbstractButton,提供“多选多”。
  • QCommandLinkButton:命令链接按钮,继承 QPushButton,除文字外默认带一个箭头图标,表明按下会打开另一窗口或页面。
  • QDialogButtonBox:按钮盒,继承 QWidget,用于对话框里的“确定”“取消”等标准按钮。

⚠️ 来源说明:本节不属于《I.MX6U嵌入式Qt开发指南》内容,为扩展知识。

QAbstractButton 是所有按钮的公共基类,它提供按钮共有的一组属性与信号(下方各控件小节中会用到):

成员 类型 说明
setText(QString) / text() 属性 按钮显示文本
setIcon(QIcon) / icon() 属性 按钮图标
setCheckable(bool) 属性 是否可切换选中状态
setChecked(bool) / isChecked() 属性 选中状态
setEnabled(bool) 属性 是否可用
clicked() 信号 被点击(最常用)
pressed() / released() 信号 按下 / 释放
toggled(bool) 信号 可选中按钮的状态变化
setShortcut(QKeySequence) 方法 设置快捷键

1.1 QPushButton

控件简介

QPushButton 继承 QAbstractButton,是最常用的按钮。通常用于执行命令或触发事件。第 4 章已在 Qt Designer 里用过它连接信号槽关闭程序,这里改用纯代码实现。

常用属性与信号

成员 说明
QPushButton(const QString &text, QWidget *parent) 构造时直接传入显示文本与父对象
setGeometry(x, y, w, h) 设置位置与大小
setText(QString) 设置文本
setStyleSheet(QString) 设置样式表,例如背景色
clicked() 点击信号

用法示例

例 04_qpushbutton 窗口换肤:单击不同按钮改变窗口背景色。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
/* 引入QPushButton类 */
#include <QPushButton>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明一个QPushButton对象pushButton1 */
    QPushButton *pushButton1;
    /* 声明一个QPushButton对象pushButton2 */
    QPushButton *pushButton2;

private slots:
    /* 声明对象pushButton1的槽函数 */
    void pushButton1_Clicked();
    /* 声明对象pushButton2的槽函数 */
    void pushButton2_Clicked();
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置宽高为800×480,位置在0, 0。(0, 0)代表原点,Qt默认最左上角的点为原点 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化两个按钮对象,并设置其显示文本为窗口皮肤1和窗口皮肤2 */
    pushButton1 = new QPushButton("窗口皮肤1", this);
    pushButton2 = new QPushButton("窗口皮肤2", this);

    /* 设定两个QPushButton对象的位置 */
    pushButton1->setGeometry(300, 200, 80, 40);
    pushButton2->setGeometry(400, 200, 80, 40);

    /* 信号槽连接 */
    connect(pushButton1, SIGNAL(clicked()), this, SLOT(pushButton1_Clicked()));
    connect(pushButton2, SIGNAL(clicked()), this, SLOT(pushButton2_Clicked()));
}

MainWindow::~MainWindow()
{
}

/* 槽函数的实现 */
void MainWindow::pushButton1_Clicked()
{
    /* 设置主窗口的样式1 */
    this->setStyleSheet("QMainWindow { background-color: rgba(255, 245, 238, 100%); }");
}

/* 槽函数的实现 */
void MainWindow::pushButton2_Clicked()
{
    /* 设置主窗口的样式2 */
    this->setStyleSheet("QMainWindow { background-color: rgba(238, 122, 233, 100%); }");
}

按钮文本不宜设置过小,否则文字可能显示不全。background-color 使用 rgba(r, g, b, a),其中 a 是百分比不透明度。

运行效果说明

编译运行后,点击“窗口皮肤 1”主窗体变为浅色,点击“窗口皮肤 2”变为紫色。窗口默认大小为 800×480。


1.2 QToolButton

控件简介

QToolButton(工具按钮)区别于 QPushButton 的一点是可以带图标。图标与按钮背景图片不是一回事:图标是按钮内容,背景图是按钮底图。工具栏(QToolBar)上放带图标和文本的按钮时,QToolButton 是首选。

常用属性与信号

成员 说明
setIcon(QIcon) 设置图标
setText(QString) 设置文本
setToolButtonStyle(Qt::ToolButtonStyle) 图标与文本的排布方式
clicked() 点击信号

常用的 Qt::ToolButtonStyleQt::ToolButtonIconOnly(只显示图标)、Qt::ToolButtonTextOnly(只显示文本)、Qt::ToolButtonTextBesideIcon(文本在图标旁)、Qt::ToolButtonTextUnderIcon(文本在图标下)、Qt::ToolButtonFollowStyle

用法示例

例 05_qtoolbutton 自定义工具栏:把系统标准图标做成工具按钮嵌入工具栏。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
/* 引入QToolButton类 */
#include <QToolButton>
/* 引入QToolBar类 */
#include <QToolBar>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明一个QToolButton对象 */
    QToolButton *toolButton;
    /* 声明一个QToolBar对象 */
    QToolBar *toolBar;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include <QApplication>
#include <QStyle>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置主窗体的位置和大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化QToolBar对象 */
    toolBar = new QToolBar(this);
    /* 设置toolBar的位置和大小 */
    toolBar->setGeometry(0, 0, 800, 100);

    /* 实例化QStyle类对象,用于设置风格,调用系统类自带的图标 */
    QStyle *style = QApplication::style();

    /* 使用Qt自带的标准图标,可以在帮助文档里搜索QStyle::StandardPixmap */
    QIcon icon = style->standardIcon(QStyle::SP_TitleBarContextHelpButton);

    /* 实例化QToolButton对象 */
    toolButton = new QToolButton();

    /* 设置图标 */
    toolButton->setIcon(icon);
    /* 设置要显示的文本 */
    toolButton->setText("帮助");
    /* 设置toolButton的样式,文本置于图标下方 */
    toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

    /* 最后将toolButton添加到ToolBar里 */
    toolBar->addWidget(toolButton);
}

MainWindow::~MainWindow()
{
}

运行效果说明

运行后工具栏左上角出现一个“帮助”工具按钮,图标在上、文本在下。这种设计在许多带工具栏的软件中都能见到。


1.3 QRadioButton

控件简介

QRadioButton 提供带文本标签的单选框,可在选中(checked)与未选中(unchecked)间切换。同一父对象下默认一次只能选中一个,即“多选一”。典型场景是视频网站切换线路。

常用属性与信号

成员 说明
setText(QString) 设置文本
setChecked(bool) / isChecked() 设置/读取选中状态
toggled(bool) 选中状态变化信号
clicked() 点击信号

用法示例

例 06_radiobutton 仿手机开关:用 qss 样式表把单选框画成开关图片。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
/* 引入QRadioButton */
#include <QRadioButton>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明两个QRadioButton对象 */
    QRadioButton *radioButton1;
    QRadioButton *radioButton2;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 主窗体设置位置和显示的大小 */
    this->setGeometry(0, 0, 800, 480);
    this->setStyleSheet("QMainWindow {background-color: rgba(200, 50, 100, 100%);}");

    /* 实例化对象 */
    radioButton1 = new QRadioButton(this);
    radioButton2 = new QRadioButton(this);

    /* 设置两个QRadioButton的位置和显示大小 */
    radioButton1->setGeometry(300, 200, 100, 50);
    radioButton2->setGeometry(400, 200, 100, 50);

    /* 设置两个QRadioButton的显示文本 */
    radioButton1->setText("开关一");
    radioButton2->setText("开关二");

    /* 设置初始状态,radioButton1的Checked为false,另一个为true */
    radioButton1->setChecked(false);
    radioButton2->setChecked(true);
}

MainWindow::~MainWindow()
{
}

main.cpp(引入资源里的 qss 并设为全局样式):

#include "mainwindow.h"

#include <QApplication>
/* 引入QFile */
#include <QFile>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    /* 指定文件 */
    QFile file(":/style.qss");

    /* 判断文件是否存在 */
    if (file.exists() ) {
        /* 以只读的方式打开 */
        file.open(QFile::ReadOnly);
        /* 以字符串的方式保存读出的结果 */
        QString styleSheet = QLatin1String(file.readAll());
        /* 设置全局样式 */
        qApp->setStyleSheet(styleSheet);
        /* 关闭文件 */
        file.close();
    }
    MainWindow w;
    w.show();
    return a.exec();
}

style.qss

QRadioButton {
  spacing: 2px;
  color: white;
}
QRadioButton::indicator {
  width: 45px;
  height: 30px;
}
QRadioButton::indicator:unchecked {
  image: url(:/images/switch_off.png);
}
QRadioButton::indicator:checked {
  image: url(:/images/switch_on.png);
}

资源文件添加步骤(后续例程通用):右键项目 → Add New… → Qt → Qt Resource Files → 命名(如 res);在 res.qrcAdd Prefix/(必写,类似 Linux 根节点);再 Add Files 添加 images/ 下的图片(images 文件夹需先手动创建);Ctrl+S 保存后生效。qss 文件则通过 Add New… → 选择 qss 模板创建。

运行效果说明

点击“开关一”,开关二自动关闭;点“开关二”,开关一则打开——同组互斥。因为 indicator 使用了开/关两张图片,看上去就像手机开关。


1.4 QCheckBox

控件简介

QCheckBox 继承 QAbstractButton。与 QRadioButton 的区别是选择模式:单选提供“多选一”,复选提供“多选多”。开启三态后还有“半选”状态,常见于安装程序。

常用属性与信号

成员 说明
setText(QString) 设置文本
setTristate(bool) 开启三态(不开启只有选中/未选中)
setCheckState(Qt::CheckState) 设置状态
checkState() 读取状态
stateChanged(int) 状态变化信号(返回 Qt::Checked / Qt::Unchecked / Qt::PartiallyChecked

用法示例

例 07_qcheckbox 三态选择框:点击复选框循环显示三种状态文本。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
/* 引入QCheckBox */
#include <QCheckBox>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明一个QCheckBox对象 */
    QCheckBox *checkBox;
private slots:
    /* 声明QCheckBox的槽函数,并带参数传递,用这个参数接收信号的参数 */
    void checkBoxStateChanged(int);

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 主窗体设置位置和显示的大小及背景颜色 */
    this->setGeometry(0, 0, 800, 480);
    this->setStyleSheet("QMainWindow {background-color: rgba(100, 100, 100, 100%);}");

    /* 实例化对象 */
    checkBox = new QCheckBox(this);

    /* 设置QCheckBox位置和显示大小 */
    checkBox->setGeometry(350, 200, 250, 50);

    /* 初始化三态复选框的状态为Checked */
    checkBox->setCheckState(Qt::Checked);

    /* 设置显示的文本 */
    checkBox->setText("初始化为Checked状态");

    /* 开启三态模式,必须开启,否则只有两种状态,即Checked和Unchecked */
    checkBox->setTristate();

    /* 连接checkBox的信号stateChanged(int),与我们定义的槽checkBoxStateChanged(int)连接 */
    connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(checkBoxStateChanged(int)));
}

MainWindow::~MainWindow()
{
}

/* 槽函数的实现 */
void MainWindow::checkBoxStateChanged(int state)
{
    /* 判断checkBox的state状态,设置checkBox的文本 */
    switch (state) {
    case Qt::Checked:
        /* 选中状态 */
        checkBox->setText("Checked状态");
        break;
    case Qt::Unchecked:
        /* 未选中状态 */
        checkBox->setText("Unchecked状态");
        break;
    case Qt::PartiallyChecked:
        /* 半选状态 */
        checkBox->setText("PartiallyChecked状态");
        break;
    default:
        break;
    }
}

style.qss

QCheckBox {
  spacing: 5px;
  color: white;
}
QCheckBox::indicator {
  width: 50px;
  height: 50px;
}
QCheckBox::indicator:enabled:unchecked {
  image: url(:/images/unchecked.png);
}
QCheckBox::indicator:enabled:checked {
  image: url(:/images/checked.png);
}
QCheckBox::indicator:enabled:indeterminate {
  image: url(:/images/indeterminate.png);
}

main.cpp 与 1.3 节相同(加载 qss 并设为全局样式)。

运行效果说明

多次点击复选框,文本在 CheckedPartiallyCheckedUnchecked 三种状态间循环,indicator 显示对应图片。


1.5 QCommandLinkButton

控件简介

QCommandLinkButton(命令链接按钮)继承 QPushButton。与 QRadioButton 相似,用于在互斥选项中选择一项;表面上同平面按钮,但默认带一个箭头图标,表示按下会打开另一个窗口或页面。

常用属性与信号

成员 说明
QCommandLinkButton(const QString &text, const QString &description, QWidget *parent) 构造:文本 + 描述 + 父对象
setDescription(QString) 设置描述文本
setIcon(QIcon) 设置图标
clicked() 点击信号

用法示例

例 08_qcommandlinkbutton 链接窗口:点击按钮调用系统窗口打开 /home 目录。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
/* 引入QCommandLinkButton */
#include <QCommandLinkButton>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明一个QCommandLinkButton对象 */
    QCommandLinkButton *commandLinkButton;

private slots:
    /* 声明槽函数,用于点击commandLinkButton后触发 */
    void commandLinkButtonClicked();
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
/* 引入桌面服务,用来打开系统文件夹对话框 */
#include <QDesktopServices>
/* 引入QUrl */
#include <QUrl>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 主窗体设置位置和显示的大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化对象,原型为:
     * QCommandLinkButton(const QString &text, const QString &description, QWidget *parent) */
    commandLinkButton = new QCommandLinkButton(
                "打开/home目录", "点击此将调用系统的窗口打开/home目录",this);

    /* 设置QCommandLinkButton位置和显示大小 */
    commandLinkButton->setGeometry(300, 200, 250, 60);

    /* 信号槽连接 */
    connect(commandLinkButton, SIGNAL(clicked()), this,
            SLOT(commandLinkButtonClicked()));
}

MainWindow::~MainWindow()
{
}

void MainWindow::commandLinkButtonClicked()
{
    /* 调用系统服务打开/home目录 */
    QDesktopServices::openUrl(QUrl("file:////home/") );
}

运行效果说明

点击“打开 /home 目录”按钮,系统弹出文件管理窗口,定位到 /home 目录。


1.6 QDialogButtonBox

控件简介

不同平台的对话框按钮布局不同。QDialogButtonBox 允许开发人员添加按钮,并自动使用适合当前桌面环境的布局。既可以使用系统自带的标准按钮,也可以自定义按钮。

标准按钮(QDialogButtonBox::StandardButton)包括:OkCancelOpenSaveCloseDiscardApplyResetRestoreDefaultsHelpSaveAll 等。

常用属性与信号

成员 说明
addButton(StandardButton) 添加标准按钮
addButton(QAbstractButton*, ButtonRole) 添加自定义按钮并指定角色
button(StandardButton) 取得某个标准按钮的指针
clicked(QAbstractButton*) 按钮点击信号,可判断点了哪个

用法示例

例 09_qdialogbuttonbox:同时使用标准按钮“取消”和自定义按钮“自定义”。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
/* 引入QDialogButtonBox */
#include <QDialogButtonBox>
/* 引入QPushButton */
#include <QPushButton>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明一个QDialogButtonBox对象 */
    QDialogButtonBox *dialogButtonBox;

    /* 声明一个QPushButton对象 */
    QPushButton *pushButton;

private slots:
    /* 声明信号槽,带QAbstractButton *参数,用于判断点击了哪个按钮 */
    void dialogButtonBoxClicked(QAbstractButton *);

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
/* 引入QDebug */
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 主窗体设置位置和显示的大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化并设置按钮的盒子的大小和位置 */
    dialogButtonBox = new  QDialogButtonBox(this);
    dialogButtonBox->setGeometry(300, 200, 200, 30);

    /* 使用Qt的Cancel按钮 */
    dialogButtonBox->addButton(QDialogButtonBox::Cancel);

    /* 将英文"Cancel"按钮设置为中文"取消" */
    dialogButtonBox->button(QDialogButtonBox::Cancel)->setText("取消");

    /* 实例化自定义按钮 */
    pushButton = new QPushButton(tr("自定义"));

    /* 将pushButton添加到dialogButtonBox,并设定ButtonRole为ActionRole */
    dialogButtonBox->addButton(pushButton, QDialogButtonBox::ActionRole);

    /* 信号槽连接,带参数QAbstractButton *,用于判断用户点击哪个按键 */
    connect(dialogButtonBox, SIGNAL(clicked(QAbstractButton * )),
            this, SLOT(dialogButtonBoxClicked(QAbstractButton *)));
}

MainWindow::~MainWindow()
{
}

void MainWindow::dialogButtonBoxClicked(QAbstractButton *button)
{
    /* 判断点击的对象是否为QDialogButtonBox::Cancel */
    if(button == dialogButtonBox->button(QDialogButtonBox::Cancel)) {
        /* 打印“单击了取消键” */
        qDebug() <<"单击了取消键"<<endl;
    /* 判断点击的对象是否为pushButton */
    }else if(button == pushButton) {
        /* 打印“单击了自定义键” */
        qDebug() <<"单击了自定义键"<<endl;
    }
}

addButton 的重载原型为 void QDialogButtonBox::addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role)qDebug() 是 Qt 的调试打印,功能与 C++ 的 cout 类似,输出到“应用程序输出”窗口。

运行效果说明

点击“自定义”与“取消”按钮,应用程序输出窗口分别打印“单击了自定义键”“单击了取消键”。


2. 输入窗口部件

Qt Designer 的输入部件面板提供 16 种输入部件,涵盖组合框、编辑框、微调框、拨盘、滚动条、滑动条、快捷键录入等。下面按例程逐个讲解。

2.1 QComboBox

控件简介

QComboBox 继承 QWidget,被 QFontComboBox 继承。它以占用最少屏幕空间的方式向用户展示选项列表,是最常用的下拉控件。

常用属性与信号

成员 说明
addItem(QString) 添加一项
itemText(int index) 取第 index 项的文本
currentIndex() 当前索引
count() 项数
currentIndexChanged(int) 当前项改变信号

用法示例

例 10_qcombobox 选择省份:选项变化时打印省份名。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
/* 引入QComboBox */
#include <QComboBox>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明一个QComboBox对象 */
    QComboBox *comboBox;

private slots:
    /* 声明QComboBox对象的槽函数 */
     void comboBoxIndexChanged(int);

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
/* 引入QDebug */
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置主窗体的显示位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化对象 */
    comboBox = new QComboBox(this);

    /* 设置comboBox的显示位置与大小 */
    comboBox->setGeometry(300, 200, 150, 30);

    /* 添加项,我们添加三个省份,作为comboBox的三个选项 */
    comboBox->addItem("广东(默认)");
    comboBox->addItem("湖南");
    comboBox->addItem("四川");

    /* 信号槽连接 */
    connect(comboBox, SIGNAL(currentIndexChanged(int)), this,
            SLOT(comboBoxIndexChanged(int)));
}

MainWindow::~MainWindow()
{
}

void MainWindow::comboBoxIndexChanged(int index)
{
    /* 打印出选择的省份 */
    qDebug()<<"您选择的省份是"<< comboBox->itemText(index)<<endl;
}

运行效果说明

点击下拉框选择“湖南”,输出窗口打印“您选择的省份是湖南”。多账号登录等场景常用此控件。


2.2 QFontComboBox

控件简介

QFontComboBox 继承 QComboBox,是选择字体系列的组合框。列表按字母顺序填充系统字体家族名,常用于工具栏中配合字号、粗体、斜体按钮使用。

常用属性与信号

成员 说明
currentFontChanged(QFont) 当前字体变化信号
itemText(int index) 取第 index 项名称
currentIndex() 当前索引

用法示例

例 11_qfontcombobox 字体选择:选择字体后,标签立即用该字体显示。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
/* 引入QFontComboBox */
#include <QFontComboBox>
/* 引入QLabel */
#include <QLabel>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明一个QFontComboBox对象 */
    QFontComboBox *fontComboBox;
    /* 声明一个Label对象,用于显示当前字体变化 */
    QLabel *label;

private slots:
    /* 声明QFontComboBox对象使用的槽函数 */
    void fontComboBoxFontChanged(QFont);

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置主窗体的显示位置和大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化对象 */
    fontComboBox = new QFontComboBox(this);
    label = new QLabel(this);

    /* 设置显示的位置与大小 */
    fontComboBox->setGeometry(280, 200, 200, 30);
    label->setGeometry(280, 250, 300, 50);

    /* 信号与槽连接 */
    connect(fontComboBox, SIGNAL(currentFontChanged(QFont)), this,
            SLOT(fontComboBoxFontChanged(QFont)));
}

MainWindow::~MainWindow()
{
}

/* 槽函数实现 */
void MainWindow::fontComboBoxFontChanged(QFont font)
{
    /* 将label里的文本内容设置为所选择的字体 */
    label->setFont(font);

    /* 定义一个字符串接收当前项的字体 */
    QString str = "用此标签显示字体效果\n设置的字体为:" +
            fontComboBox->itemText(fontComboBox->currentIndex());

    /* 将字符串的内容作为label的显示内容 */
    label->setText(str);
}

运行效果说明

选择字体后,标签文字立即变成该字体,并显示字体名称。Ubuntu 与 Windows 字体不同,效果会有差异。


2.3 QLineEdit

控件简介

QLineEdit 是单行文本编辑器,允许输入和编辑一行纯文本,支持撤销/重做、剪切/粘贴、拖放。通过 setEchoMode() 还可作为“只写”字段输入密码。

常用属性与信号

成员 说明
text() 读取文本
setText(QString) 设置文本
clear() 清空
setEchoMode(QLineEdit::EchoMode) 回显模式(如 Password
textChanged(QString) / returnPressed() 文本变化 / 回车信号

用法示例

例 12_qlineedit 单行输入框:点击“确认”把输入内容显示到标签,并清空输入框。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private:
    /* 声明一个QLineEdit对象 */
    QLineEdit *lineEdit;

    /* 声明一个QPushButton对象 */
    QPushButton *pushButton;

    /* 声明一个QLabel对象 */
    QLabel *label;

private slots:
    /* 声明一个槽函数,响应pushButton的clicked事件 */
    void pushButtonClicked();
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(0, 0, 800, 480);

    lineEdit = new QLineEdit(this);
    lineEdit->setGeometry(280, 200, 200, 20);

    pushButton = new QPushButton(this);
    pushButton->setGeometry(500, 200, 50, 20);
    pushButton->setText("确认");

    label = new QLabel(this);
    label->setGeometry(280, 250, 400, 20);
    label->setText("你输入的内容是:");

    /* 信号槽连接 */
    connect(pushButton,SIGNAL(clicked()), this,
            SLOT(pushButtonClicked()));
}

MainWindow::~MainWindow()
{
}

void MainWindow::pushButtonClicked()
{
    /* 字符串变量str */
    QString str;

    str = "你输入的内容是:";
    str += lineEdit->text();

    /* 设置label里的文本显示内容 */
    label->setText(str);
    /* 在点击了确认键之后清空lineEdit单行输入框 */
    lineEdit->clear();
}

运行效果说明

输入文本后点击“确认”,标签显示输入内容,输入框被清空,可继续输入。


2.4 QTextEdit

控件简介

QTextEdit 继承 QAbstractScrollArea,被 QTextBrowser 继承。它是高级的所见即所得查看器/编辑器,支持 HTML 样式的富文本(字体、颜色、图片、列表、表格),并针对大型文档和快速响应做了优化。内容超出视图时自动出现滚动条。

常用属性与信号

成员 说明
setText(QString) / toPlainText() 设置/读取纯文本
setHtml(QString) / toHtml() 设置/读取富文本
selectAll() 全选
clear() 清空
setFocus() 设置焦点
textChanged() 文本变化信号

用法示例

例 13_qtextedit 文本编辑框:两个按钮模拟全选与清除。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QTextEdit>
#include <QPushButton>

#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明一个QTextEdit对象 */
    QTextEdit *textEdit;

    /* 声明两个QPushButton对象 */
    QPushButton *pushButtonSelectAll;
    QPushButton *pushButtonClearAll;

private slots:
    /* 声明两个槽函数,响应按钮点击响应的事件 */
    void pushButtonSelectAllClicked();
    void pushButtonClearAllClicked();

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置主窗体显示的位置和大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化对象,设置位置和显示大小 */
    textEdit = new QTextEdit(this);
    textEdit->setGeometry(0, 0, 800, 400);

    /* 全选按钮 */
    pushButtonSelectAll = new QPushButton(this);
    pushButtonSelectAll->setGeometry(200, 420, 50, 20);
    pushButtonSelectAll->setText("全选");

    /* 清除按钮 */
    pushButtonClearAll = new QPushButton(this);
    pushButtonClearAll->setGeometry(500, 420, 50, 20);
    pushButtonClearAll->setText("清除");

    /* 信号槽连接 */
    connect(pushButtonSelectAll, SIGNAL(clicked()), this,
            SLOT(pushButtonSelectAllClicked()));
    connect(pushButtonClearAll, SIGNAL(clicked()), this,
            SLOT(pushButtonClearAllClicked()));

}

MainWindow::~MainWindow()
{
}

void MainWindow::pushButtonSelectAllClicked()
{
    /* 设置焦点为textEdit */
    textEdit->setFocus();
    /* 判断文本编辑框内容是否为空,不为空则全选 */
    if(!textEdit->toPlainText().isEmpty()){
        /* 全选 */
        textEdit->selectAll();
    }
}

void MainWindow::pushButtonClearAllClicked()
{
    /* 清空textEdit里的文本内容 */
    textEdit->clear();
}

运行效果说明

在编辑框输入文字后,点击“全选”文字被选中(必须先 setFocus(),否则无法选中);点击“清除”清空全部内容。


2.5 QPlainTextEdit

控件简介

QPlainTextEdit 是支持纯文本的高级查看器/编辑器,可理解为 QTextEdit 的低配版:只支持纯文本,不支持富文本,但显示效率更高。需要显示大量文字、频繁滚动时,QPlainTextEdit 表现更好。

常用属性与信号

成员 说明
insertPlainText(QString) 插入纯文本
setPlainText(QString) / toPlainText() 设置/读取纯文本
setReadOnly(bool) 只读模式
textChanged() 文本变化信号

用法示例

例 14_qplaintextedit 文本浏览编辑器:读取当前目录下的 moc_mainwindow.cpp 并按只读开关切换。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QPlainTextEdit>
#include <QRadioButton>

#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明对象 */
    QPlainTextEdit *plainTextEdit;
    QRadioButton *radioButton;

private slots:
    /* 槽函数 */
    void radioButtonClicked();

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include <QDir>
#include <QTextStream>
#include <QCoreApplication>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置当前程序的工作目录为可执行程序的工作目录 */
    QDir::setCurrent(QCoreApplication::applicationDirPath());

    this->setGeometry(0, 0, 800, 480);

    plainTextEdit = new QPlainTextEdit(this);
    plainTextEdit->setGeometry(0, 50, 800, 430);

    radioButton = new QRadioButton(this);
    radioButton->setGeometry(650, 20, 100, 20);
    radioButton->setText("只读模式");

    /* 打开可执行程序目录里的moc_mainwindow.cpp,注意如果是Windows下
       moc_mainwindow.cpp并不在当前目录,而在上一级目录"../moc_mainwindow.cpp" */
    QFile file("moc_mainwindow.cpp");

    /* 以只读模式打开,但是可以在plainTextEdit里编辑 */
    file.open((QFile::ReadOnly | QFile::Text));

    /* 加载到文件流 */
    QTextStream in(&file);

    /* 从文本流中读取全部 */
    plainTextEdit->insertPlainText(in.readAll());

    /* 信号槽连接 */
    connect(radioButton, SIGNAL(clicked()), this,
            SLOT(radioButtonClicked()));

}

MainWindow::~MainWindow()
{
}

void MainWindow::radioButtonClicked()
{
    /* 检查radioButton是否选中 */
    if(radioButton->isChecked()) {
        /* 设置为只读模式 */
        plainTextEdit->setReadOnly(true);
    } else {
        /* 设置为非只读模式 */
        plainTextEdit->setReadOnly(false);
    }
}

运行效果说明

程序启动后把可执行目录下的 moc_mainwindow.cpp 读入编辑框,此时可编辑;勾选“只读模式”后不可编辑,取消勾选后恢复编辑。


2.6 QSpinBox

控件简介

QSpinBox 继承 QAbstractSpinBox,用于处理整数和离散值。用户可通过上下按钮、键盘上下键或手动输入来增减当前值。

常用属性与信号

成员 说明
setRange(int min, int max) 范围
setSingleStep(int) 步长
setValue(int) / value() 当前值
setPrefix(QString) / setSuffix(QString) 前缀/后缀
valueChanged(int) 值变化信号

用法示例

例 15_qspinbox 窗口不透明度调节器:用微调框控制窗体透明度。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSpinBox>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明一个QSpinBox对象 */
    QSpinBox *spinBox;
private slots:
    /* 槽函数 */
    void spinBoxValueChanged(int);
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(0, 0, 800, 480);

    /* 设置主窗口背景颜色,rgb颜色标准,a代表不透明度(0~100)*/
    this->setStyleSheet("QMainWindow{background-color: "
                        "rgba(100, 100, 100, 100%) }");

    spinBox = new QSpinBox(this);
    spinBox->setGeometry(350, 200, 150, 30);

    /* 设置范围0~100 */
    spinBox->setRange(0, 100);

    /* 设置步长为10 */
    spinBox->setSingleStep(10);

    /* 设置初始值为100 */
    spinBox->setValue(100);

    /* 设置后缀 */
    spinBox->setSuffix("%不透明度");

    /* 信号槽连接 */
    connect(spinBox,SIGNAL(valueChanged(int)), this,
            SLOT(spinBoxValueChanged(int)));
}

MainWindow::~MainWindow()
{
}

void MainWindow::spinBoxValueChanged(int opacity)
{
    /* 转换为double数据类型 */
    double  dobleopacity = (double)opacity / 100;

    /* 设置窗体不透明度,范围是0.0~1.0。1则为不透明,0为全透明 */
    this->setWindowOpacity(dobleopacity);
}

运行效果说明

初始不透明度 100% 即完全不透明;点向下微调后值变小,整个窗口逐渐透明。


2.7 QDoubleSpinBox

控件简介

QDoubleSpinBox 继承 QAbstractSpinBox,用于处理浮点值,用法与 QSpinBox 基本相同,区别是数据类型为浮点。

常用属性与信号

成员 说明
setRange(double min, double max) 范围
setSingleStep(double) 步长
setValue(double) / value() 当前值
setPrefix(QString) / setSuffix(QString) 前缀/后缀
valueChanged(double) 值变化信号

用法示例

例 16_qdoublespinbox 窗口大小调节器:按百分比缩放整个窗口。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDoubleSpinBox>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明一个QDoubleSpinBox对象 */
    QDoubleSpinBox *doubleSpinBox;

private slots:
    /* 槽函数 */
    void doubleSpinBoxValueChanged(double);

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(0, 0, 800, 480);

    /* 实例化和设置显示的位置与大小 */
    doubleSpinBox = new QDoubleSpinBox(this);
    doubleSpinBox->setGeometry((this->width() - 200) / 2,
                               (this->height() - 30) / 2,
                               200, 30);
    /* 设置前缀 */
    doubleSpinBox->setPrefix("窗口大小");

    /* 设置后缀 */
    doubleSpinBox->setSuffix("%");

    /* 设置范围 */
    doubleSpinBox->setRange(50.00, 100.00);

    /* 设置初始值 */
    doubleSpinBox->setValue(100.00);

    /* 设置步长 */
    doubleSpinBox->setSingleStep(0.1);

    /* 信号槽连接 */
    connect(doubleSpinBox, SIGNAL(valueChanged(double)),
            SLOT(doubleSpinBoxValueChanged(double)));

}

MainWindow::~MainWindow()
{
}

void MainWindow::doubleSpinBoxValueChanged(double value)
{
    /* 重新计算窗口的宽与高 */
    int w = 800 * value / 100;
    int h = 480 * value / 100;

    /* 重新设置窗口的宽与高 */
    this->setGeometry(0, 0, w, h);

    /* 重新设置doubleSpinBox的显示位置 */
    doubleSpinBox->setGeometry((this->width() - 200) / 2,
                               (this->height() - 30) / 2,
                               200, 30);

}

运行效果说明

窗口初始 100%,向下调节时窗口按比例缩小,最小 50.00%;向上调节时放大,最大 100.00%。


2.8 QTimeEdit / QDateEdit / QDateTimeEdit

控件简介

三者放在同一个例程中讲解:

  • QDateTimeEdit 用于编辑日期和时间,允许用键盘或方向键增减各部分的值。
  • QTimeEdit 继承 QDateTimeEdit,专门编辑时间。
  • QDateEdit 继承 QDateTimeEdit,专门编辑日期。

常用属性与信号

成员 说明
QDateTimeEdit(const QDateTime&, QWidget*) 以日期时间构造
QTimeEdit(const QTime&, QWidget*) 以时间构造
QDateEdit(const QDate&, QWidget*) 以日期构造
setCalendarPopup(bool) 是否弹出日历选择
dateTime() / time() / date() 读取值
dateTimeChanged(QDateTime) / timeChanged(QTime) / dateChanged(QDate) 值变化信号

用法示例

例 17_qdatetimeedit 时间日期展示:同时展示三种日期时间控件。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDateTimeEdit>
#include <QTimeEdit>
#include <QDateEdit>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明对象 */
    QDateTimeEdit *dateTimeEdit;
    QTimeEdit *timeEdit;
    QDateEdit *dateEdit;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化对象,传入当前日期与时间 */
    dateTimeEdit = new QDateTimeEdit(
                QDateTime::currentDateTime(),this);
    dateTimeEdit->setGeometry(300, 200, 200, 30);
    /* 弹出日期控件与否 */
    //dateTimeEdit->setCalendarPopup(true);

    /* 实例化对象,传入当前时间 */
    timeEdit = new QTimeEdit(QTime::currentTime(),this);
    timeEdit->setGeometry(300, 240, 200, 30);

    /* 实例化对象,传入当前日期 */
    dateEdit = new QDateEdit(QDate::currentDate(),this);
    dateEdit->setGeometry(300, 280, 200, 30);
}

MainWindow::~MainWindow()
{
}

运行效果说明

程序启动后三个控件分别显示系统当前日期时间、时间和日期。Windows 与 Linux 的日期显示格式可能不同。


2.9 QDial

控件简介

QDial 继承 QAbstractSlider,提供圆形范围控制(类似速度计或电位器)。适合在环形范围(如 0~359 度)内取值,或布局上需要正方形部件的场合。由于继承自 QAbstractSlider,行为与滑块类似,共享相同的信号、槽与成员函数。

常用属性与信号

成员 说明
setRange(int min, int max) 范围
setPageStep(int) 页长(两个最大刻度间距)
setNotchesVisible(bool) 刻度是否可见
setNotchTarget(double) 两个凹槽间的目标像素数
setWrapping(bool) 是否可指向整圈任意角度
valueChanged(int) 值变化信号

用法示例

例 18_qdial 车速表:拖动拨盘,标签显示“车速”。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QDial>
#include <QLabel>
#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明对象 */
    QDial *dial;
    QLabel *label;

private slots:
    /* 槽函数 */
    void dialValueChanged(int);

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置主窗体的位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化对象和设置显示位置与大小 */
    dial = new QDial(this);
    dial->setGeometry(300, 100, 200, 200);

    /* 设置页长(两个最大刻度的间距)*/
    dial->setPageStep(10);

    /* 设置刻度可见 */
    dial->setNotchesVisible(true);

    /* 设置两个凹槽之间的目标像素数 */
    dial->setNotchTarget(1.00);

    /* 设置dial值的范围 */
    dial->setRange(0,100);

    /* 开启后可指向圆的任何角度 */
    //dial->setWrapping(true);

    /* 实例化对象和设置显示位置与大小 */
    label = new QLabel(this);
    label->setGeometry(370, 300, 200, 50);

    /* 初始化为0km/h */
    label->setText("0km/h");

    /* 信号槽连接 */
    connect(dial, SIGNAL(valueChanged(int)),
            this, SLOT(dialValueChanged(int)));
}

MainWindow::~MainWindow()
{
}

void MainWindow::dialValueChanged(int val)
{
    /* QString::number()转换成字符串 */
    label->setText(QString::number(val) + "km/h");
}

运行效果说明

用鼠标拖动拨盘或用方向键增减,标签实时显示当前“车速”。音量控制、仪表盘等场景常用。


2.10 QScrollBar

控件简介

QScrollBar 继承 QAbstractSlider,提供垂直或水平滚动条,让用户访问比显示区域更大的文档。它提供当前位置和可见文档量的可视化指示。一般滚动条不单独使用,而是配合 QScrollArea,或由自带滚动条的控件(如 QListWidget)内部使用。

常用属性与信号

成员 说明
QScrollBar(Qt::Orientation, QWidget*) 构造:方向 + 父对象
setRange(int min, int max) 范围
setValue(int) / value() 当前值
setPageStep(int) 页步长
valueChanged(int) 值变化信号

用法示例

例 19_qscrollbar 创建水平和垂直滚动条

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QScrollBar>
#include <QLabel>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明水平滚动条对象 */
    QScrollBar *horizontalScrollBar;

    /* 声明垂直滚动条对象 */
    QScrollBar *verticalScrollBar;

    /* 声明标签文本 */
    QLabel *label;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置主窗体大小,位置 */
    this->setGeometry(0,0,800,480);

    /* 实例化水平滚动条及设置位置大小 */
    horizontalScrollBar = new QScrollBar(Qt::Horizontal, this);
    horizontalScrollBar->setGeometry(0, 450, 800, 30);

    /* 实例化垂直滚动条及设置位置大小 */
    verticalScrollBar = new QScrollBar(Qt::Vertical, this);
    verticalScrollBar->setGeometry(770, 0, 30, 480);

    /* 实例化,标签文本 */
    label = new QLabel(this);
    /* 设置文本 */
    label->setText("这是一个测试");
    /* 设置位置大小 */
    label->setGeometry(300, 200, 100, 20);
}

运行效果说明

窗口底部和右侧分别出现水平、垂直滚动条。本例只演示创建实例,不对滚动效果做细化。


2.11 QSlider

控件简介

QSlider 继承 QAbstractSlider,提供垂直或水平滑动条。用户沿凹槽移动滑块手柄,位置被转换为合法范围内的整数值。

常用属性与信号

成员 说明
QSlider(Qt::Orientation, QWidget*) 构造:方向 + 父对象
setRange(int min, int max) 范围
setValue(int) / value() 当前值
setSliderPosition(int) 设置滑块位置
valueChanged(int) 值变化信号
sliderMoved(int) 拖动时信号

用法示例

例 20_qslider 水平与垂直滑动条联动

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSlider>
#include <QLabel>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明对象 */
    QSlider *horizontalSlider;
    QSlider *verticalSlider;
    QLabel *label;
private slots:
    /* 槽函数 */
    void horizontalSliderValueChanged(int);
    void verticalSliderValueChanged(int);

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(0, 0, 800, 480);

    /* 实例化水平滑动条对象*/
    horizontalSlider = new QSlider(Qt::Horizontal, this);

    /* 设置显示的位置与大小 */
    horizontalSlider->setGeometry(250, 100, 200, 20);

    /* 设置值范围 */
    horizontalSlider->setRange(0, 100);

    /* 实例化垂直滑动条对象 */
    verticalSlider = new QSlider(Qt::Vertical, this);

    /* 设置显示的位置与大小 */
    verticalSlider->setGeometry(200, 50, 20, 200);

    /* 设置值范围 */
    verticalSlider->setRange(0, 100);

    /* 实例化标签文本 */
    label = new QLabel("滑动条值:0", this);
    label->setGeometry(250, 200, 100, 20);

    /* 信号槽连接 */
    connect(horizontalSlider, SIGNAL(valueChanged(int)),
            this, SLOT(horizontalSliderValueChanged(int)));
    connect(verticalSlider, SIGNAL(valueChanged(int)),
            this, SLOT(verticalSliderValueChanged(int)));

}

MainWindow::~MainWindow()
{
}

void MainWindow::horizontalSliderValueChanged(int val)
{
    /* 当水平滑动条的值改变时,改变垂直滑动条的值 */
    verticalSlider->setSliderPosition(val);

    /* 将int类型转变成字符 */
    QString str = "滑动条值:" + QString::number(val);

    /* 显示当前垂直或水平滑动条的值 */
    label->setText(str);

}

void MainWindow::verticalSliderValueChanged(int val)
{
    /* 当垂直滑动条的值改变时,改变水平滑动条的值 */
    horizontalSlider->setSliderPosition(val);
}

运行效果说明

拖动任一滑动条,另一个同步变化,标签显示当前值。


2.12 QKeySequenceEdit

控件简介

QKeySequenceEdit 继承 QWidget,允许用户录入 QKeySequence(通常用作快捷键)。当控件获得焦点、用户释放最后一个按键后约一秒结束记录,是录制快捷键的专用控件。

常用属性与信号

成员 说明
keySequence() / setKeySequence(QKeySequence) 读取/设置快捷键序列
keySequenceChanged(const QKeySequence &) 序列变化信号
clear() 清空

用法示例

例 21_qkeysequenceedit 自定义快捷键:录入 Ctrl+Q 则关闭窗口。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QKeySequenceEdit>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明QKeySequenceEdit对象 */
    QKeySequenceEdit  *keySequenceEdit;

private slots:
    /* 声明槽 */
    void KSEKeySequenceChanged(const QKeySequence &);

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 主窗体设置位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化 */
    keySequenceEdit = new QKeySequenceEdit(this);

    /* 设置位置与大小 */
    keySequenceEdit->setGeometry(350, 200, 150, 30);

    /* 信号槽连接 */
    connect(keySequenceEdit,
            SIGNAL(keySequenceChanged(const QKeySequence &)),
            this,
            SLOT(KSEKeySequenceChanged(const QKeySequence &))
            );

}

MainWindow::~MainWindow()
{
}

void MainWindow::KSEKeySequenceChanged(
        const QKeySequence &keySequence)
{
    /* 判断输入的组合键是否为Ctrl + Q,如果是则退出程序 */
    if(keySequence == QKeySequence(tr("Ctrl+Q"))) {
        /* 结束程序 */
        this->close();
    }else {
        /* 打印出按下的组合键 */
        qDebug()<<keySequence.toString()<<endl;
    }
}

运行效果说明

焦点在控件上时按下任意键或组合键,约一秒后控件记录并打印该组合键;按下 Ctrl+Q 时程序窗口关闭。


3. 显示窗口部件

Qt 显示部件面板提供 Label、Text Browser、Graphics View、Calendar Widget、LCD Number、Progress Bar、Horizontal/Vertical Line、OpenGL Widget、QQuick Widget 等。其中 Text Browser、Graphics View 在下一节“浏览器类”讲解。

3.1 QLabel

控件简介

QLabel 继承 QFrame,用于显示文本或图像。前面例子只用它显示文本,其实它也能显示图片。按钮、Widget、Label 都能显示图像,但按钮有按下、释放、悬停三种状态,不常用于单纯显示一张图。

常用属性与信号

成员 说明
setText(QString) 设置文本
setPixmap(QPixmap) 设置图像
setScaledContents(bool) 允许缩放填充
setAlignment(Qt::Alignment) 对齐方式
setFont(QFont) 字体

用法示例

例 22_qlbel 标签显示图像或文本:一个标签显示图片,一个标签显示文字。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 用一个QLabel对象用于显示字符串 */
    QLabel *labelString;

    /* 用一个QLabel对象用于显示图像 */
    QLabel *labelImage;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置大小与位置 */
    this->setGeometry(0, 0, 800, 480);

    /* 使用资源里的文件时格式是  :+前缀+文件路径  */
    QPixmap pixmap(":images/openedv.png");

    labelImage = new QLabel(this);

    /* 标签大小为452×132,根据图像的大小来设置 */
    labelImage->setGeometry(180, 150, 452, 132);
    /* 设置图像 */
    labelImage->setPixmap(pixmap);
    /* 开启允许缩放填充 */
    labelImage->setScaledContents(true);

    labelString = new QLabel(this);
    labelString->setText("标签演示文本");
    labelString->setGeometry(300, 300, 100, 20);
}

运行效果说明

窗口中央显示 openedv.png 图片,下方显示文字“标签演示文本”。标签大小按图片实际尺寸 452×132 设置,避免图片被拉伸变形。


3.2 QCalendarWidget

控件简介

QCalendarWidget 继承 QWidget,提供基于月的日历,允许用户选择日期。它用当前月份和年份初始化,并提供若干公共槽来切换显示的年份和月份。

常用属性与信号

成员 说明
selectedDate() 当前选中日期
setSelectedDate(QDate) 设置选中日期
selectionChanged() 选择变化信号
setFont(QFont) 设置字体
setGridVisible(bool) 是否显示网格

用法示例

例 23_qcalendarwidget 日历简单使用:选择日期并显示,按钮回到当前日期。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QCalendarWidget>
#include <QPushButton>
#include <QLabel>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明QCalendarWidget,QPushButton,QLabel对象 */
    QCalendarWidget *calendarWidget;
    QPushButton *pushButton;
    QLabel *label;

private slots:
    /* 槽函数 */
    void calendarWidgetSelectionChanged();
    void pushButtonClicked();

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置位置与大小,下同 */
    this->setGeometry(0, 0, 800, 480);

    /* 对象实例化设置显示的位置与大小 */
    calendarWidget = new QCalendarWidget(this);
    calendarWidget->setGeometry(200, 20, 400, 300);

    QFont font;
    /* 设置日历里字体的大小为10像素 */
    font.setPixelSize(10);
    calendarWidget->setFont(font);

    /* 回到当前日期按钮 */
    pushButton = new QPushButton("回到当前日期",this);
    pushButton->setGeometry(200, 350, 100, 30);

    /* 标签显示当前选择日期 */
    label = new QLabel(this);
    label->setGeometry(400, 350, 400, 30);
    QString str = "当前选择的日期:"
            + calendarWidget->selectedDate().toString();
    label->setText(str);

    /* 信号槽连接 */
    connect(calendarWidget, SIGNAL(selectionChanged()),
            this, SLOT(calendarWidgetSelectionChanged()));
    connect(pushButton, SIGNAL(clicked()),
            this, SLOT(pushButtonClicked()));
}

MainWindow::~MainWindow()
{
}

void MainWindow::calendarWidgetSelectionChanged()
{
    /* 当日历点击改变当前选择的日期时,更新Label的显示内容 */
    QString str = "当前选择的日期:"
            + calendarWidget->selectedDate().toString();
    label->setText(str);
}

void MainWindow::pushButtonClicked()
{
    /* 设置当前选定的日期为系统的QDate */
    calendarWidget->setSelectedDate(QDate::currentDate());
}

运行效果说明

点击日历改变日期,标签实时更新;点击“回到当前日期”,日历跳回系统当天并更新标签。


3.3 QLCDNumber

控件简介

QLCDNumber 继承 QFrame,显示类似 LCD 的数字,支持任意大小的数字以及十进制、十六进制、八进制、二进制。通过 display() 槽可方便地接入数据源,该槽被重载以接受五种参数类型。

常用属性与信号

成员 说明
setDigitCount(int) 显示位数
setSegmentStyle(QLCDNumber::SegmentStyle) 段样式(FlatOutlineFilled
display(...) 显示数字或字符串(重载槽)
setMode(QLCDNumber::Mode) 进制(Dec/Hex/Oct/Bin
overflow() 溢出信号

用法示例

例 24_qlcdnumber LCDNumber 时钟:定时器每秒刷新系统时间。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLCDNumber>
#include <QTimer>
#include <QTime>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明QLCDNumber对象 */
    QLCDNumber *lcdNumber;

    /* 声明QTimer对象 */
    QTimer *timer;

private slots:
    /* 槽函数 */
    void timerTimeOut();

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置主窗体的大小与位置 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化与设置显示的位置大小*/
    lcdNumber = new QLCDNumber(this);
    lcdNumber->setGeometry(300, 200, 200, 50);

    /* 设置显示的位数8位 */
    lcdNumber->setDigitCount(8);
    /* 设置样式 */
    lcdNumber->setSegmentStyle(QLCDNumber::Flat);

    /* 设置lcd显示为当前系统时间 */
    QTime time = QTime::currentTime();

    /* 设置显示的样式 */
    lcdNumber->display(time.toString("hh:mm:ss"));

    timer = new QTimer(this);
    /* 设置定时器1000毫秒发送一个timeout()信号 */
    timer->start(1000);

    /* 信号槽连接 */
    connect(timer, SIGNAL(timeout()), this,
            SLOT(timerTimeOut()));

}

MainWindow::~MainWindow()
{
}

void MainWindow::timerTimeOut()
{
    /* 当定时器计时1000毫秒后,刷新lcd显示当前系统时间 */
    QTime time = QTime::currentTime();
    /* 设置显示的样式 */
    lcdNumber->display(time.toString("hh:mm:ss"));
}

运行效果说明

程序启动后 LCD 显示当前系统时间,并每秒刷新,像数字时钟一样运行。


3.4 QProgressBar

控件简介

QProgressBar 继承 QWidget,提供水平或垂直进度条,用于显示操作进度并确认程序仍在运行。常用于复制进度、加载进度等。

常用属性与信号

成员 说明
setRange(int min, int max) 范围
setValue(int) / value() 当前值
setFormat(QString) 文本格式,%p% 表示百分比
setOrientation(Qt::Orientation) 方向
setTextVisible(bool) 是否显示文本
valueChanged(int) 值变化信号

用法示例

例 25_qprogressbar 手机电池充电:定时器驱动进度条循环充电。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QProgressBar>
#include <QTimer>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明对象 */
    QProgressBar *progressBar;
    QTimer *timer;

    /* 用于设置当前QProgressBar的值 */
    int value;

private slots:
    /* 槽函数 */
    void timerTimeOut();

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置主窗体位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    progressBar = new QProgressBar(this);
    progressBar->setGeometry(300, 200, 200, 60);

    /* 样式表设置,常用setStyleSheet来设置样式(实现界面美化的功能) */
    progressBar->setStyleSheet (
                "QProgressBar{border:8px solid #FFFFFF;"
                "height:30;"
                "border-image:url(:/images/battery.png);" //背景图片
                "text-align:center;"    // 文字居中
                "color:rgb(255,0,255);"
                "font:20px;"      // 字体大小为20px
                "border-radius:10px;}"
                "QProgressBar::chunk{"
                "border-radius:5px;" // 斑马线圆角
                "border:1px solid black;" // 黑边,默认无边
                "background-color:skyblue;"
                "width:10px;margin:1px;}" // 宽度和间距
                );

    /* 设置progressBar的范围值 */
    progressBar->setRange(0, 100);
    /* 初始化value为0 */
    value = 0;
    /* 给progressBar设置当前值 */
    progressBar->setValue(value);
    /* 设置当前文本字符串的显示格式 */
    progressBar->setFormat("充电中%p%");

    /* 定时器实例化设置每100ms发送一个timeout信号 */
    timer = new QTimer(this);
    timer->start(100);

    /* 信号槽连接 */
    connect(timer, SIGNAL(timeout()),
            this, SLOT(timerTimeOut()));
}

MainWindow::~MainWindow()
{
}

void MainWindow::timerTimeOut()
{
    /* 定时器时间到,value值自加一 */
    value ++;
    progressBar->setValue(value);
    /* 若value值大于100,令value再回到0 */
    if(value>100)
        value = 0;
}

运行效果说明

进度条以电池图片为底,每 100ms 前进一格,从 0% 充到 100% 后回到 0% 重新开始。


3.5 QFrame

控件简介

QFrame 继承 QWidget,是所有带框架窗口部件的基类。它绘制框架并调用虚函数 drawContents() 填充框架,子类可重写该函数。QPopupMenu 用它把菜单“升高”,QProgressBar 有“凹陷”外观,QLabel 有平坦外观。

QFrame::Shape 定义框架外形:

取值 效果
NoFrame 不画任何东西
Box 在内容周围画一个框
Panel 画一个平板,内容看起来凸起或凹陷
WinPanel 类似 Panel,但三维效果与 Windows 95 一致
ToolBarPanel 调用 QStyle::drawToolBarPanel()
MenuBarPanel 调用 QStyle::drawMenuBarPanel()
HLine 画水平线,用于分隔
VLine 画竖直线,用于分隔
StyledPanel 调用 QStyle::drawPanel()
PopupPanel 调用 QStyle::drawPopupPanel()

阴影风格(QFrame::Shadow):Plain(无三维效果)、Raised(凸起)、Sunken(凹陷)。

常用的还有 drawFrame()frameChanged() 两个函数。

常用属性与信号

成员 说明
setFrameShape(QFrame::Shape) 框架外形
setFrameShadow(QFrame::Shadow) 阴影风格
frameRect() 框架矩形
setFrameStyle(int) 同时设置外形与阴影

用法示例

例 26_qframe 水平/垂直线:两条 QFrame 分别画水平线和垂直线。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFrame>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 声明对象 */
    QFrame *hline;
    QFrame *vline;

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置主窗体的显示位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化 */
    hline = new QFrame(this);
    /* 确定起始点,设置长和宽,绘制矩形 */
    hline->setGeometry(QRect(200, 100, 400, 40));

    /* 设置框架样式为HLine,水平。由于是HLine,只显示一条水平直线 */
    hline->setFrameShape(QFrame::HLine);
    /* 绘制阴影 */
    hline->setFrameShadow(QFrame::Sunken);

    /* 实例化 */
    vline = new QFrame(this);
    /* 确定起始点,设置长和宽,绘制矩形 */
    vline->setGeometry(QRect(300, 100, 2, 200));

    /* 设置框架样式为VLine,垂直。由于是VLine,只显示一条垂直直线 */
    vline->setFrameShape(QFrame::VLine);
    /* 绘制阴影 */
    vline->setFrameShadow(QFrame::Sunken);
}

MainWindow::~MainWindow()
{
}

Display Widgets 里的 Horizontal Line / Vertical Line 就是 QFrame 封装好的控件,也可以用本例的方式自行实现。

运行效果说明

窗口中央出现一条水平直线和一条垂直直线。QFrame 常用于绘制边框美化界面,QLabel 等控件也能设置独特的边框样式。


4. 显示窗口部件之浏览器

本节包含两个“浏览器”类控件:QTextBrowser(文本)与 QGraphicsView(图形)。两者都需要在项目里勾选 mainwindow.ui,以便使用自带的菜单栏、工具栏与状态栏。

4.1 QTextBrowser

控件简介

QTextBrowser 继承 QTextEdit,在只读 QTextEdit 的基础上增加了超文本导航功能,用户可以跟踪超文本文档中的链接。适合做一个能打开 txt、html 等文件的文本浏览器。

常用属性与信号

成员 说明
setPlainText(QString) 按纯文本设置内容
setHtml(QString) 按 HTML 设置内容
setSource(QUrl) 加载指定 URL
backward() / forward() / home() 后退/前进/主页
anchorClicked(QUrl) 链接被点击信号
setOpenExternalLinks(bool) 是否用外部浏览器打开链接

用法示例

例 27_qtextbrowser 简单的文本浏览器:通过菜单栏“打开”动作加载文件,按后缀选择 HTML 或纯文本显示。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTextBrowser>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    /* 声明对象 */
    QTextBrowser *textBrowser;
    QAction *openAction;

private slots:
    /* 槽函数 */
    void openActionTriggered();
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
/* 窗口对话框与文本流 */
#include <QFileDialog>
#include <QTextStream>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    /* 设置主窗体位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 将窗口标题设置为文本浏览器 */
    this->setWindowTitle("文本浏览器");

    /* 实例化 */
    textBrowser = new QTextBrowser(this);
    /* 将文本浏览器窗口居中 */
    this->setCentralWidget(textBrowser);

    /* 实例化打开动作 */
    openAction = new QAction("打开",this);
    /* ui窗口自带有menubar(菜单栏)、mainToolbar(工具栏)与statusbar(状态栏)
     * menuBar是ui生成工程就有的,可以在menubar里添加我们的QAction等 */
    /* 将动作添加到菜单栏 */
    ui->menubar->addAction(openAction);

    /* 信号槽连接 */
    connect(openAction, SIGNAL(triggered()),
            this, SLOT(openActionTriggered()));

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::openActionTriggered()
{
    /* 调用系统打开文件窗口,过滤文件名 */
    QString fileName = QFileDialog::getOpenFileName(
                this,tr("打开文件"),"",
                tr("Files(*.txt *.cpp *.h *.html *.htm)")
                );
    QFile myFile(fileName);
    /* 以只读、文本方式打开,若打开失败,则返回 */
    if(!myFile.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    /* 用QTextStream对象接收 */
    QTextStream in (&myFile);

    /* 读取全部数据 */
    QString myText = in.readAll();

    /* 判断打开文件的后缀,如果是html格式的则设置文本浏览器为html格式 */
    if(fileName.endsWith("html") || fileName.endsWith("htm")){
        textBrowser->setHtml(myText);
    } else {
        textBrowser->setPlainText(myText);
    }

    /* ui窗口自带有statusbar(状态栏),设置打开的文件名 */
    ui->statusbar->showMessage("文件名:" + fileName);
}

运行效果说明

菜单栏点击“打开”,在系统文件对话框中选择 mainwindow.cpp,内容显示在文本浏览器中,状态栏显示文件名。可自行扩展关闭、字体颜色、缩放等功能。(Ubuntu16 的 Qt 可能看不到菜单栏,Ubuntu18 正常。)


4.2 QGraphicsView

控件简介

QGraphicsView 继承 QAbstractScrollArea,是图形视图框架的一部分,提供基于图元的模型/视图编程。它在可滚动视图中可视化 QGraphicsScene 的内容。

要可视化场景,先构造一个 QGraphicsView 对象,把要可视化的场景地址传给它的构造函数;也可以稍后调用 setScene() 设置。

常用属性与信号

成员 说明
setScene(QGraphicsScene*) 设置场景
scene() 取得场景
QGraphicsScene::addPixmap(QPixmap) 向场景添加图元
QGraphicsScene::clear() 清空场景
QPixmap::scaled(w, h, aspectMode, transformMode) 缩放图像
setRenderHint(...) 渲染质量提示

用法示例

例 28_qgraphicsview 简单的图像浏览器:通过菜单打开图片,缩放后加入场景显示。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsView>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    /* 声明对象 */
    QGraphicsView *graphicsView;
    QGraphicsScene *graphicsScene;
    QAction *openAction;

private slots:
    /* 槽函数 */
    void openActionTriggered();

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    /* 设置主窗体大小 */
    this->setGeometry(0, 0, 800, 480);
    /* 将窗口标题设置为图像浏览器 */
    this->setWindowTitle("图像浏览器");

    /* 实例化图形视图对象 */
    graphicsView = new QGraphicsView(this);
    /* 将图像浏览器窗口居中 */
    this->setCentralWidget(graphicsView);

    /* 实例化场景对象 */
    graphicsScene = new QGraphicsScene(this);

    /* 在QGraphicsView设置场景 */
    graphicsView->setScene(graphicsScene);

    /* 将动作添加到菜单栏 */
    openAction = new QAction("打开",this);
    ui->menubar->addAction(openAction);

    /* 信号槽连接 */
    connect(openAction, SIGNAL(triggered()),
            this, SLOT(openActionTriggered()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::openActionTriggered()
{
    /* 调用系统打开文件窗口,设置窗口标题为“打开文件”,过滤文件名 */
    QString fileName = QFileDialog::getOpenFileName(
                this,tr("打开文件"), "",
                tr("Files(*.png *.jpg *.bmp)")
                );
    /* 定义QPixmap对象,指向fileName */
    QPixmap image(fileName);

    /* 假若用户没选择文件,则返回 */
    if(image.isNull())
        return;
    /* 把image缩放为graphicsView的长宽,保持纵横比,使用快速变换 */
    image = image.scaled(graphicsView->width(),
                          graphicsView->height(),
                          Qt::KeepAspectRatio,
                          Qt::FastTransformation
                          );
    /* 在添加场景内容前,先清除之前的场景内容 */
    graphicsScene->clear();
    /* 添加场景内容image */
    graphicsScene->addPixmap(image);
    /* ui窗口自带有statusBar(状态栏),设置打开的文件名 */
    ui->statusbar->showMessage("文件名:" + fileName);
}

运行效果说明

菜单栏点击“打开”,选择一张图片,图片按视口大小等比缩放后显示在窗口中,状态栏显示文件名。


5. 总结

5.1 按用途记忆

mindmap
  root((Qt控件<br/>7.1-7.4))
    按钮
      QPushButton 命令
      QToolButton 工具栏图标
      QRadioButton 多选一
      QCheckBox 多选多/三态
      QCommandLinkButton 链接
      QDialogButtonBox 对话框按钮
    输入
      QComboBox 下拉
      QFontComboBox 字体
      QLineEdit 单行
      QTextEdit 富文本
      QPlainTextEdit 纯文本
      QSpinBox 整数
      QDoubleSpinBox 浮点
      QDateTimeEdit 日期时间
      QDial 拨盘
      QScrollBar 滚动条
      QSlider 滑动条
      QKeySequenceEdit 快捷键
    显示
      QLabel 文本/图像
      QCalendarWidget 日历
      QLCDNumber 数字
      QProgressBar 进度
      QFrame 边框/分隔线
    浏览器
      QTextBrowser 超文本
      QGraphicsView 图形场景

5.2 关键规律

规律 说明
位置与大小 所有 QWidget 子类都可用 setGeometry(x, y, w, h)
信号槽写法 例程统一使用 connect(obj, SIGNAL(...), this, SLOT(...))
容器 QWidget 可作容器;setCentralWidget() 把控件设为主窗口中央部件
布局 例程大量使用 setGeometry 绝对定位,下一篇将学习布局管理器
样式表 setStyleSheet() 可实现换肤、充电条、开关等美化效果
资源路径 引用 qrc 资源格式为 :/前缀/文件路径,如 :/images/battery.png

6. 构建运行步骤

  1. 新建项目:Qt Creator → FileNew File or ProjectApplication (Qt)Qt Widgets Application;项目名如 04_qpushbutton;基类选 QMainWindow不勾选 “Generate form”(例程用纯代码,不用 .ui)。
  2. 替换源码:把 mainwindow.hmainwindow.cpp 替换为本节代码;main.cpp 若无特别说明保持新建时的默认内容。
  3. 添加资源(涉及 qss/图片的例程):参照 1.3 节步骤添加 .qrc、图片,并创建 style.qss
  4. 检查 .pro 文件:Qt Widgets 项目默认包含:

    QT       += core gui
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    CONFIG += c++11
    SOURCES += main.cpp mainwindow.cpp
    HEADERS += mainwindow.h
    
  5. 编译运行Ctrl+R(构建并运行)或 Ctrl+B(仅构建)。

  6. 交叉编译到开发板:参照《I.MX6U嵌入式Qt开发指南》第十四章配置交叉编译环境,将可执行文件拷贝到板子后运行(需带 Qt 库与字体)。


7. 面试题

Q1:QPushButtonQRadioButtonQCheckBox 的共同基类是什么?它们的选择模式有何区别?

共同基类是 QAbstractButtonQPushButton 用于执行命令/触发事件,一般不可切换;QRadioButton 单选,同组内“多选一”;QCheckBox 复选,允许多选多,并可通过 setTristate() 开启半选状态。

Q2:QTextEditQPlainTextEdit 有什么区别?什么时候用哪个?

QTextEdit 支持富文本(HTML 样式、图片、列表、表格),功能强;QPlainTextEdit 只支持纯文本,可理解为前者的低配版。处理大量文字、频繁滚动时,QPlainTextEdit 的显示效率更高,应优先使用。

Q3:QComboBoxQFontComboBox 的关系是什么?如何取得当前选项的文本?

QFontComboBox 继承 QComboBox,是一个专门填充系统字体家族的下拉框,其字体变化信号为 currentFontChanged(QFont)QComboBox 中可用 itemText(currentIndex()) 取得当前选项文本,或直接用 currentText()

Q4:QSpinBoxQDoubleSpinBox 都可以用 valueChanged 信号,为什么它们的槽函数参数类型不同?

因为两者处理的数据类型不同:QSpinBox 处理整数,信号是 valueChanged(int)QDoubleSpinBox 处理浮点值,信号是 valueChanged(double)。连接时槽函数参数类型必须与信号一致。

Q5:为什么用 QTextEdit::selectAll() 全选前要先 setFocus()QTextBrowserQTextEdit 又是什么关系?

selectAll() 作用于当前有焦点的编辑区域,如果控件没有焦点,选中可能不生效,因此例程先调用 setFocus()QTextBrowser 继承 QTextEdit,在只读模式下扩展了超文本导航(链接跳转、前进/后退),用于显示带链接的文档。


内容来源:《【正点原子】I.MX6U嵌入式Qt开发指南V1.2》第七章 Qt控件 7.1 按钮、7.2 输入窗口部件、7.3 显示窗口部件、7.4 显示窗口部件之浏览器;配套例程 Embedded-Qt-Tutorial/Qt/01/04_qpushbutton ~ 28_qgraphicsview