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

发布于 2024-08-07 21:31:44 字数 510 浏览 5 评论 0原文

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

How do I set an application's taskbar icon in PyQt4?

I have tried setWindowIcon, and it successfully sets the icon in the top-left of the main window, but it does not affect the icon shown in the Windows 7 taskbar -- the taskbar icon remains the default Python pyw icon. Here is my code:

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_()

[update] I've tried placing the setWindowIcon() before the show(). I've tried it with other images, ico and png. Nothing helps.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

扮仙女 2024-08-14 21:31:44

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

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

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

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

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

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

I've found the answer, after some digging.

In Windows 7, the taskbar is not for "Application Windows" per se, it's for "Application User Models". For example, if you have several different instances of your application running, and each instance has its own icon, then they will all be grouped under a single taskbar icon. Windows uses various heuristics to decide whether different instances should be grouped or not, and in this case it decided that everything hosted by Pythonw.exe should be grouped under the icon for Pythonw.exe.

The correct solution is for Pythonw.exe to tell Windows that it is merely hosting other applications. Perhaps a future release of Python will do this. Alternatively, you can add a registry key to tell Windows that Pythonw.exe is just a host rather than an application in its own right. See MSDN documentation for AppUserModelIDs.

Alternatively, you can use a Windows call from Python, to explicitly tell Windows what the correct AppUserModelID is for this process:

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

EDIT: Please see Ronan's answer: the myappid string should be unicode.

青衫负雪 2024-08-14 21:31:44

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

@DamonJW's answer will work, but there is a minor catch: myappid should be unicode (argument type is PCWSTR).

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

Otherwise getting the AppUserModelID will get wrong 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)

That said, it is a minor thing, since Windows will still recognize the unicode string as "another process" and switch the icon accordingly.

摘星┃星的人 2024-08-14 21:31:44

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

You must set the AppUserModelID before your app shows any GUI. If you need to access other Windows 7 features you can have a look at Q7Goodies which is a Qt add-on for Windows 7 with a PyQt bindings.

扭转时空 2024-08-14 21:31:44

使用 PyQt6 和 Windows 11 的工作示例。此代码会将任务栏图标从 Python 解释器图标更改为您使用 self.setWindowIcon(QtGui.QIcon('gui/icons/Logo.png')) 设置的图标

import ctypes
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('company.app.1')

Working example using PyQt6 and Windows 11. This code will change the taskbar icon from the Python interpreter icon to what you set using self.setWindowIcon(QtGui.QIcon('gui/icons/Logo.png'))

import ctypes
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('company.app.1')
杀お生予夺 2024-08-14 21:31:44

在我的 Windows 10 上,解决方案看起来略有不同:

import ctypes
myappid = 'mycompany.myproduct.subproduct.version' 
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
time.sleep(1)

没有延迟,图标只是闪烁并消失。
有了延迟就可以了。

On my Windows 10 the solution looks slightly different:

import ctypes
myappid = 'mycompany.myproduct.subproduct.version' 
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
time.sleep(1)

Whit out the delay an icon just blinking and disappeared.
With the delay it is woks OK.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文