
在 Qt GUI 开发中,显示类控件不仅要承担信息展示的基础职责,还需满足动态反馈与交互选择的核心需求。ProgressBar(进度条)以直观的可视化方式呈现任务进度,是文件上传、数据加载等场景的必备控件;CalendarWidget(日历控件)则为日期选择提供了标准化界面,广泛应用于日程管理、数据筛选等功能中。本文将基于 Qt 5.14 版本,从核心属性、实战案例到进阶技巧,全面拆解这两个控件的使用方法,带你解锁显示类控件的高级玩法!下面就让我们正式开始吧!
QProgressBar 是 Qt 中用于展示任务进度的核心控件,它通过填充的进度条直观反映任务完成比例,支持自定义进度样式、显示格式和方向,能极大提升用户对长时间任务的感知体验。无论是简单的倒计时进度,还是复杂的文件传输进度展示,ProgressBar 都能轻松胜任。
ProgressBar 的属性围绕进度展示和外观样式展开,以下是最常用的核心属性,结合实用场景帮你快速理解:
属性名 | 功能说明 | 取值 / 类型 | 实用场景 |
|---|---|---|---|
minimum | 进度条最小值 | int(默认 0) | 任务起始点(如文件下载从 0 开始) |
maximum | 进度条最大值 | int(默认 100) | 任务终点(如 100% 完成) |
value | 进度条当前值 | int(默认 0) | 实时更新任务进度 |
alignment | 进度文本对齐方式 | Qt::AlignLeft/AlignCenter/AlignRight 等 | 优化进度文本显示位置 |
textVisible | 是否显示进度文本 | bool(默认 true) | 简洁界面可隐藏文本 |
orientation | 进度条方向 | Qt::Horizontal(水平,默认)/Qt::Vertical(垂直) | 水平适用于顶部 / 底部进度,垂直适用于侧边栏 |
invertAppearance | 是否反向增长 | bool(默认 false) | 特殊场景下进度从右向左 / 从下向上增长 |
textDirection | 进度文本方向 | Qt::LeftToRight/Qt::RightToLeft | 适配不同语言排版需求 |
format | 进度文本格式 | 字符串(支持 % p/% v/% m/% t 占位符) | 自定义进度显示(如 “50%”“已完成 50/100”) |
其中,format属性的占位符功能非常实用,四个核心占位符的含义如下:
%p:显示百分比(0-100),如 “50%”;%v:显示当前进度值,如 “50”;%m:显示剩余时间(毫秒级,需结合定时器计算);%t:显示总时间(毫秒级,需结合定时器计算)。 ProgressBar 的基础用法非常简洁,通过设置minimum、maximum和value三个核心属性,即可实现进度展示。以下是两种常见的基础场景示例:
适用于展示已知进度的场景(如操作完成度提示):
#include "widget.h"
#include <QProgressBar>
#include <QLabel>
#include <QVBoxLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("ProgressBar基础用法");
// 创建布局管理器(用于控件排版)
QVBoxLayout *layout = new QVBoxLayout(this);
// 创建提示标签
QLabel *tipLabel = new QLabel("任务完成进度:", this);
layout->addWidget(tipLabel);
// 创建进度条
QProgressBar *staticProgress = new QProgressBar(this);
staticProgress->setMinimum(0); // 最小值0
staticProgress->setMaximum(100); // 最大值100
staticProgress->setValue(68); // 当前进度68%
staticProgress->setAlignment(Qt::AlignCenter); // 文本居中
staticProgress->setFormat("已完成 %p%"); // 显示格式:已完成 68%
layout->addWidget(staticProgress);
// 添加垂直间距,优化界面
layout->addSpacing(20);
// 创建垂直进度条(演示方向属性)
QLabel *verticalTip = new QLabel("垂直进度条演示:", this);
layout->addWidget(verticalTip);
QProgressBar *verticalProgress = new QProgressBar(this);
verticalProgress->setOrientation(Qt::Vertical); // 垂直方向
verticalProgress->setMinimum(0);
verticalProgress->setMaximum(50);
verticalProgress->setValue(35);
verticalProgress->setFormat("%v/%m"); // 显示格式:35/50
verticalProgress->setFixedHeight(150); // 固定高度,便于展示
layout->addWidget(verticalProgress, 0, Qt::AlignCenter); // 居中对齐
}运行程序后,可看到水平进度条显示 “已完成 68%”,垂直进度条显示 “35/50”,能直观展示不同方向和格式的进度效果。
适用于展示实时变化的进度(如文件下载、数据加载),结合 Qt 的 QTimer 控件可实现进度自动增长。
先在.ui文件中拖入ProgressBar控件:


编辑代码:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &Widget::handle);
//启动定时器
timer->start(100);
}
Widget::~Widget()
{
delete ui;
}
void Widget::handle()
{
//获取进度条的当前数值
int value = ui->progressBar->value();
if(value >= 100)
{
//进度条满了,就可以停止定时器了
timer->stop();
return;
}
ui->progressBar->setValue(value + 1);
}运行程序后,进度条会从 0% 自动增长到 100%,进度文本实时显示 “XX%”,完成后提示 “下100%”,完美模拟了进度反馈。

默认的 ProgressBar 样式较为朴素,通过 Qt Style Sheet(QSS)可自定义进度条的颜色、边框、圆角等样式,让界面更具设计感。我们可以通过QSS设置进度条的颜色为红色。
首先我们在空间的属性界面找到Style Sheet选项:

点击右侧的“...”进入QSS编辑页面,并输入如下的代码:


点击“OK”后运行程序,可以观察到进度条变为了红色:

当然,我们也可以通过类似的代码设置进度条为其他更加复杂的样式,大家可以在日后使用Qt时自行摸索。
在使用 ProgressBar 的过程中,容易遇到一些细节问题,这里总结了高频问题及解决方案:
alignment属性设置不当;alignment为Qt::AlignCenter(默认居中,最稳妥);QProgressBar::text选择器自定义文本颜色、字体大小。invertAppearance属性仅控制进度增长方向,不改变文本方向;textDirection属性为Qt::RightToLeft。%p占位符会自动根据(value - minimum)/(maximum - minimum)计算百分比,与最大值是否为 100 无关;minimum=0、maximum=200、value=100,则%p显示 50%,无需手动计算。QCalendarWidget 是 Qt 提供的日历控件,支持日期选择、月份 / 年份切换、日期范围限制等功能,无需手动绘制日历界面,可直接集成到项目中,大幅提升开发效率。无论是简单的日期选择框,还是复杂的日程管理界面,CalendarWidget 都能满足需求。
CalendarWidget 的属性围绕日期展示和交互功能展开,以下是核心属性及实用场景:
属性名 | 功能说明 | 取值 / 类型 | 实用场景 |
|---|---|---|---|
selectedDate | 当前选中的日期 | QDate 类型 | 获取用户选择的日期 |
minimumDate | 可选择的最小日期 | QDate 类型 | 限制日期范围(如只能选择今天之后的日期) |
maximumDate | 可选择的最大日期 | QDate 类型 | 限制日期范围(如只能选择近 30 天的日期) |
firstDayOfWeek | 每周第一天 | Qt::Monday/Qt::Sunday 等 | 适配不同地区习惯(如国内周一为一周第一天) |
gridVisible | 是否显示表格边框 | bool(默认 true) | 简洁界面可隐藏边框 |
selectionMode | 日期选择模式 | QAbstractItemView::SingleSelection(默认,单选)等 | 仅支持单选日期(默认不支持多选) |
navigationBarVisible | 是否显示导航栏 | bool(默认 true) | 隐藏导航栏可固定显示某个月份 |
horizontalHeaderFormat | 水平表头格式 | QCalendarWidget::ShortDayNames(短名称,如 “一”)等 | 控制星期几的显示格式 |
verticalHeaderFormat | 垂直表头格式 | QCalendarWidget::NoVerticalHeader(隐藏)等 | 控制日期左侧的行号显示 |
dateEditEnabled | 是否允许编辑日期 | bool(默认 true) | 禁止编辑可防止用户输入非法日期 |
CalendarWidget 的信号主要用于响应日期选择和月份 / 年份切换,以下是最常用的信号:
信号名 | 触发时机 | 参数说明 | 实用场景 |
|---|---|---|---|
selectionChanged() | 选中的日期发生改变时 | 无参数(通过 selectedDate () 获取日期) | 实时获取用户选择的日期 |
activated(const QDate& date) | 双击日期或按下回车键时 | date:选中的日期 | 快速确认选择的日期 |
currentPageChanged(int year, int month) | 切换月份 / 年份时 | year:新年份;month:新月份 | 同步更新月份 / 年份显示标签 |
我们先在.ui文件中拖入“Calendar Widget”控件和一个label标签,用于显示选中的日期:


CalendarWidget 的基础用法只需几行代码,即可实现日期选择和展示。以下示例实现了 “选择日期后,在标签中显示选中日期” 的核心功能:
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_calendarWidget_selectionChanged()
{
QDate date = ui->calendarWidget->selectedDate();
qDebug() << date;
ui->label->setText(date.toString());
}运行程序后,选择日历中的任意日期,上方标签会实时显示 ,并且在控制台中也会打印出QDate对象的调试信息,能够直观展示日期选择和格式化功能。

minimumDate和maximumDate仅限制日期选择,不限制导航栏切换;currentPageChanged信号,当切换到超出范围的月份时,自动切换回最近的合法月份:connect(calendar, &QCalendarWidget::currentPageChanged, this, [=](int year, int month) {
QDate currentMonthFirstDay(year, month, 1);
QDate minDate = calendar->minimumDate();
QDate maxDate = calendar->maximumDate();
// 如果当前月份小于最小日期的月份,切换到最小日期的月份
if (currentMonthFirstDay < minDate) {
calendar->setCurrentPage(minDate.year(), minDate.month());
}
// 如果当前月份大于最大日期的月份,切换到最大日期的月份
else if (currentMonthFirstDay > maxDate) {
calendar->setCurrentPage(maxDate.year(), maxDate.month());
}
});qt_calendar_today);paintCell时未先调用QCalendarWidget::paintCell,覆盖了默认样式;paintCell时,先调用父类方法绘制默认样式,再绘制自定义内容。QDate::toString的格式符使用不当,默认根据系统 locale 显示;// 方式1:使用中文格式符(dddd显示中文星期)
QString dateStr = selected.toString("yyyy年MM月dd日 dddd");
// 方式2:设置locale为中文
calendar->setLocale(QLocale::Chinese);显示类控件是 Qt 界面开发的重要组成部分,掌握 ProgressBar 和 CalendarWidget 的使用后,可进一步学习 Chart 控件(数据可视化)、OpenGL 控件(3D 图形显示)等高级显示控件,构建更专业、更具交互性的 Qt 应用。 如果本文对你有帮助,欢迎点赞、收藏、转发,如有疑问或建议,欢迎在评论区留言交流~ 后续将推出 Qt 控件系列其他文章,敬请期待!