Tkinter:如何在页面上显示带有按钮的页面?

时间:2019-07-15 20:43:57

标签: python tkinter

我正在为欺凌/滥用项目编写一个“热线”程序,共有4页:首页/欺凌/虐待/其他和顶部栏。我正在按按钮进入其他页面,但是每次都会有不同的错误。

我已经尝试过从页面和容器中执行提升命令,以及在其中编程的显示命令。两者均无效。 (顺便说一下,代码并非全部属于我,其中大部分是来自Caspar Wylie的问题Using buttons in Tkinter to navigate to different pages of the application?

import tkinter as tk

class Page(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
    def show(self):
        self.lift()

class Page1(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = tk.Label(self, text="Welcome to the Help Hotline! Please select your concern.", relief = 'groove')
       label.grid(row = 0, column = 1, columnspan = 3, sticky = 'nesw', padx = 5, pady = 5)

       bullybutton = tk.Button(self, text = "Bullying",  command = MainView.p2.lift)
       bullybutton.grid(row = 1, column = 1, padx = 5, pady = 5, sticky = 'nsew')

       abusebutton = tk.Button(self, text = "Abuse",  command = MainView.p3.lift)
       abusebutton.grid(row = 1, column = 2, padx = 5, pady = 5, sticky = 'nsew')

       otherbutton = tk.Button(self, text = "Other",  command = MainView.p4.lift)
       otherbutton.grid(row = 1, column = 3, padx = 5, pady = 5, sticky = 'nsew')

class Page2(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = tk.Label(self, text="This is page 2")
       label.grid(row = 0, column = 1, sticky = 'nesw', padx = 5, pady = 5)

class Page3(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = tk.Label(self, text="This is page 3")
       label.grid(row = 0, column = 1, sticky = 'nesw', padx = 5, pady = 5)

class Page4(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = tk.Label(self, text="This is page 4")
       label.grid(row = 0, column = 1, sticky = 'nesw', padx = 5, pady = 5)

class MainView(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        p1 = Page1(self)
        p2 = Page2(self)
        p3 = Page3(self)
        p4 = Page4(self)

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)

        p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p3.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p4.place(in_=container, x=0, y=0, relwidth=1, relheight=1)

        menubar = tk.Menu(root)
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Home", command=p1.lift)
        filemenu.add_command(label="Bullying", command=p2.lift)
        filemenu.add_command(label="Abuse", command=p3.lift)
        filemenu.add_command(label="Other", command=p4.lift)
        filemenu.add_separator()
        filemenu.add_command(label="Quit", command=exit)
        menubar.add_cascade(label="Navigate", menu=filemenu)

        root.config(menu=menubar)
        p1.show()


root = tk.Tk()
root.geometry('500x500')
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.title("Bullying and Abuse Hotline")
root.mainloop()

我希望有3个按钮,每个按钮都转到各自的页面,但我收到有关“无属性tk”或“缺少参数自变量”或根本没有变化的错误。

1 个答案:

答案 0 :(得分:1)

这是对代码的(相当专业的)重做,我认为它可以完成您想要的事情。您没有提供与Caspar Wylie的问题的链接,所以我大量借鉴了Bryan Oakley开创性的answer中显示的技术,该问题Switch between two frames in tkinter的作用非常相似,尽管没有菜单(但最后确实包含许多可能非常有用的链接)。

更新

我自己找到了Caspar Wylie的问题,并在您的问题中添加了链接,并对以下代码进行了一些修改,以使其与相关的答案更加一致(恰好也是Bryan编写的)。

import tkinter as tk


class MainView(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        container = tk.Frame(self)
        container.pack(side='top', fill='both', expand=True)

        # Create dictionary of page (Frame subclass) instances.
        self.pages  = {}
        for Page in (Home, Bullying, Abuse, Other):
            page = Page(container, controller=self)
            self.pages[Page.__name__] = page
            page.place(in_=container, x=0, y=0, relwidth=1, relheight=1)

        menubar = tk.Menu(parent)
        filemenu = tk.Menu(menubar, tearoff=0)

        def options(page_name, show=self.show):  # Helper func.
            return dict(label=page_name, command=lambda: show(page_name))

        filemenu.add_command(**options('Home'))
        filemenu.add_command(**options('Bullying'))
        filemenu.add_command(**options('Abuse'))
        filemenu.add_command(**options('Other'))

        filemenu.add_separator()
        filemenu.add_command(label='Quit', command=exit)
        menubar.add_cascade(label='Navigate', menu=filemenu)

        parent.config(menu=menubar)
        self.show('Home')  # Display initial page.

    def show(self, page_name):
        self.pages[page_name].lift()


class Home(tk.Frame):
   def __init__(self, parent, controller):
       super().__init__(parent)

       label = tk.Label(self, text='Welcome to the Help Hotline! '
                                   'Please select your concern.', relief='groove')
       label.grid(row=0, column=1, columnspan=3, sticky='nesw', padx=5, pady=5)

       def options(page_name, show=controller.show):  # Helper func.
           return dict(text=page_name, command=lambda: show(page_name))

       bully_button = tk.Button(self, **options('Bullying'))
       bully_button.grid(row = 1, column=1, padx=5, pady=5, sticky='nsew')

       abuse_button = tk.Button(self, **options('Abuse'))
       abuse_button.grid(row=1, column=2, padx=5, pady=5, sticky='nsew')

       other_button = tk.Button(self, **options('Other'))
       other_button.grid(row=1, column=3, padx=5, pady=5, sticky='nsew')


class Bullying(tk.Frame):
   def __init__(self, parent, controller):
       super().__init__(parent)

       label = tk.Label(self, text='This is page 2')
       label.grid(row=0, column=1, sticky='nesw', padx=5, pady=5)


class Abuse(tk.Frame):
   def __init__(self, parent, controller):
       super().__init__(parent)

       label = tk.Label(self, text='This is page 3')
       label.grid(row=0, column=1, sticky='nesw', padx=5, pady=5)


class Other(tk.Frame):
   def __init__(self, parent, controller):
       super().__init__(parent)

       label = tk.Label(self, text='This is page 4')
       label.grid(row=0, column=1, sticky='nesw', padx=5, pady=5)


root = tk.Tk()
root.geometry('500x500')
main = MainView(root)
main.pack(side='top', fill='both', expand=True)
root.title('Bullying and Abuse Hotline')
root.mainloop()