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

时间:2009-10-11 19:59:09

标签: 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.QIcon('chalk.ico'))
mainwindow.setWindowIcon(QtGui.QIcon('chalk.ico'))
app.exec_()

[更新]我尝试将setWindowIcon()放在show()之前。我已尝试过其他图像,ico和png。什么都没有帮助。

3 个答案:

答案 0 :(得分:93)

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

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

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

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

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

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

答案 1 :(得分:7)

@ 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字符串识别为“另一个进程”并相应地切换图标。

答案 2 :(得分:4)

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