How to open and close another window with scrollba

2019-08-04 06:01发布

问题:

I want to build a Tkinter app in python 3.5. with a StartPage and a another window PageTwo that includes a table with a scolldownbar. I have tried to apply a framework from an online tutorial and the listbox example from another website.

My problem is: when I run the program both pages are loaded directly. How can I manage to let PageTwo only open on click on Button in StartPage, and then apply another button in PageTwo that closed PageTwo again and redirects to StartPage?

Second question: Alternatively to the listbox example I would like to use canvas with scrollbar on PageTwo. But how and where do I have to introduce the canvas? I get totally messed up with all the inheritances throughout the different classes.

If you would suggest a complete different setup, this would also be fine.

Many thanks for your help.

import tkinter as tk

class GUI(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(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {} 

        for F in (StartPage, PageTwo):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        frame = StartPage(container, self)
        self.frames[StartPage] = frame
        frame.grid(row=0, column=0, sticky="nsew")        
        self.show_frame(StartPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise() # zeigt Frame oben an

class StartPage(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Your choice?")                         
        label.pack(pady=10,padx=10)
        button1 = tk.Button(self, text="Open PageTwo",
                             width = 25, command=lambda: controller.show_frame(PageTwo))
        button1.pack(pady=10, padx=10)

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

        tk.Frame.__init__(self, parent)
        master = tk.Tk()
        scrollbar = tk.Scrollbar(master)
        scrollbar.pack(side=tk.RIGHT, fill="y")

        listbox = tk.Listbox(master, yscrollcommand=scrollbar.set)
        for i in range(1000):
            listbox.insert(tk.END, str(i))
        listbox.pack(side=tk.LEFT, fill="both")

        scrollbar.config(command=listbox.yview)

if __name__ == '__main__':  
    app = GUI()
    app.mainloop()      

回答1:

To fix the issues:

  • initialize PageTwo only when the button is clicked
  • use Toplevel for popup window
  • use root as the StartPage

Below is a demo based on your posted code:

import tkinter as tk
from tkinter import ttk

class GUI(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(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        label = tk.Label(self, text="Your choice?")
        label.pack(pady=10,padx=10)
        button1 = ttk.Button(self, text="Open PageTwo", width=25, command=lambda: self.show_frame(PageTwo))
        button1.pack(pady=10, padx=10)
        button2 = ttk.Button(self, text="Open PageCanvas", width=25, command=lambda: self.show_frame(PageCanvas))
        button2.pack(pady=10, padx=10)

    def show_frame(self, page):
        win = page(self)
        # make window modal
        win.grab_set()
        self.wait_window(win)

class PageTwo(tk.Toplevel):
    def __init__(self, parent):
        tk.Toplevel.__init__(self, parent)
        self.title('Two')
        scrollbar = tk.Scrollbar(self)
        scrollbar.pack(side=tk.RIGHT, fill="y")
        listbox = tk.Listbox(self, yscrollcommand=scrollbar.set)
        for i in range(1000):
            listbox.insert(tk.END, str(i))
        listbox.pack(side=tk.LEFT, fill="both")
        scrollbar.config(command=listbox.yview)

class PageCanvas(tk.Toplevel):
    def __init__(self, parent):
        tk.Toplevel.__init__(self, parent)
        self.title('Canvas')
        self.geometry('400x600')
        canvas = tk.Canvas(self, bg='white', scrollregion=(0, 0, 400, 20000))
        canvas.pack(fill='both', expand=True)
        vbar = tk.Scrollbar(canvas, orient='vertical')
        vbar.pack(side='right', fill='y')
        vbar.config(command=canvas.yview)
        canvas.config(yscrollcommand=vbar.set)
        for i in range(1000):
            canvas.create_text(5, i*15, anchor='nw', text=str(i))

if __name__ == '__main__':
    app = GUI()
    app.mainloop()