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

Qt 如何设置应用程序';Windows 7中的任务栏图标,qt,windows-7,pyqt,Qt,Windows 7,Pyqt,如何在PyQt4中设置应用程序的任务栏图标 我尝试过setWindowIcon,它成功地将图标设置在主窗口的左上角,但它不会影响Windows 7任务栏中显示的图标——任务栏图标仍然是默认的Python pyw图标。这是我的密码: from PyQt4 import QtGui app = QtGui.QApplication([]) mainwindow = QtGui.QMainWindow() mainwindow.show() app.setWindowIcon(QtGui.QIco

如何在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。没有任何帮助。

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

在Windows7中,任务栏本身不是“应用程序窗口”,而是“应用程序用户模型”。例如,如果您有几个不同的应用程序实例正在运行,并且每个实例都有自己的图标,那么它们都将被分组在单个任务栏图标下。Windows使用各种试探法来决定是否应该对不同的实例进行分组,在这种情况下,它决定Pythonw.exe承载的所有内容都应该在Pythonw.exe的图标下进行分组

正确的解决方案是Pythonw.exe告诉Windows它只是在承载其他应用程序。也许Python的未来版本会做到这一点。或者,您可以添加一个注册表项,告诉Windows Pythonw.exe本身只是一个主机,而不是一个应用程序。有关详细信息,请参阅MSDN文档

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

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

编辑:请参阅Ronan的回答:myappid字符串应为unicode。

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

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

否则,获取AppUserModelID将获得错误的unicode字符(
祭潣灭湡⹹祭牰摯捵⹴畳灢潲畤瑣瘮牥楳湯):


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

.show()
窗口之前设置图标是否有帮助?不,如果我在
.show()
之前设置图标,则没有区别。是否尝试了其他图像文件?虽然我使用的是KDE4.Btw,但您的代码在随机png文件中运行良好-问题是否会在WinXP或Vista中重现?如果没有,请咨询-但请在此处分享您的发现:)我尝试了其他图像文件,但仍然不起作用。我没有WinXP或Vista可供测试。如果有人在这些系统上测试代码,请告诉我们答案。我已在PyQt邮件列表中发布了一个查询。如果它解决了您的问题,您应该接受自己的答案。:)谢谢我需要使用PySide做同样的事情。如何找出什么是myappid?@生物学家它的任意字符串也适用于tkinterI无法让您的代码正常工作,但@DamonJW的答案对我有效。我的代码的第一部分与@DamonJW的相同,除了
myappid
字符串中的
u
。第二部分只是检查Windows正在“查看”的实际字符串。添加得不错。这在Python 3上可能不是问题,因为所有字符串都是unicode。我不确定这是否会在非windows机器(如Linux)上中断,如果是这样,您可以通过检查
os.name
import ctypes
myappid = u'mycompany.myproduct.subproduct.version' # arbitrary string
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
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)