【问题标题】:Tkinter: How to show next frame in tupleTkinter:如何在元组中显示下一帧
【发布时间】:2019-03-30 04:18:59
【问题描述】:

我正在尝试为 tkinter 按钮编写一个方法,该方法将遍历帧元组并在我单击下一个按钮时显示下一帧。目标是编写函数,这样我只需将“self”(对于当前可见的框架对象)作为参数传递。

我已经浏览了一些示例,这些示例允许我通过将新框架作为参数传递给函数来切换到新框架。我目前已经按照这些思路实施了一些措施作为权宜之计,直到我找到解决当前问题的方法。我不确定要包含多少代码,但我已经将它配对,以便它仍然可以正常运行,并且问题最少。

App.next_frame() 中的元组 App.frames 和 else 块是问题区域。

class App(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)
        self.master = master
        self.pack()

        #### Add any new pages to this tuple ####
        self.frames = (StartPage, Page2)
        self.current_frame = None
        self.next_frame(self.current_frame)

    def next_frame(self, cframe_class):
        '''Set the visible page to the next frame in the frames tuple.
        Pass self to the cframe_class argument'''
        if self.current_frame == None:
            '''If the application has just started, this block will run
            in order to set the current frame to the start page.'''
            self.current_frame = StartPage(self)
            self.current_frame.pack()
        else:         ##### Problem #####
            cfi = self.frames.index(cframe_class)
            #### "ValueError: tuple.index(x): x not in tuple" ####
            cfi += 1
            self.current_frame.destroy()
            self.current_frame = self.frames[cfi]
            self.current_frame.pack()

class StartPage(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)
        tk.ttk.Button(self, text = "Test Next",
                        command = lambda: master.next_frame(self)).pack()

class Page2(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)
        tk.ttk.Label(self, text = "This is Page 2").pack()

def main():
    root = tk.Tk()
    app = App(root)
    app.mainloop()    #app.mainloop() or root.mainloop()?

if __name__ == "__main__":
    main()

调试器在 cfi 变量行抛出 "ValueError: tuple.index(x): x not in tuple"。当我在单击下一个按钮后单步执行该函数时,调试器告诉我我的参数“cframe_class”的 id 为:

<__main__.StartPage object .!app.!startpage>

我理解该行的第一部分,但我不确定如何解释 object.!app.!startpage> 部分。看起来应该这样读:“Startpage 是一个继承自 NOTapp、NOTstartpage 的对象”,但我不明白为什么会这样。

我的元组中的 StartPage 对象的 id 为:

<class '__main__.StartPage'>

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    也许您可以使用存储为属性的索引来跟踪当前帧,而不是传递参数。

    import tkinter as tk
    from tkinter import ttk
    
    class App(tk.Frame):
        def __init__(self, master = None):
            super().__init__(master)
            self.master = master
            self.pack()
            self.cfi = 0
            #### Add any new pages to this tuple ####
            self.frames = (StartPage(self), Page2(self))
            self.current_frame = None
            self.next_frame()
    
        def next_frame(self):
            '''Set the visible page to the next frame in the frames tuple.
            Pass self to the cframe_class argument'''
            if self.cfi == 0:
                '''If the application has just started, this block will run
                in order to set the current frame to the start page.'''
                self.current_frame = self.frames[0]
                self.current_frame.pack()
                self.cfi +=1
            else:
                self.current_frame.pack_forget()
                try:
                    self.current_frame = self.frames[self.cfi]
                except IndexError:
                    self.current_frame = self.frames[0]
                    self.cfi = 0
                self.current_frame.pack()
                self.cfi += 1
    
    class StartPage(tk.Frame):
        def __init__(self, master = None):
            super().__init__(master)
            tk.Button(self, text = "Test Next", command = master.next_frame).pack()
    
    class Page2(tk.Frame):
        def __init__(self, master = None):
            super().__init__(master)
            tk.Button(self, text = "This is Page 2",command=master.next_frame).pack()
    
    def main():
        root = tk.Tk()
        app = App(root)
        app.mainloop()    #app.mainloop() or root.mainloop()?
    
    if __name__ == "__main__":
        main()
    

    【讨论】:

    • 嘿亨利,感谢您的回复和解决方案。我想我也能够从您的代码中找出为什么我会在名称不匹配的地方收到错误。我创建的元组只包含基类的名称,而不是像您在解决方案中那样实例化类的对象:StartPage(self)。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2018-10-18
    • 2018-11-28
    • 2020-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多