Home > Enterprise >  Images not displaying after compiling .exe
Images not displaying after compiling .exe

Time:12-19

Was finally able to get images to display properly in my .py file, with correct sizing and whatnot. Now, my issue is that they don't display at all after compiling with pyinstaller.

  • The images show up in the temp directory and I can navigate to it and open them.
  • The program will correctly print the location of the images.
  • The program will correctly print the images' information like dimensions

I'm not sure what I'm doing wrong.

Traceback:

Traceback (most recent call last):
File "tkinter\__init__.py", line 1921, in __call__
File "Tools\Cable_Resistance_Calculator\cable_resistance_calculator.py",
line 109, in max_power
File "customtkinter\windows\widgets\ctk_label.py",
line 93, in __init__ 
self._update_image()
File "customtkinter\windows\widgets\ctk_label.py",
line 130, in _update_image
self._label.configure(image=self._image.create_scaled_photo_image(self._get_widget_scaling(), File "tkinter\__init__.py",
line 1675, in configure
File "tkinter\__init__.py",
line 1665, in _configure _tkinter.TclError: image "pyimage1" doesn't exist  

Code:

import sys, os
import customtkinter as tk
import tkinter.ttk as ttk
#
def resource_path(relative_path):
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.dirname(os.path.realpath(__file__))
    return os.path.join(base_path, relative_path)
#
def init(top, gui, *args, **kwargs):
    global w, top_level, root
    w = gui
    top_level = top
    root = top
#
def destroy_window():
    # Function which closes the window.
    global top_level
    top_level.destroy()
    top_level = None
#
def vp_start_gui():
    '''Starting point when module is the main routine.'''
    global val, w, root
    root = tk.CTk()
    top = crc_main_window (root)
    init(root, top)
    root.mainloop()
#
w = None
def create_crc_main_window(rt, *args, **kwargs):
    global w, w_win, root
    root = rt
    w = tk.CTkToplevel (root)
    top = crc_main_window (w)
    init(w, top, *args, **kwargs)
    return (w, top)
#
def destroy_crc_main_window():
    global w
    w.destroy()
    w = None
#
class crc_main_window:
    def __init__(self, top=None):
        '''This class configures and populates the toplevel window.
           top is the toplevel containing window.'''
        _bgcolor = '#d9d9d9'  # X11 color: 'gray85'
        _fgcolor = '#000000'  # X11 color: 'black'
        _compcolor = '#d9d9d9' # X11 color: 'gray85'
        _ana1color = '#d9d9d9' # X11 color: 'gray85'
        _ana2color = '#ececec' # Closest X11 color: 'gray92'
        # setting geometry and locking it in, as well as the title
        top.geometry("392x300 607 367")
        top.minsize(120, 1)
        top.maxsize(3604, 1061)
        top.resizable(0,  0)
        top.title("Cable Resistance Calculator")
        top.configure(background="#d9d9d9")
        #
        def max_power():
            #
            self.max_power_top = tk.CTkToplevel(root)
            #
            self.max_power_top.title("Max Power Transmission")
            #
            self.max_power_top.geometry("592x313 607 367")
            self.max_power_top.resizable(0, 0)
            #
            self.max_frame = tk.CTkFrame(self.max_power_top)
            # 
            self.max_frame.place(x=3,y=3,width=586,height=307)
            # 
            from PIL import ImageTk, Image
            self.image1 = Image.open(resource_path('max_power_trans.PNG'))
            self.image = tk.CTkImage(self.image1, size=(580,301))
            self.label1 = tk.CTkLabel(master=self.max_frame,image=self.image)
            self.label1.image=self.image
            self.label1.place(x=3,y=3,width=583,height=304)
            self.label1.configure(text="")
        def power_calc():
            self.power_calc_top = tk.CTkToplevel(root)
            self.power_calc_top.title("Power Calculation Reference")
            self.power_calc_top.geometry("922x481 607 367")
            self.power_calc_top.resizable(0, 0)
            #
            self.power_frame = tk.CTkFrame(self.power_calc_top)
            self.power_frame.place(x=3,y=3,width=916,height=475)
            #
            from PIL import ImageTk, Image
            self.image2 = Image.open(resource_path('power_calc.png'))
            self.image3 = tk.CTkImage(self.image2, size=(910,469))
            self.label2 = tk.CTkLabel(self.power_frame,image=self.image3)
            self.label2.image=self.image3
            self.label2.place(x=3,y=3,width=913,height=472)
            self.label2.configure(text="")
        #
        from tkinter import Menu
        menubar = Menu(top)
        top.config(menu=menubar)
        file_menu = Menu(menubar,tearoff=False)
        file_menu.add_command(label='Max Power Reference',command=max_power)
        file_menu.add_command(label='Power Calc Reference',command=power_calc)
        file_menu.add_command(label='Exit',command=root.destroy)
        menubar.add_cascade(label="File",menu=file_menu,underline=0)

if __name__ == '__main__':
    vp_start_gui()

Compiler code:

import PyInstaller.__main__ as pym
pym.run([
    'main_hub.py',
    '--onefile',
    '--console',
    '--noconfirm',
    '--add-data=compile\\lib\\site-packages\\customtkinter\\;customtkinter\\',
    '--add-data=Tools\\Cable_Resistance_Calculator\\max_power_trans.PNG;.',
    '--add-data=Tools\\Cable_Resistance_Calculator\\power_calc.png;.',
])

Update: I've also tried in --onedir mode, and with a hardcoded path to the image files. Neither have worked so far.

CodePudding user response:

So I took my minimum reproducer code and created a new .py file with it, and tested it to find it worked perfectly fine. So what gives?

Well, as it turns out...I did in fact have another CTk() window. This script is part of a larger program that had already called root = tk.CTk(), so I already had an existing root window. I changed up the way the main program calls this script, and now it works.

  • Related