12人参与 • 2026-08-06 • C/C++

工程使用qmake编译
qt += widgets printsupport
config += c++17
# you can make your code fail to compile if it uses deprecated apis.
# in order to do so, uncomment the following line.
#defines += qt_disable_deprecated_before=0x060000 # disables all the apis deprecated before qt 6.0.0
sources += \
main.cpp \
mainwindow.cpp
headers += \
mainwindow.h
forms += \
mainwindow.ui
win32 {
libs += -luser32 -lole32
}
# default rules for deployment.
qnx: target.path = /tmp/$${target}/bin
else: unix:!android: target.path = /opt/$${target}/bin
!isempty(target.path): installs += target
resources += \
resources.qrc

#ifndef mainwindow_h
#define mainwindow_h
#include <qmainwindow>
#include <qtimer>
#ifdef q_os_win
#define initguid
#include <windows.h>
#include <shobjidl.h>
#endif
class mainwindow : public qmainwindow
{
q_object
public:
explicit mainwindow(qwidget *parent = nullptr);
~mainwindow() override;
private slots:
void ontimertick();
private:
void inittaskbar();
void releasetaskbar();
void settaskbarprogress(qint64 completed, qint64 total, tbpflag state = tbpf_normal);
void cleartaskbarprogress();
qtimer m_timer;
int m_progressvalue = 0;
#ifdef q_os_win
itaskbarlist3* m_taskbarinterface = nullptr;
hwnd m_hwnd = nullptr;
#endif
};
#endif // mainwindow_h
#include "mainwindow.h"
#include <qdebug>
mainwindow::mainwindow(qwidget *parent)
: qmainwindow(parent)
{
setwindowtitle("qt6 任务栏进度演示");
resize(600, 400);
#ifdef q_os_win
m_hwnd = reinterpret_cast<hwnd>(winid());
inittaskbar();
#endif
connect(&m_timer, &qtimer::timeout, this, &mainwindow::ontimertick);
m_timer.start(30);
}
mainwindow::~mainwindow()
{
#ifdef q_os_win
cleartaskbarprogress();
releasetaskbar();
#endif
}
void mainwindow::inittaskbar()
{
#ifdef q_os_win
hresult hr = coinitializeex(null, coinit_apartmentthreaded);
if (failed(hr))
{
qwarning() << "com初始化失败";
return;
}
hr = cocreateinstance(
clsid_taskbarlist,
nullptr,
clsctx_all,
iid_itaskbarlist3,
reinterpret_cast<void**>(&m_taskbarinterface)
);
if (failed(hr) || m_taskbarinterface == nullptr)
{
qwarning() << "创建任务栏接口失败";
couninitialize();
return;
}
m_taskbarinterface->hrinit();
#endif
}
void mainwindow::releasetaskbar()
{
#ifdef q_os_win
if (m_taskbarinterface)
{
m_taskbarinterface->release();
m_taskbarinterface = nullptr;
}
couninitialize();
#endif
}
// 修复参数类型 tbpflag
void mainwindow::settaskbarprogress(qint64 completed, qint64 total, tbpflag state)
{
#ifdef q_os_win
if (!m_taskbarinterface || m_hwnd == nullptr)
return;
m_taskbarinterface->setprogressvalue(m_hwnd, ulonglong(completed), ulonglong(total));
// 现在state是原生tbpflag枚举,无类型转换报错
m_taskbarinterface->setprogressstate(m_hwnd, state);
#endif
}
void mainwindow::cleartaskbarprogress()
{
#ifdef q_os_win
if (m_taskbarinterface && m_hwnd)
{
m_taskbarinterface->setprogressstate(m_hwnd, tbpf_noprogress);
}
#endif
}
void mainwindow::ontimertick()
{
m_progressvalue++;
if (m_progressvalue > 100)
{
m_progressvalue = 0;
cleartaskbarprogress();
}
#ifdef q_os_win
tbpflag progressstate = tbpf_normal;
if (m_progressvalue < 25)
{
progressstate = tbpf_normal; // 绿色
}
else if (m_progressvalue < 50)
{
progressstate = tbpf_paused; // 黄色暂停
}
else if (m_progressvalue < 75)
{
progressstate = tbpf_error; // 红色错误
}
else if (m_progressvalue < 90)
{
// 无限转圈
settaskbarprogress(0, 0, tbpf_indeterminate);
return;
}
else
{
progressstate = tbpf_normal;
}
settaskbarprogress(m_progressvalue, 100, progressstate);
#endif
}
#include <qapplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
qapplication a(argc, argv);
// windows 高dpi适配(可选推荐)
#if defined(q_os_win)
qapplication::sethighdpiscalefactorroundingpolicy(qt::highdpiscalefactorroundingpolicy::passthrough);
#endif
mainwindow w;
w.show();
return a.exec();
}
windows 任务栏进度条功能是通过 windows 7 引入的 itaskbarlist3 com 接口实现的。该接口提供了丰富的任务栏交互能力,包括:
qt 作为跨平台框架,需要通过平台特定的代码来调用这些 windows api。
// 主要进度相关方法 hresult setprogressstate(hwnd hwnd, tbpflag tbpflags); hresult setprogressvalue(hwnd hwnd, ulonglong ullcompleted, ulonglong ulltotal);
参数说明:
hwnd:窗口句柄,通过 qwidget::winid() 获取tbpflags:进度状态标志,控制进度条外观和行为ullcompleted:已完成的工作量ulltotal:总工作量typedef enum tbpflag {
tbpf_noprogress = 0x00000000, // 无进度条
tbpf_indeterminate = 0x00000001, // 不确定进度(转圈动画)
tbpf_normal = 0x00000002, // 绿色正常进度
tbpf_error = 0x00000004, // 红色错误状态
tbpf_paused = 0x00000008 // 黄色暂停状态
} tbpflag;
项目文件 (.pro) 配置:
win32 {
libs += -luser32 -lole32 # 链接 windows api 库
}
头文件包含:
#ifdef q_os_win #define initguid #include <windows.h> #include <shobjidl.h> // itaskbarlist3 接口定义 #endif
windows com 组件需要正确初始化和清理:
// 初始化 com(单线程公寓模式)
hresult hr = coinitializeex(null, coinit_apartmentthreaded);
if (failed(hr)) {
qwarning() << "com初始化失败";
return;
}
// 创建 itaskbarlist3 实例
hr = cocreateinstance(
clsid_taskbarlist,
nullptr,
clsctx_all,
iid_itaskbarlist3,
reinterpret_cast<void**>(&m_taskbarinterface)
);
// 清理资源
void releasetaskbar() {
if (m_taskbarinterface) {
m_taskbarinterface->release();
m_taskbarinterface = nullptr;
}
couninitialize();
}
设置进度值:
void settaskbarprogress(qint64 completed, qint64 total, tbpflag state = tbpf_normal) {
#ifdef q_os_win
if (!m_taskbarinterface || m_hwnd == nullptr)
return;
// 设置进度值(0-100)
m_taskbarinterface->setprogressvalue(m_hwnd,
ulonglong(completed),
ulonglong(total));
// 设置进度状态
m_taskbarinterface->setprogressstate(m_hwnd, state);
#endif
}
清除进度:
void cleartaskbarprogress() {
#ifdef q_os_win
if (m_taskbarinterface && m_hwnd) {
m_taskbarinterface->setprogressstate(m_hwnd, tbpf_noprogress);
}
#endif
}
// 模拟文件下载进度
void ondownloadprogress(qint64 bytesreceived, qint64 bytestotal) {
int percent = (bytestotal > 0) ?
(bytesreceived * 100 / bytestotal) : 0;
tbpflag state = tbpf_normal;
if (percent >= 100) {
state = tbpf_noprogress; // 下载完成
} else if (networkerror) {
state = tbpf_error; // 网络错误
}
settaskbarprogress(percent, 100, state);
}
// 媒体播放进度
void onmediapositionchanged(qint64 position, qint64 duration) {
int percent = (duration > 0) ?
(position * 100 / duration) : 0;
tbpflag state = tbpf_normal;
if (ispaused) {
state = tbpf_paused; // 暂停状态
} else if (isbuffering) {
state = tbpf_indeterminate; // 缓冲中
}
settaskbarprogress(percent, 100, state);
}
// 批量图片处理
void processimages(const qstringlist& imagepaths) {
int total = imagepaths.count();
for (int i = 0; i < total; ++i) {
// 处理单张图片
processsingleimage(imagepaths[i]);
// 更新进度
int progress = (i + 1) * 100 / total;
settaskbarprogress(progress, 100);
// 根据处理状态设置颜色
tbpflag state = tbpf_normal;
if (haserror) state = tbpf_error;
else if (iswarning) state = tbpf_paused;
settaskbarprogress(progress, 100, state);
}
// 处理完成
cleartaskbarprogress();
}
// 使用条件编译确保只在 windows 平台编译
#ifdef q_os_win
// windows 特定代码
#endif
// 或者使用运行时检测
if (qsysinfo::producttype() == "windows") {
// windows 平台逻辑
}
release() 和 couninitialize()// 进度状态智能切换
void updateprogresswithstate(int value, int total, processstatus status) {
tbpflag flag = tbpf_normal;
switch (status) {
case processstatus::normal:
flag = tbpf_normal;
break;
case processstatus::paused:
flag = tbpf_paused;
break;
case processstatus::error:
flag = tbpf_error;
break;
case processstatus::indeterminate:
flag = tbpf_indeterminate;
break;
case processstatus::completed:
flag = tbpf_noprogress;
break;
}
settaskbarprogress(value, total, flag);
}
可能原因:
解决方案:
// 添加调试信息 qdebug() << "窗口句柄:" << m_hwnd; qdebug() << "接口指针:" << m_taskbarinterface; qdebug() << "com初始化结果:" << hr;
可能原因:
预防措施:
// 在析构函数中确保资源释放
mainwindow::~mainwindow() {
#ifdef q_os_win
cleartaskbarprogress();
releasetaskbar();
#endif
}
除了进度条,itaskbarlist3 还支持任务栏按钮:
// 添加任务栏按钮(需要额外实现) // m_taskbarinterface->thumbbaraddbuttons() // m_taskbarinterface->thumbbarupdatebuttons()
在任务栏图标上显示状态指示器:
// 设置叠加图标 // m_taskbarinterface->setoverlayicon()
qt6 实现 windows 任务栏进度条的关键点:
#ifdef q_os_win 条件编译setprogressvalue 和 setprogressstate通过本文的示例代码和详细解析,您应该能够:
以上就是基于qt实现windows任务栏进度条显示(附源码)的详细内容,更多关于qt任务栏进度条的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论