Tkinter程序经PyInstaller打包为exe后主程序控件不显示问题
Tkinter程序PyInstaller打包后主窗口控件不显示问题
本地VS Code运行正常,但PyInstaller打包为.exe后,登录界面能正常工作,登录成功后调用的main_program类仅能生成对应尺寸和背景色的窗口,但所有控件都不显示。
登录界面代码
from config import * import base64 from PIL import ImageTk,Image from attribution_tool_main_program_class import main_program import pandas as pd import os import sys from sql_uploader import azure_sql_connector from tkinter import Tk,Label,Canvas,Entry,Button, messagebox, Toplevel,mainloop class login_screen_class(): def __init__(self): self.df = azure_sql_connector('opr_dev').read_table('SELECT * FROM [dbo].[attribution_username_file]') self.root = Tk() self.root.withdraw() self.login_screen = Toplevel(self.root) self.login_screen.title("Attribution Tool - Login") self.login_screen.geometry("1920x1080") train_icon = self.resource_path('train.ico') self.login_screen.iconbitmap(train_icon) background_image=self.resource_path('background_image_2.png') self.my_img = ImageTk.PhotoImage(Image.open(background_image)) my_label = Label(self.login_screen,image=self.my_img) my_label.grid(row=0,column=0, sticky='N') my_canvas1 = Canvas(self.login_screen,bg = "#75787B") my_canvas1.grid(row=0,column=0,padx=200,pady=200) font= "Helvetica, 16" user_Name = Label(my_canvas1,text="Username",bg = "#75787B", fg="white",font=font) user_Name.grid(row=0,column=0,columnspan=2,pady=10,padx=10,sticky='N') self.username_entry = Entry(my_canvas1,width =30,bg = "#75787B",font=font,foreground='white') self.username_entry.grid(row=1,column=0,padx=10) password_name = Label(my_canvas1,text="Password",bg = "#75787B", fg="white",font=font,borderwidth=0) password_name.grid(row=2,column=0,columnspan=2,pady=10,padx=10) self.password_entry = Entry(my_canvas1,width =30,bg = "#75787B",font=font,foreground='white',show='*') self.password_entry.grid(row=3,column=0,padx=10) login_image=self.resource_path('login-button-png-7.png') my_img_login = ImageTk.PhotoImage(Image.open(login_image)) sign_in_button = Button(my_canvas1,image=my_img_login, command = lambda: self.username_password_check(), borderwidth=0) sign_in_button.grid(row=4,column=0,columnspan=2, pady=10, padx=10) self.login_screen.bind_all("<Return>",self.username_password_check) mainloop() def resource_path(self,relative_path): try: base_path = sys._MEIPASS except Exception: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path) def username_password_check(self,event=None): self.username = self.username_entry.get().lower() password=self.password_entry.get() if self.username =="": messagebox.showerror("No username entered", "Please enter a valid username to login to Attribution Tool") elif password =="": messagebox.showerror("No password entered", "Please enter a valid password to login to Attribution Tool") login_list = self.df.values.tolist() for record in login_list: if record[0].lower() ==self.username: if base64.b64decode(record[1]).decode("utf-8") == password: self.login_screen.withdraw() main_program((self.username).capitalize(),self.root) else: messagebox.showerror("Login Error", "The details you have entered are invalid") break if __name__ == '__main__': login_screen_class()
使用的PyInstaller打包命令
pyinstaller --name Attribution_tool --onefile --windowed --icon=Train.ico --add-data "login-button-png-7.png;." --add-data "background_image_2.png;." --add-data "train.ico;." Attribution_tool_v19.py
问题排查与解决方案
1. 主程序资源路径未正确处理
登录界面用resource_path函数处理资源路径,但main_program类中如果用到图片、配置等外部文件,很可能没做同样处理,导致打包后无法找到资源,控件渲染失败。
- 把
resource_path函数复制到main_program所在模块,或封装成公共函数供所有模块调用,确保所有资源加载都通过该函数获取路径。
2. 主窗口Tk实例管理问题
登录界面创建self.root = Tk()并隐藏,传给main_program后,主程序可能未正确复用这个根实例:
- 检查
main_program的__init__方法,确保基于传入的root参数构建界面,先调用root.deiconify()显示根窗口,再添加控件,不要重新创建Tk()实例(Tkinter仅允许一个根实例)。
3. 控件引用被垃圾回收
Tkinter中,ImageTk.PhotoImage创建的图片若为局部变量,会被Python垃圾回收机制清理,导致控件空白。登录界面把图片绑定到self.my_img,但主程序可能没这么做:
- 主程序中所有图片对象都要绑定到实例属性(如
self.btn_img = ImageTk.PhotoImage(...)),避免被回收。
4. 打包命令遗漏依赖
打包时可能未包含main_program依赖的模块或资源:
- 若主程序有额外资源文件,添加对应的
--add-data参数; - 若PyInstaller未自动识别自定义模块(如
attribution_tool_main_program_class.py、config.py),在打包命令中加入--hidden-import attribution_tool_main_program_class --hidden-import config --hidden-import sql_uploader; - 暂时去掉
--windowed参数打包,运行.exe时查看控制台输出的错误信息,快速定位问题(如缺失模块或资源)。
内容的提问来源于stack exchange,提问作者Man_Like_Dave
相关产品推荐
相关产品推荐

