1.起因:
希望:pyqt5 项目,pyinstaller main.spec 打包,我想要 main.exe 就像一个普通的应用软件一样显示我自定义的图标。
结果: main.exe 左侧图标还是老土的样子,并没有成为我的图标。独立运行是,任务栏也没有出现该图标。真的搞了很久,信心受挫。
最后,无意中发现有个简单的办法就能实现了。说到底是打包资源和路径的问题。
2.失败的尝试
先说一下用过却失败的办法,给大家避坑。也可能有些人正碰上类似的问题,刚好能解决。
1.失败1:有人说在代码最开头加上下面的代码,任务栏上就会出现自定义的图标。
import ctypes
if __name__ == "__main__":
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")
在我这里用不用都无变化。
2.失败2:有人说要在 QtDesigner 里面的时候就设置好,然后 pyuic5 -o xx.py xx.ui
设置好确实可以在pycharm中运行时显示,但是依然没法在独立运行时在任务栏显示。
3.失败3:我一直想,可能是资源文件没打包好,导致找不到图标才不行的。
道理是对的,但是我一直折腾 pyrcc5 .\rcc.qrc -o rcc_rc.py 命令就没必要了。
最终的路径错误是这样解决:
3.解决:
设置 exe 的图标:
原图标:
(随机图标,网络上找的图片,最好白背景,方便处理):
实现后的图标:
要注意的是,windows上显示软件图标具有滞后性,所以当你把exe复制到桌面后发现图标没了,不要惊慌,只要一直盯着它看,过两天就会出现图标了,一切尽在掌握!:
桌面图标看起来(滞后性,刷新没用,这是windows缓存机制的原因):
如果你想要立刻就看到图标变化怎么办?
解决:每次生成exe后,在 cmd 中用如下命令刷新图标缓存(win10):
ie4uinit.exe -show
win7,8用:ie4uinit.exe -ClearIconCache
好了,下面是设置 exe 的图标的具体做法。
做法:
exe图标必须是 ico,所以要先制作图片。
1.先将 png 转换为 ico 图片(这个地方只能是 ico 格式才能设置)。
png转ico
有很多在线转换网站,但都不太好用,这个还行。你如果有更好的,不妨在评论区留言。
导出尺寸你可以先用 16*16 大小。
windows 在文件管理器(就是文件夹)里默认用的是 16*16 的尺寸。在桌面用的好像是64*64?,所以导出64的也行(我测试的时候用的16,桌面图标被放大了不好看)。
2.在 main.spec 中设置 icon 路径(pyinstaller 的时候打包进去),我用的是 main.spec,所以设置:
exe = EXE(
...
icon='resource\\qrc\\image\\mian.ico',
如果用pyinstaller命令直接打包格式差不多如下:
pyinstaller -i "D:\xxx.ico" -F -D ×××.py
-i 就是 -icon 的意思
设置任务栏图标(窗口图标)
1.增加代码:假设你的图片路径为 image/my.png
def init_ui(self):
filename = self.resource_path(os.path.join("image/", "my.png"))
self.setWindowIcon(QIcon(filename))
def resource_path(self, relative_path):
if getattr(sys, 'frozen', False):
base_path = sys._MEIPASS
else:
base_path = "./"
ret_path = os.path.join(base_path, relative_path)
return ret_path
注意: resource_path 函数的作用就是区分你在 pycharm 的测试环境,还是在 exe 的实际运行环境。 这个函数是重点,如果没有这个函数,你设置的图像依然不会正常显示。
sys._MEIPASS 是获得 exe 在Windows上运行时的路径(并不是exe的路径,而是一个exe解压后的临时路径)。
2.把图片一起打包过去,我用的是 pyinstaller main.spec 命令,只需要增加一个 data 就行了:
datas=[
(path.join('D:\\xxx', '.\\image\\'), '\\image\\'),
],
就这样,第一步,代码里设置窗口图标,第二步,打包图片到运行路径下,,这两步都完成就行了。逻辑上走通。
看看运行效果:
请为我打 666,谢谢您嘞!