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

Dam*_*nJW 42 qt pyqt windows-7

如何在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_()
Run Code Online (Sandbox Code Playgroud)

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

Dam*_*nJW 97

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

在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)
Run Code Online (Sandbox Code Playgroud)

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


Ron*_*xão 9

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

import ctypes
myappid = u'mycompany.myproduct.subproduct.version' # arbitrary string
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
Run Code Online (Sandbox Code Playgroud)

否则,获取AppUserModelID会得到错误的unicode characters(???????????????????):

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)
Run Code Online (Sandbox Code Playgroud)

也就是说,这是一个小问题,因为Windows仍然会将unicode字符串识别为"另一个进程"并相应地切换图标.


小智 5

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