[英]How would I make a method which is run every time a frame is shown in tkinter
I have a gui application that has several windows and buttons to go forward and backward.我有一个 gui 应用程序,它有几个窗口和按钮可以前进和后退。 To do this I am using a controller and raising the frames to the top with each window change.
为此,我使用控制器并在每次窗口更改时将框架提升到顶部。 Here is my code for the controller and a typical frame.
这是我的控制器代码和典型框架。
import Tkinter as tk # python
from tkFileDialog import askopenfilename, asksaveasfilename
from analyzer import Options
TITLE_FONT = ("Helvetica", 18, "bold")
class TennisProgram(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
container = tk.Frame(self)
#Allow the window to be resized
# container.resizable(width=True, height=True)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
#List of options bundles. One bundle for each video
self.options_bundle_list = {}
self.frames = {}
#Init empty array to hold the list of files
#Placed in the container so that all views can access it
self.files = []
for F in (UploadPage, AnalysisOptionsPage, FormAnalysisOptions, MatchAnalysisOptions, MatchAnalysisOptionsPage2, OutputPage, ProcessingPage):
page_name = F.__name__
frame = F(container, self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
# Name the window
self.title("Tennis Analyzer")
self.show_frame("UploadPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class UploadPage(tk.Frame):
#TODO Add logic to remove a file path from the list
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.createView()
def createView(self):
label = tk.Label(self, text="Upload Videos for Analysis", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
#Listbox to display the list of files to be processed
self.path_list = tk.Listbox(self)
#Additional options allow listbox to expand as the window is resized
self.path_list.pack(fill=tk.BOTH ,expand=True)
for path in self.controller.files:
self.path_list.insert(tk.END, path)
add_vidoes_button = tk.Button(self, text="Add Videos",
command=self.choose_files)
continue_button = tk.Button(self, text="Continue",
command=lambda: self.controller.show_frame("AnalysisOptionsPage"))
add_vidoes_button.pack(side=tk.TOP)
continue_button.pack(side=tk.BOTTOM)
def choose_files_paths(self):
#don't want a full GUI, so keep the root window from appearing
#self.controller.withdraw()
#Get a file name from the user
filename = askopenfilename()
#Add it to the list of files to be processed
self.controller.files.append(filename)
self.path_list.insert(tk.END, filename)
The code that I write in init gets executed once and creates the view but I was wondering if it was possible to have a function which runs every time the frame got raised, similar to an onResume function in Android.我在 init 中编写的代码被执行一次并创建视图,但我想知道是否有可能有一个函数在每次帧上升时运行,类似于 Android 中的 onResume 函数。 I would want to do this in case some underlying data has changed like in this upload page.
我想这样做,以防某些基础数据已更改,如此上传页面中所示。 For example, what if an item is deleted from the array which populates the listview, I would want to be able to refresh it.
例如,如果从填充列表视图的数组中删除一个项目,我希望能够刷新它。
Tkinter has low level events such as <Visibility>
and <Map>
which should fire when the pages change. Tkinter 具有低级事件,例如
<Visibility>
和<Map>
,它们应该在页面更改时触发。 Unfortunately, these don't work reliably on all platforms.不幸的是,这些并不能在所有平台上可靠地工作。
The simplest and most robust solution is to generate your own event.最简单和最强大的解决方案是生成您自己的事件。 You can create and bind to a custom event by specifying the event inside
<<
and >>
(eg: <<ShowFrame>>
).您可以通过在
<<
和>>
指定事件来创建并绑定到自定义事件(例如: <<ShowFrame>>
)。
First, change show_frame
to send an event to a window when it is shown:首先,更改
show_frame
以在显示时向窗口发送事件:
def show_frame(self, page_name):
...
frame.event_generate("<<ShowFrame>>")
Next, each page can bind to this event if it needs to be notified when it is made visible:接下来,如果需要在使其可见时通知每个页面,则可以绑定到此事件:
class UploadPage(tk.Frame):
def __init__(self, parent, controller):
...
self.bind("<<ShowFrame>>", self.on_show_frame)
def on_show_frame(self, event):
print("I am being shown...")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.