如何在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。什么都没有帮助。
答案 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插件。