简体   繁体   English

我将如何制作每次在 tkinter 中显示帧时运行的方法

[英]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.

相关问题 我已经将tkinter窗口划分为单元格(使用框架)。 如何定义适用于每个单元的方法? - I've divided a tkinter window into cells (using frame). How do I define a method that would apply to every cell? 如何在tkinter中使用destroy()方法处理我的代码? - How would I make destroy() method in tkinter work with my code? 我如何将这个计时器变成每秒更新的 function? - How would I make this timer into a function which updates every second? 如何每次在 tkinter 循环中制作新标签? - How do I make a new label every time in a loop in tkinter? 使用 Python 和 Tkinter,我将如何运行 .mainloop() 的每个循环的代码? - Using Python and Tkinter, How would I run code every loop of .mainloop()? 每次运行程序时,都没有正确显示Python Curses窗口 - Python Curses windows are not shown properly every time I run the program 每次单击时如何使 tkinter 按钮更改颜色 - How do I make a tkinter button change colors every time I click it 如何在python中使Tkinter在一定时间内完成每个代码? - How can I make Tkinter in python to do every code in certain amount of time? 每次在 tkinter 中按下按钮时,如何创建一个将列增加 1 的函数? - How do I make a function that increases the column by 1 every time a button is pressed in tkinter? 如何让 Tkinter 运行可执行文件? - How do I make Tkinter run an executable?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM