Как установить значок панели задач приложения в Windows 7

Как установить значок панели задач приложения в PyQt4?

Я попробовал setWindowIcon, и он успешно устанавливает значок в верхнем левом углу главного окна, но это не влияет на значок, показанный на панели задач Windows 7 - значок на панели задач остается значком Pyw 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. Ничего не помогает

4 ответа

Решение

Я нашел ответ после некоторых копаний.

В Windows 7 панель задач не для "Windows приложений" как таковой, а для "Пользовательских моделей приложений". Например, если у вас запущено несколько разных экземпляров приложения, и у каждого экземпляра есть свой значок, все они будут сгруппированы под одним значком панели задач. Windows использует различные эвристики, чтобы решить, следует ли группировать разные экземпляры, и в этом случае она решила, что все, что находится на Pythonw.exe, должно быть сгруппировано под значком Pythonw.exe.

Правильное решение для Pythonw.exe, чтобы сказать Windows, что он просто размещает другие приложения. Возможно, будущий выпуск Python сделает это. Кроме того, вы можете добавить раздел реестра, чтобы сообщить Windows, что Pythonw.exe - это просто хост, а не само приложение. См. Документацию MSDN для AppUserModelID.

Кроме того, вы можете использовать вызов Windows из Python, чтобы явно указать Windows, какой правильный AppUserModelID предназначен для этого процесса:

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

РЕДАКТИРОВАТЬ: Пожалуйста, смотрите ответ Ронана: строка myappid должна быть Unicode.

Ответ @DamonJW будет работать, но есть небольшая хитрость: myappid должен быть в кодировке Unicode (тип аргумента - PCWSTR).

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

В противном случае получение AppUserModelID приведет к неправильным символам Юникода (祭潣灭湡⹹祭牰摯捵⹴畳灢潲畤瑣瘮牥楳湯):

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 как "другой процесс" и соответственно переключать значок.

Вы должны установить AppUserModelID, прежде чем ваше приложение покажет какой-либо графический интерфейс. Если вам нужен доступ к другим функциям Windows 7, вы можете взглянуть на Q7Goodies, который является надстройкой Qt для Windows 7 с привязками PyQt.

В моей Windows 10 решение выглядит немного иначе:

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

Без задержки значок просто мигнул и исчез. С задержкой все в порядке.

Другие вопросы по тегам