在tkinter中切换帧时如何更新/刷新窗口小部件?

在tkinter中切换帧时如何更新/刷新窗口小部件?,tkinter,Tkinter,我有一个gui应用程序,其中导航栏有按钮在帧之间切换。在startpage上有一个获取文件名的条目小部件和一个显示所有保存文件名的列表框。从列表框中选择文件名后,将打开另一个页面,其中显示所选文件名 我相信答案是在开始时创建帧对象,将它们堆叠起来,并提升调用的帧。但我认为我的窗口需要在每次调用时更新,以便显示不同的文件名。此外,它被放置在与其他框架完全相同的位置,以便我仍然可以使用导航栏按钮切换到其他主窗口和其他窗口。我发现了类似的东西,但我无法理解 我的acutal应用程序比这个复杂一些,但我

我有一个gui应用程序,其中导航栏有按钮在帧之间切换。在startpage上有一个获取文件名的条目小部件和一个显示所有保存文件名的列表框。从列表框中选择文件名后,将打开另一个页面,其中显示所选文件名

我相信答案是在开始时创建帧对象,将它们堆叠起来,并提升调用的帧。但我认为我的窗口需要在每次调用时更新,以便显示不同的文件名。此外,它被放置在与其他框架完全相同的位置,以便我仍然可以使用导航栏按钮切换到其他主窗口和其他窗口。我发现了类似的东西,但我无法理解

我的acutal应用程序比这个复杂一些,但我认为这是我问题的一个小而精确的表示

编辑:

多屏幕 从tkinter进口* 类屏幕框: 屏幕是一个区域 对于程序中的内容 定义初始自我,主控,名称: 帧。初始帧自身,主帧 属性 self.master=master self.name=name 与主人初始化 self.master.addScreenself def showself: 方法将显示屏幕 self.master.showScreenself.name 类screenControllerFrame: 屏幕控制器 将管理屏幕 节目中 定义初始自我,父级: 帧。初始帧自身,父帧 配置 self.grid\u rowconfigure0,权重=1 self.grid\u column配置0,权重=1 属性 self.allScreens={} self.currentScreen=None def addScreenself,屏幕对象: 将屏幕对象添加到screenController 放置屏幕 screenObject.gridrow=0,column=0,sticky=nsew 添加到字典 self.allScreens[screenObject.name]=screenObject def showScreenself,屏幕名称: 如果self.allScreens中有screenName: 陈列 self.allScreens[screenName].tkraise 更新变量 self.currentScreen=屏幕名称 创建一个Tkinter窗口 窗口=Tk window.Title多个屏幕 window.geometry400x300 window.columnconfigure0,权重=1 window.rowconfigure1,权重=1 为屏幕创建一个控制器 screenMaster=screenControllerwindow screenMaster.gridrow=1,column=0,sticky=NSEW 创建屏幕1 screen1=屏幕管理员,S1 Labelscreen1,text=这是屏幕1。gridrow=0,column=0 屏幕1.configbg=红色 创建屏幕2 screen2=屏幕管理员,S2 Labelscreen2,text=这是屏幕2。gridrow=0,column=0 屏幕2.configbg=蓝色 创建屏幕3 screen3=屏幕管理员,S3 Labelscreen3,text=这是屏幕3。gridrow=0,column=0 屏幕3.configbg=绿色 创建一个导航栏 navBar=Framewindow navBar.gridrow=0,column=0,sticky=EW navBar.configbg=F1F0F2 b1=ButtonnavBar,text=Screen 1,command=lambda:Screen 1.show b1.gridrow=0,column=0 b1=按钮nNAVBAR,文本=屏幕2,命令=lambda:screen2.show b1.gridrow=0,column=1 b1=按钮nNAVBAR,文本=屏幕3,命令=lambda:screen3.show b1.gridrow=0,column=2 默认情况下显示屏幕1 屏幕1.show window.mainloop 这就是我使用OO编程来解决这个问题的方法,无论你在哪个屏幕上,导航栏都会保持静态,只需将屏幕相互抬高,你就不需要不断创建新对象并节省大量内存

这个解决方案也是非常模块化的,只允许您添加屏幕,就像它们是Tkinter帧一样

多屏幕 从tkinter进口* 类屏幕框: 屏幕是一个区域 对于程序中的内容 定义初始自我,主控,名称: 帧。初始帧自身,主帧 属性 self.master=master self.name=name 与主人初始化 self.master.addScreenself def showself: 方法将显示屏幕 self.master.showScreenself.name 类screenControllerFrame: 屏幕控制器 将管理屏幕 节目中 定义初始自我,父级: 帧。初始帧自身,父帧 配置 self.grid\u rowconfigure0,权重=1 self.grid\u column配置0,权重=1 属性 self.allScreens={} self.currentScreen=None def addScreenself,屏幕对象: 将屏幕对象添加到screenController 放置屏幕 screenObject.gridrow=0,column=0,sticky=nsew 添加到字典 self.allScreens[screenObject.name]=screenObject def showScreenself,屏幕名称: 如果self.allScreens中有screenName: 陈列 self.allScreens[screenName].tkraise 更新变量 self.currentScreen=屏幕名称 创建一个Tkinter窗口 窗口=Tk window.Title多个屏幕 window.geometry400x300 window.columnconfigure0,权重=1 window.rowconfigure1,权重=1 为屏幕创建一个控制器 screenMaster=screenControllerwindow screenMaster.gridrow=1,column=0,sticky=NSEW 创建屏幕1 screen1=屏幕管理员,S1 Labelscreen1,text=这是屏幕1。gridrow=0,column=0 屏幕1.configbg=红色 创建屏幕2 screen2=屏幕管理员,S2 Labelscreen2,text=这是屏幕2。gridrow=0,column=0 屏幕2.configbg=蓝色 创建屏幕3 screen3=屏幕管理员,S3 Labelscreen3,text=这是屏幕3。gridrow=0,column=0 屏幕3.configbg=绿色 创建一个导航栏 navBar=Framewindow navBar.gridrow=0,column=0,sticky=EW navBar.configbg=F1F0F2 b1=ButtonnavBar,text=Screen 1,command=lambda:Screen 1.show b1.gridrow=0,column=0 b1=按钮nNAVBAR,文本=屏幕2,命令=lambda:screen2.show b1.gridrow=0,column=1 b1=按钮nNAVBAR,文本=屏幕3,命令=lambda:screen3.show b1.gridrow=0,column=2 默认情况下显示屏幕1 屏幕1.show window.mainloop 这就是我使用OO编程来解决这个问题的方法,无论你在哪个屏幕上,导航栏都会保持静态,只需将屏幕相互抬高,你就不需要不断创建新对象并节省大量内存

这个解决方案也是非常模块化的,只允许您添加屏幕,就像它们是Tkinter帧一样。

问题:每次我想从StartPage转到PageOne时,如何传递所选的文件名

核心要点:

重载类methode Frame.tkraise,以便在每次从控制器调用.tkraise时更新PageOne小部件

注意:我只显示示例代码的更改部分,仔细比较并复制到实际代码中

类MainApplicationtk.Tk中没有更改:

类StartPagetk.Frame:

类PageOneTek.框架:

备选方案:

问题:每次我想从StartPage转到PageOne时,如何传递所选的_文件名

核心要点:

重载类methode Frame.tkraise,以便在每次从控制器调用.tkraise时更新PageOne小部件

注意:我只显示示例代码的更改部分,仔细比较并复制到实际代码中

类MainApplicationtk.Tk中没有更改:

类StartPagetk.Frame:

类PageOneTek.框架:

备选方案:


相关@stovfl您建议的答案很好,但我有一个问题,据我所知,发生的情况是框架堆叠在一起,然后按照堆叠顺序将一个提升到另一个之上。然而,在我的应用程序中,我想要的是,当我从窗口2切换回窗口1时,该窗口的内容将被更新或刷新,并且不再像以前一样。你知道我该怎么做吗?@stovfl我已经添加了代码…我不知道每次我想从StartPageRelevant@stovfl转到PageOne时如何传递所选的文件名。你建议的答案很好,但我有一个问题,据我所知,发生的情况是帧堆叠在彼此的顶部,然后简单地按堆叠顺序将一个提升到另一个之上。然而,在我的应用程序中,我想要的是,当我从窗口2切换回窗口1时,该窗口的内容将被更新或刷新,并且不再像以前一样。你知道我该怎么做吗?@stovfl我已经添加了代码…每次我想从StartGetHanks转到PageOne时,我都不知道如何传递所选的文件名!终于学会了如何解决这个问题,非常感谢!终于学会了如何解决这个问题
import tkinter as tk

class MainApplication(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(1, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames={}
        for F in (StartPage,PageOne):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame
            frame.grid(row=1, column=0, sticky="nsew")

        self.show_frame("StartPage")

    def show_frame(self, page_name):
        frame = self.frames[page_name]
        frame.tkraise()


class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        self.list_box = tk.Listbox(self)
        self.list_box.pack()
        for item in ["file 1", "file 2", "file 3"]:
            self.list_box.insert(tk.END, item)
        button1 = tk.Button(self, text='Go to next Page', command=lambda: self.getvalue(controller))
        button1.pack()

    def getvalue(self, controller):
        clicked_item=self.list_box.curselection()
        selected_file=self.list_box.get(clicked_item)
        print(selected_file)
        controller.show_frame('PageOne')

class PageOne(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        # ....selected file name to be displayed here....
        button1 = tk.Button(self, text="Back to Home", command=lambda: controller.show_frame('StartPage'))
        button1.pack()


app = MainApplication()
app.geometry("400x400")
app.mainloop()

class MainApplication(tk.Tk):
   ...
class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        ...
        .Button(..., command=lambda: controller.show_frame('PageOne'))

    def getvalue(self):
        ...
        return selected_file

class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        # ....selected file name to be displayed here....
        self.label = tk.Label(self, text='')
        self.label.pack()

    def tkraise(self, aboveThis=None):
        # Get a reference to StartPage
        start_page = self.controller.frames['StartPage']

        # Get the selected item from start_page
        self.label.configure(text=start_page.getvalue())

        # Call the real .tkraise
        super().tkraise(aboveThis)