我有一个来自更大的脚本的以下python 2.7代码段代码。
def RefreshAction():
execfile("SatTracker.py")
def CloseWindow():
window.destroy()
button = tk.Frame(window)
button = tk.Button(text='Refresh Data', width=25,command=lambda:[CloseWindow(),RefreshAction()])
button.pack()
window.mainloop()
所以我的整个代码生成了一个包含图像,文本和按钮的tkinter窗口。现在按钮应该触发命令关闭Tkinter窗口,然后重新运行整个脚本,它就可以了。当我再次单击刷新按钮时,会发生奇怪的事情。窗口不再关闭,但脚本仍然启动,但是出现此错误。
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\envs\python2\lib\lib-tk\Tkinter.py", line 1541, in __call__
return self.func(*args)
File "SatTracker.py", line 294, in <lambda>
button = tk.Button(text='Refresh Data', width=25,command=lambda:[CloseWindow(),RefreshAction()])
File "C:/Users/Peter Kongstad/Dropbox/Geoscience/2. Masters/7. Semester/Delphini-1 - Software Part/GUI/Programming/SatTracker.py", line 291, in CloseWindow
window.destroy()
File "C:\ProgramData\Anaconda3\envs\python2\lib\lib-tk\Tkinter.py", line 1864, in destroy
self.tk.call('destroy', self._w)
TclError: can't invoke "destroy" command: application has been destroyed
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\envs\python2\lib\lib-tk\Tkinter.py", line 1541, in __call__
return self.func(*args)
File "C:/Users/Peter Kongstad/Dropbox/Geoscience/2. Masters/7. Semester/Delphini-1 - Software Part/GUI/Programming/SatTracker.py", line 294, in <lambda>
button = tk.Button(text='Refresh Data', width=25,command=lambda:[CloseWindow(),RefreshAction()])
File "C:/Users/Peter Kongstad/Dropbox/Geoscience/2. Masters/7. Semester/Delphini-1 - Software Part/GUI/Programming/SatTracker.py", line 288, in RefreshAction
execfile("SatTracker.py")
File "SatTracker.py", line 297, in <module>
window.mainloop()
File "C:\ProgramData\Anaconda3\envs\python2\lib\lib-tk\Tkinter.py", line 1129, in mainloop
self.tk.mainloop(n)
KeyboardInterrupt
有效地阻止一切。现在我不一定需要它来关闭旧的tkinter窗口,只要我单击按钮,脚本再次运行并开始使用新的更新数据更新当前窗口。
所以无论哪种方法来解决这个问题都很好。有什么建议?
基于this answer & comments,以下脚本在按下按钮时重新启动脚本:
import os
import sys
import tkinter as tk
window = tk.Tk()
def restart():
#CloseWindow()
RefreshAction()
def RefreshAction():
os.execl(sys.executable, *([sys.executable]+sys.argv))
def CloseWindow():
window.destroy()
#quit()
button = tk.Frame(window)
button = tk.Button(text='Refresh Data', width=25,command=restart)
button.pack()
window.mainloop()
虽然在我的最后它出现错误,因为我的用户名中有空格。总而言之,你应该像下面的代码一样,除非你有全局变量或者其他东西:
import tkinter as tk
def restart(root):
CloseWindow(root)
RefreshAction()
def RefreshAction():
main()
def CloseWindow(root):
root.destroy()
def main():
window = tk.Tk()
button = tk.Frame(window)
button = tk.Button(text='Refresh Data', width=25,
command= lambda arg=window: restart(arg))
button.pack()
window.mainloop()
main()
你也许想看看this question & answers关于如何构建你的tkinter程序。我使用的模板非常类似于布莱恩的模板。
不要破坏您的应用程序根窗口。如果销毁窗口,则无法再使用其子窗口小部件。使用Tk()
创建一个根窗口,然后使用该窗口调用.mainloop()
。然后使你想要一个Toplevel
窗口。您可以关闭那个并随时重新创建它。
另外我不明白你为什么要再次运行你的整个脚本。你只想调用重新创建Toplevel的代码(也许是因为你没有Toplevel
...)