Tkinter: как показать следующий кадр в кортеже - PullRequest
0 голосов
/ 30 марта 2019

Я пытаюсь написать метод для кнопки tkinter, который будет перебирать ряд кадров и отображать следующий кадр всякий раз, когда я нажимаю следующую кнопку. Цель состоит в том, чтобы написать функцию так, чтобы мне приходилось только передавать «self» (для текущего видимого объекта кадра) в качестве аргумента.

Я уже просмотрел несколько примеров, которые позволяют мне переключиться на новый кадр, передав его в качестве аргумента функции. В настоящее время я реализовал что-то в этом духе в качестве временного промежутка, пока не смогу найти решение текущей проблемы. Я не был уверен, сколько кода включить, но я спарил его так, чтобы он все еще работал с минимальными проблемами.

Кортеж App.frames и блок else в App.next_frame () являются проблемными областями.

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()

Отладчик выбрасывает «ValueError: tuple.index (x): x not in tuple» в строке переменной cfi. Когда я нажимаю на следующую кнопку после перехода к следующей функции, отладчик сообщает, что мой аргумент "cframe_class" имеет идентификатор:

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

Я понимаю первую часть строки, но не знаю, как интерпретировать объект .! App.! Startpage> . Похоже, это следует читать: «Стартовая страница - это объект, который наследуется от NOTapp, NOTstartpage», но я не понимаю, почему это так.

Объект StartPage в моем кортеже имеет идентификатор:

<class '__main__.StartPage'>

1 Ответ

1 голос
/ 30 марта 2019

Возможно, вы можете использовать индекс, хранящийся в качестве атрибута, чтобы отслеживать текущий кадр, вместо передачи аргумента.

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...