环境
使用Qt for Python开发Windows应用程序。
Python版本:3.12
Qt版本:PySide6
前言
先上一个简单的测试程序
from PySide6.QtWidgets import QMainWindow,QLabel,QApplication
from PySide6 import QtGui
import sysclass MainWindow(QMainWindow):def __init__(self):super().__init__()self.resize(200,100)self.setWindowTitle("Hello World")label = QLabel("My test app.")label.setMargin(10)self.setCentralWidget(label)self.show()if __name__ == '__main__':app = QApplication(sys.argv)w = MainWindow()app.exec()
运行:
设置应用程序图标
以上测试程序,左上角没有程序图标,想要设置窗口显示的图标,很简单,和原生Qt开发一样的,添加setWindowIcon
修改以上代码,添加:
if __name__ == '__main__':app = QApplication(sys.argv)app.setWindowIcon(QtGui.QIcon('logo.ico'))w = MainWindow()app.exec()
再次运行,就可以看到窗口显示的程序图标了。
通过pyinstaller打包出来:
pyinstaller.exe .\TestIcon.py
这时候会看到一个默认的程序图标,如下:
这并不是我们想要设置的logo,想要修改这个应用程序图标,两个方法:
1.通过pyinstaller命令直接添加ico图标进行打包
pyinstaller.exe --windowed --icon=logo.ico .\TestIcon.py
然后可以看到同级目录下dist文件夹中,生成的打包程序:
2.通过修改.spec文件后打包
前面我们在执行 pyinstaller.exe .\TestIcon.py
后 ,同级目录下会生成一个和Python文件名相同的.spec文件
通过文本打开后,在这里添加icon=['logo.ico']
指定ico图标的位置
然后在终端使用pyinstaller执行这个spec文件:
pyinstaller.exe .\TestIcon.spec
也是同样的效果。
最后需要注意的是,pyinstaller打包后,需要将图标文件拷贝到运行程序目录去,否则运行时窗口图标显示不了。
设置任务栏图标
以上设置了窗口上显示的程序图标以及打包出来的exe显示的图标,再次运行这个程序,会发现系统任务栏上显示的图标依然不是我们设置的logo图标,而是这样:
这是因为运行应用程序时,Windows 会查看可执行文件并尝试猜测它属于哪个“应用程序组”。默认情况下,任何 Python 脚本(包括你的应用程序)都归入同一个“Python”组,因此将显示 Python 图标。为了阻止这种情况发生,我们需要为 Windows 提供不同的应用程序标识符。
下面的代码通过调用ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID()
自定义应用程序 ID 来实现这一点。
只需要在代码前面添加以下内容:
try:from ctypes import windll # Only exists on Windows.myappid = 'mycompany.myproduct.subproduct.version'windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
except ImportError:pass
完整代码如下:
from PySide6.QtWidgets import QMainWindow,QLabel,QApplication
from PySide6 import QtGui
import systry:from ctypes import windll # Only exists on Windows.myappid = 'mycompany.myproduct.subproduct.version'windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
except ImportError:passclass MainWindow(QMainWindow):def __init__(self):super().__init__()self.resize(200,100)self.setWindowTitle("Hello World")label = QLabel("My test app.")label.setMargin(10)self.setCentralWidget(label)self.show()if __name__ == '__main__':app = QApplication(sys.argv)app.setWindowIcon(QtGui.QIcon('logo.ico'))w = MainWindow()app.exec()
再次运行,可以看到系统任务栏上已经能够正常显示logo了
注意:上面的列表显示了一个通用mycompany.myproduct.subproduct.version字符串,实际应该对其进行更改以成你的实际应用的信息。输入什么并不重要,但惯例是使用反向域表示法com.mycompany来表示公司标识符。