2009-10-11 147 views
35

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

我试过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_() 

[更新]我已经试过show()前放置setWindowIcon()。我用其他图像,ico和png尝试过。没什么帮助。

+0

在'.show()'窗口帮助之前设置图标吗? – 2009-10-11 20:13:41

+0

不,如果我在'.show()'之前设置图标,它没有区别。 – DamonJW 2009-10-11 20:23:31

+0

你尝试过其他图像文件吗?你的代码对于我来说是一个随机的PNG文件,尽管我使用的是KDE4。 – 2009-10-11 20:39:39

回答

79

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

在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。

+0

如果它解决了你的问题,你应该接受你自己的答案。 :) – Macke 2011-01-18 11:31:55

+0

谢谢!我需要使用PySide相同的东西。 – BaldDude 2016-06-20 17:18:28

+0

如何找出什么是myappid? – aBiologist 2016-11-28 10:39:29

4

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

4

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

+0

我无法让您的代码正常工作,但@DamonJW的答案为我工作。 – uruloke 2015-05-08 12:24:04

+0

我的代码的第一部分与@ DamonJW的相同,除了'myappid'字符串前面的'u'外。第二部分只是检查Windows“看到”的实际字符串。 – 2016-03-22 15:47:13

+0

不错的加法。推测这是Python 3上的一个非问题,因为所有的字符串都是unicode。 – Snorfalorpagus 2016-04-19 08:44:19

相关问题