当前位置: 代码网 > it编程>编程语言>C/C++ > 基于Qt实现Windows任务栏进度条显示(附源码)

基于Qt实现Windows任务栏进度条显示(附源码)

2026年08月06日 C/C++ 我要评论
一、效果展示二、源码分享工程使用qmake编译1、.proqt += widgets printsupportconfig += c++17# you can make your code fail

一、效果展示

二、源码分享

工程使用qmake编译

1、.pro

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

2、mainwindow.h

#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

3、mainwindow.cpp

#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
}

4、main.cpp

#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();
}

三、任务栏进度条详解

1、 技术原理

windows 任务栏进度条功能是通过 windows 7 引入的 itaskbarlist3 com 接口实现的。该接口提供了丰富的任务栏交互能力,包括:

  • 进度显示:在应用程序图标上显示进度条
  • 缩略图工具栏:添加自定义按钮到任务栏预览
  • 叠加图标:在图标上显示状态指示器
  • 缩略图预览:自定义任务栏预览内容

qt 作为跨平台框架,需要通过平台特定的代码来调用这些 windows api。

2、 核心 api 解析

itaskbarlist3 接口

// 主要进度相关方法
hresult setprogressstate(hwnd hwnd, tbpflag tbpflags);
hresult setprogressvalue(hwnd hwnd, ulonglong ullcompleted, ulonglong ulltotal);

参数说明:

  • hwnd:窗口句柄,通过 qwidget::winid() 获取
  • tbpflags:进度状态标志,控制进度条外观和行为
  • ullcompleted:已完成的工作量
  • ulltotal:总工作量

进度状态标志 (tbpflag)

typedef enum tbpflag {
    tbpf_noprogress       = 0x00000000,  // 无进度条
    tbpf_indeterminate    = 0x00000001,  // 不确定进度(转圈动画)
    tbpf_normal           = 0x00000002,  // 绿色正常进度
    tbpf_error            = 0x00000004,  // 红色错误状态
    tbpf_paused           = 0x00000008   // 黄色暂停状态
} tbpflag;

3、实现步骤详解

环境配置

项目文件 (.pro) 配置:

win32 {
    libs += -luser32 -lole32  # 链接 windows api 库
}

头文件包含:

#ifdef q_os_win
#define initguid
#include <windows.h>
#include <shobjidl.h>  // itaskbarlist3 接口定义
#endif

com 初始化

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
}

4、实际应用场景

文件下载/上传进度

// 模拟文件下载进度
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();
}

5、注意事项与最佳实践

平台兼容性

// 使用条件编译确保只在 windows 平台编译
#ifdef q_os_win
    // windows 特定代码
#endif

// 或者使用运行时检测
if (qsysinfo::producttype() == "windows") {
    // windows 平台逻辑
}

资源管理

  1. 及时释放 com 资源:在窗口关闭时调用 release()couninitialize()
  2. 异常处理:检查 com 调用返回值,处理可能的失败
  3. 线程安全:com 初始化应在主线程进行

用户体验优化

// 进度状态智能切换
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);
}

6、常见问题与解决方案

问题1:进度条不显示

可能原因:

  • com 初始化失败
  • 窗口句柄无效
  • itaskbarlist3 接口创建失败

解决方案:

// 添加调试信息
qdebug() << "窗口句柄:" << m_hwnd;
qdebug() << "接口指针:" << m_taskbarinterface;
qdebug() << "com初始化结果:" << hr;

问题2:进度状态不更新

可能原因:

  • 未在主线程调用
  • 进度值超出范围
  • 状态标志设置错误

问题3:内存泄漏

预防措施:

// 在析构函数中确保资源释放
mainwindow::~mainwindow() {
#ifdef q_os_win
    cleartaskbarprogress();
    releasetaskbar();
#endif
}

7、扩展功能

任务栏按钮

除了进度条,itaskbarlist3 还支持任务栏按钮:

// 添加任务栏按钮(需要额外实现)
// m_taskbarinterface->thumbbaraddbuttons()
// m_taskbarinterface->thumbbarupdatebuttons()

叠加图标

在任务栏图标上显示状态指示器:

// 设置叠加图标
// m_taskbarinterface->setoverlayicon()

8、总结

qt6 实现 windows 任务栏进度条的关键点:

  1. 平台特定代码:使用 #ifdef q_os_win 条件编译
  2. com 接口:正确初始化和释放 itaskbarlist3 接口
  3. 进度控制:合理使用 setprogressvaluesetprogressstate
  4. 状态管理:根据业务逻辑切换不同的进度状态
  5. 资源清理:确保在程序退出时释放所有 com 资源

通过本文的示例代码和详细解析,您应该能够:

  • 理解 windows 任务栏进度条的工作原理
  • 在 qt6 项目中正确集成该功能
  • 根据实际需求定制进度显示逻辑
  • 处理常见的兼容性和稳定性问题

以上就是基于qt实现windows任务栏进度条显示(附源码)的详细内容,更多关于qt任务栏进度条的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com