Tkinter按钮动作

问题描述 投票:0回答:2

我有一个来自更大的脚本的以下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窗口,只要我单击按钮,脚本再次运行并开始使用新的更新数据更新当前窗口。

所以无论哪种方法来解决这个问题都很好。有什么建议?

python python-2.7 tkinter
2个回答
1
投票

基于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程序。我使用的模板非常类似于布莱恩的模板。


1
投票

不要破坏您的应用程序根窗口。如果销毁窗口,则无法再使用其子窗口小部件。使用Tk()创建一个根窗口,然后使用该窗口调用.mainloop()。然后使你想要一个Toplevel窗口。您可以关闭那个并随时重新创建它。

另外我不明白你为什么要再次运行你的整个脚本。你只想调用重新创建Toplevel的代码(也许是因为你没有Toplevel ...)

© www.soinside.com 2019 - 2024. All rights reserved.