Atristamez
Atristamez

Reputation: 31

Python tkinter - Compilation is successful but program runs incorrectly when compiled as an Exe

So I created a sort of calculator using tkinter and have made it so that a quick setup creates a save.dat file in the AppData directory and this works as a python script, however when compiled using the line:
pyinstaller --onefile -w file.py it does not work. The exe runs the setup process just fine, but it seems, after some testing, when it reaches the end of the if statement, if save.dat already exists (a dialog box appears and there's a do not show again tick box and an OK button), it does not wait for a response and shuts down. I get a glimpse of it as a background process when I check taskmanager, but no window ever appears. I don't understand what the issue is so I could use some help. Here is a snip of my code:

from tkinter import *
from tkinter import messagebox
import pickle
import os.path
import sys

def saving():
    messagebox.showinfo("Setting Up", "Setup will now begin")
    path = os.path.expanduser("~/AppData/Local")
    os.chdir(path)
    os.makedirs("hydrocalc")
    loc = os.path.expanduser("~/AppData/Local/hydrocalc/save.dat")
    new = "0"
    pickle.dump(new, open(loc, "wb"))
    
popup = Tk()
popup.withdraw()
loc = os.path.expanduser("~/AppData/Local/hydrocalc/save.dat")
if (os.path.exists(loc)):
    i = pickle.load(open(loc, "rb"))
    # then a few variables referring to the calculator
   def world():
       #the functions referring to the calculator
      if (i == "0"):
        popup.deiconify()
        popup["bg"] = "#f0f0f0"
        popup.title("INSTRUCTIONS")
        labelpu = Label(popup, bg="white", text= #instructions on usage, justify="left").grid()
        popup.resizable(width=False, height=False)
        var = StringVar()
        check = Checkbutton(popup, text="Don't Show Again", variable=var, onvalue="1", offvalue="0", 
        bg="#f0f0f0")
        check.deselect()
        check.grid()
        lbl = Label(popup, text=var.get())

        def btnOkay():
            global i
            lbl = Label(popup, text=var.get())
            if (var.get() == "0"):
                popup.withdraw()
                i = "1"
                calc.deiconify()
                world()
            
            elif (var.get() == "1"):
                
                info = open(loc, 'w+')
                new = "1"
                pickle.dump(new, open(loc, "wb"))
                popup.withdraw()
                calc.deiconify()
                i = "1"
                world()
        popup.deiconify()
        btnOK = Button(popup, text="OK", bg="#f0f0f0", justify="center", width=20, 
        command=lambda:btnOkay()).grid()
    elif (i == "1"):
        calc.deiconify()
        world()
else:
    saving()
    messagebox.showinfo("Setup Complete", "Setup is now complete. Please restart the program to 
    continue.")
    sys.exit()

Upvotes: 2

Views: 241

Answers (1)

astqx
astqx

Reputation: 2096

There a couple of changes to be made, refer to the updated code below

from tkinter import *
from tkinter import messagebox
import pickle
import os.path
import sys

def saving():
    messagebox.showinfo("Setting Up", "Setup will now begin")
    path = os.path.expanduser(appdata)
    os.chdir(path)
    os.makedirs(appdir)
    loc = os.path.expanduser(pref_file)
    new = "0"
    pickle.dump(new, open(loc, "wb"))
    
popup = Tk()
popup.withdraw()

appdata=os.getenv('APPDATA') #modified for my convenience
appdir=os.path.join(appdata,'MyApp')
pref_file=os.path.join(appdir,'pref.pickle')
loc = os.path.expanduser(pref_file)

if (os.path.exists(loc)):

    def world():
        #the functions referring to the calculator
        if (i == "0"):
            popup.deiconify()
            popup["bg"] = "#f0f0f0"
            popup.title("INSTRUCTIONS")
            labelpu = Label(popup, bg="white", text='instructions on usage', justify="left").grid()
            popup.resizable(width=False, height=False)
            var = StringVar()
            check = Checkbutton(popup, text="Don't Show Again", variable=var, onvalue="1", offvalue="0", 
            bg="#f0f0f0")
            check.deselect()
            check.grid()
            lbl = Label(popup, text=var.get())
            btnOK = Button(popup, text="OK", bg="#f0f0f0", justify="center", width=20,command=lambda:btnOkay()).grid()
            def btnOkay():
                global i
                lbl = Label(popup, text=var.get())
                if (var.get() == "0"):
                    popup.withdraw()
                    i = "1"
                    #calc.deiconify()
                    print('deiconified calc') #added for debugging
                
                elif (var.get() == "1"):
                    
                    info = open(loc, 'w+')
                    new = "1"
                    pickle.dump(new, open(loc, "wb"))
                    popup.withdraw()
                    #calc.deiconify()
                    print('deiconified calc') #added for debugging
                    i = "1"
                    world()
                    popup.deiconify()

        elif i == "1":
            #calc.deiconify() commented for debugging
            print('deiconified calc')
            exit() #added for debugging

    i = pickle.load(open(loc, "rb"))
    world()

else:
    saving()
    messagebox.showinfo("Setup Complete", "Setup is now complete. Please restart the program to continue.")
    sys.exit()

popup.mainloop()

NOTES

  • You did not have a mainloop() for your program, due to which your window would have never shown up.
  • There was no initial call to the world() function in the if condition.
  • Don't call world() from the elif i == "1": condition, it will lead to infinite recursion.

I still am not completely clear with as to what exactly do you wanted to achieve, let me know if my code met your requirement. Hope it helped.

Upvotes: 2

Related Questions