如何在Windows 7中设置应用程序的任务栏图标

问题描述 投票:0回答:5

如何在 PyQt4 中设置应用程序的任务栏图标?

我尝试过setWindowIcon,它成功地设置了主窗口左上角的图标,但它不影响Windows 7任务栏中显示的图标——任务栏图标仍然是默认的Python pyw图标。这是我的代码:

from PyQt4 import QtGui

app = QtGui.QApplication([])
mainwindow = QtGui.QMainWindow()
mainwindow.show()

app.setWindowIcon(QtGui.QIcon('chalk.ico'))
mainwindow.setWindowIcon(QtGui.QIcon('chalk.ico'))
app.exec_()

[更新] 我尝试将

setWindowIcon()
放在
show()
之前。我已经尝试过使用其他图像,ico 和 png。没有任何帮助。

qt windows-7 pyqt
5个回答
155
投票

经过一番挖掘,我找到了答案。

在 Windows 7 中,任务栏本身并不是用于“应用程序窗口”,而是用于“应用程序用户模型”。例如,如果您的应用程序有多个不同的实例正在运行,并且每个实例都有自己的图标,那么它们将全部分组在一个任务栏图标下。 Windows 使用各种启发式方法来决定是否应将不同的实例分组,在本例中,它决定将 Pythonw.exe 托管的所有内容都应分组在 Pythonw.exe 的图标下。

正确的解决方案是让 Pythonw.exe 告诉 Windows 它只是托管其他应用程序。也许 Python 的未来版本会做到这一点。或者,您可以添加一个注册表项来告诉 Windows Pythonw.exe 只是一个主机,而不是一个应用程序。请参阅 MSDN 文档了解 AppUserModelIDs

或者,您可以使用 Python 中的 Windows 调用,明确告诉 Windows 此进程的正确 AppUserModelID 是什么:

import ctypes
myappid = 'mycompany.myproduct.subproduct.version' # arbitrary string
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)

编辑:请参阅 Ronan 的答案:myappid 字符串应该是 unicode。


19
投票

@DamonJW 的答案可行,但有一个小问题:myappid 应该是 unicode(参数类型是 PCWSTR)。

import ctypes
myappid = u'mycompany.myproduct.subproduct.version' # arbitrary string
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)

否则获取AppUserModelID会得到错误的unicode字符(

祭潣灭湡⹹祭牰摯捵⹴畳灢潲畤瑣瘮牥楳湯
):

import ctypes
from ctypes import wintypes
lpBuffer = wintypes.LPWSTR()
AppUserModelID = ctypes.windll.shell32.GetCurrentProcessExplicitAppUserModelID
AppUserModelID(ctypes.cast(ctypes.byref(lpBuffer), wintypes.LPWSTR))
appid = lpBuffer.value
ctypes.windll.kernel32.LocalFree(lpBuffer)
if appid is not None:
    print(appid)

也就是说,这是一件小事,因为 Windows 仍然会将 unicode 字符串识别为“另一个进程”并相应地切换图标。


10
投票

您必须在应用程序显示任何 GUI 之前设置 AppUserModelID。如果您需要访问其他 Windows 7 功能,您可以查看 Q7Goodies,它是带有 PyQt 绑定的 Windows 7 的 Qt 插件。


0
投票

在我的 Windows 10 上,解决方案看起来略有不同:

import ctypes
myappid = 'mycompany.myproduct.subproduct.version' 
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
time.sleep(1)

如果没有延迟,图标就会闪烁并消失。 有了延迟就可以了。


0
投票

使用 PyQt6 和 Windows 11 的工作示例。此代码会将任务栏图标从 Python 解释器图标更改为您使用 self.setWindowIcon(QtGui.QIcon('gui/icons/Logo.png')) 设置的图标

import ctypes
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('company.app.1')
© www.soinside.com 2019 - 2024. All rights reserved.