wxpython如何设置window上任务栏的进度条

news2025/1/16 3:31:30

该功能是各大编译器或者一些软件在执行耗时操作时,显示进度的一种方式:

Qt

如果是使用的pyQt或者是Qt就很简单了,直接使用QWinTaskbarProgress就可以完成该功能。

Wxpython

但是wxpython就没有那么简单了,需要了解一些window的特性。

预备知识

这里需要简单了解COM在Window上的概念,Window的构件框架,可以将一些功能模块化,能够兼容的使用其中提供的功能,只暴露出接口Class提供给我们使用。

这里CLSID就是每一个接口Class的全局ID,例如CLSID_TaskbarList的为{56FDF344-FD6D-11d0-958A-006097C9A090}。

然后采用组合或者继承的方式,可以从CLSID的类中选择实例化接口:
例如:

 pythoncom.CoCreateInstance(shell.CLSID_TaskbarList, None, pythoncom.CLSCTX_INPROC_SERVER, shell.IID_ITaskbarList)

这里的None与CLSID采用的继承或者组合的方式有关,一般情况下是None.

而pythoncom.CLSCTX_INPROC_SERVER则与注册该功能是否存在InProcServer32有关:

这样大概就知道了实现window任务栏进度条的方法,需要从微软提供的官方COM中使用其中的接口进行实现功能。

方式一

这里我首先尝试使用的是win32com的,但是目前的该功能仅仅支持ItaskbarList的基础类,功能也仅仅是支持有限的几个,删除激活任务栏而已。

大概的流程是:

import time
import win32api
import win32con
import win32gui
import pythoncom

from win32com.shell import shell, shellcon

# 获取 Shell 的 COM 接口
shell_instance = pythoncom.CoCreateInstance(shell.CLSID_TaskbarList, None, pythoncom.CLSCTX_INPROC_SERVER, shell.IID_ITaskbarList)

shell_instance.HrInit()
shell_instance.AddTab(hwnd)
shell_instance.ActivateTab(hwnd)
shell_instance.DeleteTab(hwnd)

这种方式最后宣告失败,就算是我从window中寻找到了对应的IID_ITaskbarList3为{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF},并做了修改,可在shell.CLSID_TaskbarList寻找不到这个子接口,一直报错。

方式二:

直接使用python调用COM的常规方法。

参考:nullicon-default.png?t=N7T8https://www.coder.work/article/347057

参考:Using API's in a:: format? - Programming (C#, C++, JAVA, VB, .NET etc.) - Neowinicon-default.png?t=N7T8https://www.neowin.net/forum/topic/716968-using-apis-in-a-objectaction-format/#comment-590434472

参考微软ITaskbarList3文档:

ITaskbarList3 (shobjidl_core.h) - Win32 apps | Microsoft Learnicon-default.png?t=N7T8https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nn-shobjidl_core-itaskbarlist3

主代码如下:

# coding:utf-8
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# {EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF} IID_ITaskbarList3

import wx
import comtypes.client as cc
cc.GetModule("TaskbarLib.tlb")
import comtypes.gen.TaskbarLib as tbl

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(300, 200))
        self.panel = wx.Panel(self)

        self.progress = 0

        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
        self.timer.Start(1000)

    def OnTimer(self, event):
        self.progress += 10
        if self.progress > 100:
            self.progress = 0

        self.SetTaskbarProgress(self.progress)

    def SetTaskbarProgress(self, progress):
        hwnd = self.GetHandle()
        taskbar = cc.CreateObject(
            "{56FDF344-FD6D-11d0-958A-006097C9A090}",
            interface=tbl.ITaskbarList3)

        taskbar.HrInit()

        taskbar.AddTab(hwnd)
        taskbar.ActivateTab(hwnd)

        """
        TBPF_NOPROGRESS (0x00000000)
        停止显示进度并将按钮返回到其正常状态。 使用此标志调用此方法,以在操作完成或取消时关闭进度栏。
        
        TBPF_INDETERMINATE (0x00000001)
        进度指示器的大小不会增加,但会重复沿任务栏按钮的长度循环。 这表示活动未指定完成进度的比例。 正在取得进展,但无法预测操作需要多长时间。
        
        TBPF_NORMAL (0x00000002)
        进度指示器的大小从左到右增长,与估计完成的操作量成比例。 这是一个确定的进度指示器:正在对操作持续时间进行预测。
        
        TBPF_ERROR (0x00000004)
        进度指示器变为红色,表示在其中一个正在广播进度的窗口中发生了错误。 这是一个确定的状态。 如果进度指示器处于不确定状态,则会切换到红色确定性显示,其中泛型百分比不指示实际进度。
        
        TBPF_PAUSED (0x00000008)
        进度指示器变为黄色,表示进度当前在其中一个窗口中已停止,但用户可以恢复。 不存在错误条件,并且没有任何内容阻止进度继续。 这是一个确定的状态。 如果进度指示器处于不确定状态,则会切换到黄色确定性显示,其中泛型百分比不指示实际进度。
        """
        taskbar.SetProgressState(hwnd, 0x00000001)# TBPF_INDETERMINATE (0x00000001)

        taskbar.SetProgressValue(hwnd, progress, 100)



app = wx.App(False)
frame = MyFrame(None, wx.ID_ANY, "Taskbar Progress Indicator")
frame.Show()
app.MainLoop()

可以看到使用的是comtypes模块来进行实现了该功能,这里可能会有一个疑惑:

TaskbarLib.tlb是什么?

简单理解就是类似与一个C语言的.h文件,能够从中获取对应的接口来进行使用,而这里文件的生成就是使用微软提供的工具。

TaskbarLib.tlb的生成

这里该文件是由一个配置文件TaskbarLib.idl:

[
   uuid(683BF642-E9CA-4124-BE43-67065B2FA653),
   version(1.0),
]
library TaskbarLib
{
[
	uuid(56FDF342-FD6D-11d0-958A-006097C9A090),
	object,
]
interface ITaskbarList : IUnknown 
{
	HRESULT _stdcall HrInit();

	HRESULT _stdcall AddTab([in] long hwnd);

	HRESULT _stdcall DeleteTab([in] long hwnd);

	HRESULT _stdcall ActivateTab([in] long hwnd);

	HRESULT _stdcall SetActivateAlt([in] long hwnd);
};

[
	uuid(602D4995-B13A-429b-A66E-1935E44F4317),
	object,
]
interface ITaskbarList2 : ITaskbarList
{
	HRESULT MarkFullscreenWindow(
		[in] long hwnd,
		[in] BOOL fFullscreen);
}

cpp_quote("#ifdef MIDL_PASS")
typedef IUnknown* HIMAGELIST;
typedef IUNknown* HICON;
cpp_quote("#endif")

cpp_quote("#include <pshpack8.h>")
typedef struct tagTHUMBBUTTON
{
	DWORD   dwMask;
	UINT	iId;
	UINT	iBitmap;
	HICON   hIcon;
	WCHAR   szTip[260];
	DWORD   dwFlags;
} THUMBBUTTON, *LPTHUMBBUTTON;
cpp_quote("#include <poppack.h>")

[
	uuid(ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf),
	object,
]
interface ITaskbarList3 : ITaskbarList2
{
	// Flags for Setting Taskbar Progress state
	typedef [v1_enum] enum TBPFLAG
	{
		TBPF_NOPROGRESS	 = 0x00000000,
		TBPF_INDETERMINATE  = 0x00000001,
		TBPF_NORMAL		 = 0x00000002,
		TBPF_ERROR		  = 0x00000004,
		TBPF_PAUSED		 = 0x00000008,
	} TBPFLAG;

	cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(TBPFLAG)")

	// Flags for SetTabActive
	typedef [v1_enum] enum TBATFLAG
	{
		TBATF_USEMDITHUMBNAIL   = 0x00000001,
		TBATF_USEMDILIVEPREVIEW = 0x00000002,
	} TBATFLAG;

	cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(TBATFLAG)")

	HRESULT SetProgressValue(
		[in] long hwnd,
		[in] ULONGLONG ullCompleted,
		[in] ULONGLONG ullTotal);

	HRESULT SetProgressState(
		[in] long hwnd,
		[in] TBPFLAG tbpFlags);

	HRESULT RegisterTab(
		[in] long hwndTab,
		[in] HWND hwndMDI);

	HRESULT UnregisterTab(
		[in] long hwndTab);

	HRESULT SetTabOrder(
		[in] long hwndTab,
		[in] long hwndInsertBefore);

	HRESULT SetTabActive(
		[in] long hwndTab,
		[in] long hwndMDI,
		[in] TBATFLAG tbatFlags);

	HRESULT ThumbBarAddButtons(
		[in] long hwnd,
		[in] UINT cButtons,
		[in, size_is(cButtons)] LPTHUMBBUTTON pButton);

	HRESULT ThumbBarUpdateButtons(
		[in] long hwnd,
		[in] UINT cButtons,
		[in, size_is(cButtons)] LPTHUMBBUTTON pButton);

	HRESULT ThumbBarSetImageList(
		[in] long hwnd,
		[in] HIMAGELIST himl);

	HRESULT SetOverlayIcon(
		[in] long hwnd, 
		[in] HICON hIcon,
		[in, string] LPCWSTR pszDescription);

	HRESULT SetThumbnailTooltip(
		[in] long hwnd, 
		[in, string] LPCWSTR pszTip);

	HRESULT SetThumbnailClip(
		[in] long hwnd, 
		[in] RECT *prcClip);
}

[ uuid(56FDF344-FD6D-11d0-958A-006097C9A090) ] coclass TaskbarList { interface ITaskbarList3; }
};

这里的midl编译器比较麻烦获得,如果电脑有安装VSStudio可能会简单很多:
打开工具-命令行-开发者(powershell),在这里输入midl即可。

使用MIDL编译器进行生成:

midl /tlb   .\TaskbarLib.tlb TaskBarLib.idl

生成dll:

TlbImp .\TaskbarLib.tlb /out:TaskbarLib.dll

这里提供一个编译好的备份:

链接:https://pan.baidu.com/s/1-0UQrzjC0d_paDP5w5KknQ 
提取码:947z

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1149172.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

项目经理有责任,没权利,如何确保项目顺利交付?

由于项目经理在项目中所背负的责任并未被赋予相应的权力,因此在协调资源和组织协同工作方面,他们无法简单地借助权力来解决问题。一旦项目出现问题,不论责任在哪一方,项目经理都首当其冲地需要承担责任。 虽然项目经理看似权力很…

SVN出现Cleanup failed to process the following paths...

SVN报错,需要执行SVN的清理命令clean up,但clean up时出现错误Cleanup failed to process the following paths... 解决办法: 1、clean up的窗口,勾选Break locks和Fix time stamps(简单方便)&#xff1b…

ESP8266模块常规调试过程讲解

ESP8266-WIFI模块串口调试过程讲解 一、ESP8266介绍 ESP8266是一个高度集成的无线SoC(System on a Chip)模块,基于ESP8266芯片,集成了Wi-Fi功能。具有丰富的特性和功能,广泛应用于各种物联网项目中。 ESP8266模块支持802.11b/g/n无线标准,内置TCP/IP协议栈,可以实现串…

Linux之centos7安装配置及Linux常用命令

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《LInux实战开发》。🎯🎯 …

私有云:【7】VCenter安装Composer服务

私有云:【7】VCenter安装Composer服务 1、创建Composer数据库2、VCenter安装Composer服务2.1、安装Native Client组件2.2、对Composer服务器扩容出一个安装盘 3、安装Composer服务 服务器创建好后配置IP,加入域以及添加域管理员cloudadmin,可…

如何校准振弦采集模块以获得更准确的读数?

如何校准振弦采集模块以获得更准确的读数? 振弦采集模块是一种用于测量振弦传感器输出的模块。在使用振弦采集模块时,校准是非常重要的,因为它可以确保您获得准确的测量结果。本文将介绍如何校准振弦采集模块以获得更准确的读数。 1. 使用标…

华为OD机试 - 堆栈中的剩余数字 - 逻辑分析(Java 2023 B卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述1、输入2、输出3、说明 四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题&a…

如何零样本实现语义分割

CLIPTeacher:一种基于VLM的通用零样本语义分割框架,有效地利用了可见和忽略区域,而不需要对原CLIP模型进行任何更改,性能提升显著!单位:名古屋大学 现有的通用零样本语义分割(GZLSS&#xff09…

校园快递派送互助系统 微信小程序设计与实现

本毕业设计的内容是设计实现一个基于Springboot微信小程序的快递校园帮。使用微信开发者是以java语言进行开发,MYSQL为数据库开发平台,Tomcat网络信息服务作为应用服务器。快递校园帮的功能已基本实现,主要包括有用户、快递员、快递公司、快递…

使用Panda-Gym的机器臂模拟进行Deep Q-learning强化学习

强化学习(RL)是一种机器学习方法,它允许代理通过试错来学习如何在环境中表现。行为主体因采取行动导致预期结果而获得奖励,因采取行动导致预期结果而受到惩罚。随着时间的推移,代理学会采取行动,使其预期回报最大化。 RL代理通常使…

Kubernetes概念及实践

Kubernetes(K8S)中文文档_Kubernetes中文社区 Kubernetes 文档 | Kubernetes K8S 是负责自动化运维管理多个跨机器 Docker 程序的 集群。 kubeadm快速部署K8s集群的工具,如: 创建master node:kubeadm init 将worker node加入到集群中&#x…

Qt 重写QSlider简单实现滑动解锁控件(指定百分比回弹效果)

组件效果图: 应用场景: 用于滑动解锁相关场景,Qt的控件鼠标监听机制对于嵌入式设备GUI可触摸屏依旧可用。 实现方式: 主要是通过继承QSlider以及搭配使用QStyleOptionSlider来实现效果。 注意细则: QStyleOptionSlider是用于定制空白区域是否可移动滑块,根据需求可…

MySQL 到 TiDB:vivo 的 Hive Metastore 横向扩展之路

以下文章来源于公众号 vivo 互联网技术 ,作者 Wang Zhiwen 导读 本文介绍了 vivo 在大数据元数据服务横向扩展道路上的探索历程,由实际面临的问题出发,对当前主流的横向扩展方案进行了调研及对比测试,通过多方面对比数据择优选择…

10_4阻塞和非阻塞跟poll和等待队列

阻塞和非阻塞 广泛上的区别就是 应用程序如果非阻塞那读取不到数据就应该马上有返回值 阻塞的话就是在应用程序去read数据,但是设备驱动没有数据,就一直卡住,直到有数据再继续往下 补充阻塞知识,应用层大部分都是阻塞 如果要非阻塞 ,应用程序在打开设备节点的时候填写int fd …

文件夹比较工具怎么用 对比两个文件夹找出多余的文件

在日常工作中,经常会接触到大量的文件,长时间堆积,文件夹会越来越多,从而导致文件重复,如果想要找出想要的文件会比较麻烦,那么你知道应该怎么来查找吗?下面就让我们来学习一下文件夹比较工具怎…

【LeetCode刷题-哈希】-- 705.设计哈希集合

705.设计哈希集合 方法:使用链地址法 设哈希表的大小为base,可以设计一个简单的哈希函数:hash(x) x mod base 开辟一个大小为base的数组,数组的每个位置是一个链表,当计算出哈希值后,就插入到对应位置的…

华为OD机试 - 计算疫情扩散时间 - 矩阵(Java 2023 B卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷&#…

在CentOS上用yum方式安装MySQL8真实全过程记录(顺利版本)

此文参考我前面的文章《在CentOS上用yum方式安装MySQL8过程记录》,之前比较曲折,现在再安装一台mysql。 因为之前很多坑已经走过,加上这台Linux之前没安装过MYSQL,所以整个过程算是非常顺利。 安装环境:centos7 mysql…

【c++|opencv】一、基础操作---1.图像读取

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 有关c操作opencv记录 1. 正文 1.1 图像读取、显示、保存 // 读取、显示、保存图像#include <opencv2/opencv.hpp> #include <iostream>us…

开发语言工具编程系统化教程入门和初级专辑课程上线

开发语言工具编程系统化教程入门和初级专辑课程上线 学习编程捷径&#xff1a;&#xff08;不论是正在学习编程的大学生&#xff0c;还是IT人士或者是编程爱好者&#xff0c;在学习编程的过程中用正确的学习方法 可以达到事半功倍的效果。对于初学者&#xff0c;可以通过下面…