Python Tkinter按钮失灵

Python Tkinter按钮失灵,python,python-2.7,tkinter,Python,Python 2.7,Tkinter,我从一个更大的脚本中获得了以下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()]) butt

我从一个更大的脚本中获得了以下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回调中出现异常 回溯(最近一次呼叫最后一次): 文件“C:\ProgramData\Anaconda3\envs\python2\lib\lib tk\Tkinter.py”,第1541行,在调用中__ 返回self.func(*args) 文件“SatTracker.py”,第294行,在 button=tk.button(text='Refresh Data',width=25,command=lambda:[CloseWindow(),RefreshAction()]) 文件“C:/Users/Peter Kongstad/Dropbox/Geoscience/2.Masters/7.term/Delphini-1-Software Part/GUI/Programming/SatTracker.py”,第291行,关闭窗口 window.destroy() 文件“C:\ProgramData\Anaconda3\envs\python2\lib\lib tk\Tkinter.py”,第1864行,在destroy中 self.tk.call('destroy',self.\w) Tcl错误:无法调用“销毁”命令:应用程序已销毁 Tkinter回调中的异常 回溯(最近一次呼叫最后一次): 文件“C:\ProgramData\Anaconda3\envs\python2\lib\lib tk\Tkinter.py”,第1541行,在调用中__ 返回self.func(*args) 文件“C:/Users/Peter Kongstad/Dropbox/Geoscience/2.Masters/7.term/Delphini-1-Software Part/GUI/Programming/SatTracker.py”,第294行,在 button=tk.button(text='Refresh Data',width=25,command=lambda:[CloseWindow(),RefreshAction()]) 文件“C:/Users/Peter Kongstad/Dropbox/Geoscience/2.Masters/7.term/Delphini-1-Software Part/GUI/Programming/SatTracker.py”,第288行,正在运行 execfile(“SatTracker.py”) 文件“SatTracker.py”,第297行,在 window.mainloop() 文件“C:\ProgramData\Anaconda3\envs\python2\lib\lib tk\Tkinter.py”,第1129行,在mainloop中 self.tk.mainloop(n) 键盘中断 有效地阻止了一切。 现在,我不一定需要它来关闭旧的tkinter窗口,只要我单击按钮,脚本就会再次运行,并开始用新的更新数据更新当前窗口


所以我认为无论哪种方法都可以解决这个问题。有什么建议吗?

不要破坏应用程序根窗口。如果您破坏了一个窗口,它的子窗口小部件将无法再使用。使用
Tk()
创建一个根窗口,然后使用该窗口调用
.mainloop()
。然后将您想要的窗口设置为
顶级
窗口。您可以随时关闭该文件并重新创建它


我也不明白你为什么要再次运行整个脚本。您只需要调用重新创建顶级的代码(可能是因为您没有
Toplevel
…)

不要破坏您的应用程序根窗口。如果您破坏了一个窗口,它的子窗口小部件将无法再使用。使用
Tk()
创建一个根窗口,然后使用该窗口调用
.mainloop()
。然后将您想要的窗口设置为
顶级
窗口。您可以随时关闭该文件并重新创建它

我也不明白你为什么要再次运行整个脚本。您只需要调用重新创建顶级的代码(可能是因为您没有
Toplevel
…)

基于以下脚本,按下按钮时重新启动脚本:

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()
您可能还想了解如何构造tkinter程序。我使用的模板与Bryan的模板非常相似。

基于以下脚本,当按下按钮时,脚本将重新启动:

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()

您可能还想了解如何构造tkinter程序。我使用的模板与Bryan的模板非常相似。

您应该为按钮的
命令
选项定义一个方法。如果它需要调用多个方法,您所做的事情是不受欢迎的。我现在更新了它。很抱歉。我是python编程的新手。所以,如果我的方法不好,那是因为我不知道更好。如果你能告诉我更好的方法。然后无论如何,请执行=)可能重复的为什么要重新启动整个脚本?首先要做的是停止使用
lambda
。这对于某种类型的问题是好的,但这不是那种类型的问题。创建一个合适的函数,以便更容易地调试它。您应该为按钮的
命令
选项定义一个方法。如果它需要调用多个方法,则不赞成您所做的操作。我现在已经更新了它。很抱歉。我是python编程的新手。所以,如果我的方法不好,那是因为我不知道更好。如果你能告诉我更好的方法。然后无论如何,请执行=)可能重复的为什么要重新启动整个脚本?首先要做的是停止使用
lambda
。这对于某种类型的问题是好的,但这不是那种类型的问题。创建一个合适的函数,这样你就可以更容易地调试它。我需要重新启动整个程序,因为它从一个网站获得一个TLE代码,然后将该代码分解为更小的位,然后将其转换为精确的卫星当前纬度和经度坐标。然后将这些长/纬度坐标投影到3D地球仪和2D地图上,显示其当前位置。然后,我用谷歌Chrome浏览器驱动程序运行这些坐标,打开一个实时天气图和谷歌地球,用这些坐标捕捉图像,并根据long/lat。最后,所有这些图像都被裁剪、调整大小并整齐地隐藏到一个Tkinter中。你不需要重复你的评论。评论