Python tkinter - 编译成功但编译为 Exe 时程序运行不正确
Python tkinter - Compilation is successful but program runs incorrectly when compiled as an Exe
所以我使用 tkinter 创建了一种计算器,并且已经做到了这样一个快速设置会在 AppData 目录中创建一个 save.dat 文件,它作为一个 python 脚本工作,但是在编译时使用行:
pyinstaller --onefile -w file.py
这是行不通的。 exe
运行设置过程就好了,但似乎经过一些测试,当它到达 if 语句的末尾时,如果 save.dat 已经存在(出现一个对话框并且没有显示再次勾选框和 OK 按钮),它不会等待响应并关闭。当我检查 taskmanager 时,我瞥见它是一个后台进程,但没有 window 出现。我不明白问题出在哪里,所以我需要一些帮助。这是我的代码片段:
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()
有几处需要修改,请参考下面的更新代码
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()
注释
- 您的程序没有
mainloop()
,因此您的 window 永远不会出现。
- 在
if
条件下没有对 world()
函数的初始调用。
- 不要在
elif i == "1":
条件下调用world()
,会导致无限递归。
我仍然不完全清楚你到底想实现什么,如果我的代码满足你的要求,请告诉我。希望对您有所帮助。
所以我使用 tkinter 创建了一种计算器,并且已经做到了这样一个快速设置会在 AppData 目录中创建一个 save.dat 文件,它作为一个 python 脚本工作,但是在编译时使用行:
pyinstaller --onefile -w file.py
这是行不通的。 exe
运行设置过程就好了,但似乎经过一些测试,当它到达 if 语句的末尾时,如果 save.dat 已经存在(出现一个对话框并且没有显示再次勾选框和 OK 按钮),它不会等待响应并关闭。当我检查 taskmanager 时,我瞥见它是一个后台进程,但没有 window 出现。我不明白问题出在哪里,所以我需要一些帮助。这是我的代码片段:
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()
有几处需要修改,请参考下面的更新代码
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()
注释
- 您的程序没有
mainloop()
,因此您的 window 永远不会出现。 - 在
if
条件下没有对world()
函数的初始调用。 - 不要在
elif i == "1":
条件下调用world()
,会导致无限递归。
我仍然不完全清楚你到底想实现什么,如果我的代码满足你的要求,请告诉我。希望对您有所帮助。