如何将基于tkinter的应用程序与自定义图标捆绑在一起?

时间:2019-11-20 14:43:02

标签: python image user-interface tkinter pyinstaller

我有一个基于tkinter的应用程序,结构如下:

import tkinter as tk

class App(tk.Frame):
    def __init__(self, master):
        self.master = master
        tk.Frame.__init__(self, self.master)
        self.configure_gui()
        self.create_widgets()

    def configure_gui(self):
        self.master.iconbitmap("my_logo.ico")
        self.master.title("Example")
        self.master.minsize(250, 50)

    def create_widgets(self):
        self.label = tk.Label(self.master, text="hello world")
        self.label.pack()


if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    root.mainloop()

当我从命令行运行.py文件时,我的徽标将按预期替换应用程序主窗口中的默认tkinter feather徽标。我什至可以使用以下命令将应用程序冻结并捆绑到pyinstaller中:

pyinstaller -i my_logo.ico my_application.py

不幸的是,当我尝试运行此过程生成的.exe文件时,遇到以下错误:

Traceback (most recent call last):
  File "my_application.py", line 22, in <module>
  File "my_application.py", line 7, in __init__
  File "my_application.py", line 11, in configure_gui
  File "tkinter\__init__.py", line 1865, in wm_iconbitmap
_tkinter.TclError: bitmap "my_logo.ico" not defined
[5200] Failed to execute script my_application

我搜寻了这个网站和其他网站,以寻找适合我的情况的解决方案,但没有找到。任何方向将不胜感激!

1 个答案:

答案 0 :(得分:1)

我发现将映像存储为.py模块对我来说比较容易,然后PyInstaller像处理其他模块和基本命令行命令一样处理该映像,以使exe正常运行而无需任何特殊操作:

制作image.py文件的脚本:

import base64
with open("my_logo.ico", "rb") as image:
    b = base64.b64encode(image.read())
with open("image.py", "w") as write_file:
    write_file.write("def icon(): return (" + str(b) + ")"

然后将模块导入为图像:

import tkinter as tk
import image

class App(tk.Frame):
    def __init__(self, master):
        self.master = master
        tk.Frame.__init__(self, self.master)
        self.configure_gui()
        self.create_widgets()

    def configure_gui(self):
        self.master.tk.call('wm', 'iconphoto', self.master._w, tk.PhotoImage(data=image.icon()))
        self.master.title("Example")
        self.master.minsize(250, 50)

    def create_widgets(self):
        self.label = tk.Label(self.master, text="hello world")
        self.label.pack()


if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    root.mainloop()

否则,您基本上必须调出在build命令中添加.ico文件,然后在脚本中需要添加行以确定解压缩后的pyinstaller-packed脚本的目录位置,然后调整压缩后的路径.ico个文件。

在这里讨论:Bundling data files with PyInstaller (--onefile)

但是我发现自己的方式更容易。