Tkinter; how to use scrollbar in a popup/top-level window that opens when a button is pressed in main root window

StackOverflow https://stackoverflow.com/questions/22645041

Question

I'm trying to create an app with a scrollbar in a top level window that opens when a button,bttn, is pressed in the main root window and from the code below I'd need help with the following:

  • the scrollbar should be in a new, top-level, window from the main root window by pressing the button bttn defined in widget()
  • the new popup window should contain the scrollbar vscrollbar defined in VerticalScrollFrame
  • the scrollbar vscrollbar shouldn't appear in the main root window, only in the new popup window

    from Tkinter import * 
    class VerticalScrolledFrame(Frame):
    
    
        def __init__(self, parent, *args, **kw):
            Frame.__init__(self, parent, *args, **kw)            
    
            # create a canvas object and a vertical scrollbar for scrolling it
            vscrollbar = Scrollbar(self, orient=VERTICAL)
            vscrollbar.pack(fill=Y, side=RIGHT, expand=FALSE)
            canvas = Canvas(self, bd=0, highlightthickness=0,
                            yscrollcommand=vscrollbar.set)
            canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)
            vscrollbar.config(command=canvas.yview)
    
            # reset the view
            canvas.xview_moveto(0)
            canvas.yview_moveto(0)
    
            # create a frame inside the canvas which will be scrolled with it
            self.interior = interior = Frame(canvas)
            interior_id = canvas.create_window(0, 0, window=interior,
                                               anchor=NW)
    
            # track changes to the canvas and frame width and sync them,
            # also updating the scrollbar
            def _configure_interior(event):
                # update the scrollbars to match the size of the inner frame
                size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
                canvas.config(scrollregion="0 0 %s %s" % size)
                if interior.winfo_reqwidth() != canvas.winfo_width():
                    # update the canvas's width to fit the inner frame
                    canvas.config(width=interior.winfo_reqwidth())
            interior.bind('<Configure>', _configure_interior)
    
            def _configure_canvas(event):
                if interior.winfo_reqwidth() != canvas.winfo_width():
                    # update the inner frame's width to fill the canvas
                    canvas.itemconfigure(interior_id, width=canvas.winfo_width())
            canvas.bind('<Configure>', _configure_canvas)
    
    
    if __name__ == "__main__":
    
        class SampleApp(Frame):
            def __init__(self,root, *args, **kwargs):
                Frame.__init__(self, root,*args, **kwargs)
    
    
                self.frame = VerticalScrolledFrame(root)
                self.frame.pack()
    
                self.widget()
    
    
            def widget(self):
                self.label = Label(text="Shrink the window to activate the scrollbar.")
                self.label.pack()
    
                bttn = Button(self.frame.interior, text = "Flytta fram/bak i listvy", command = self.open_new_window_with_text_and_scrollbar)
                bttn.pack()
    
            # Should be opened in a new, top-level, window from the main root window by pressing the #button bttn defined in widget()
            # the new popup window should contain the scrollbar vscrollbar defined in SampleApp
            # the scrollbar vscrollbar shouldn't appear in the main root window, only in the new #popup window
    
            def open_new_window_with_text_and_scrollbar(self):
    
                self.top = tk.Toplevel(self)
                frame = VerticalScrolledFrame(root)
                frame.pack()
                Button = tk.Button(self.top, text="Close window", command=self.top.destroy)
                Label = tk.Label(self.top, wraplength = 500,text="testing")
                Label.pack(side="left", fill="both", expand=True)
                Button.pack()
    
    
    
        root = tk.Tk()
        root.title("Maltparser1.0_demo")
    
        root.geometry("900x700")
        app = SampleApp(root)
        root.mainloop()
    
Was it helpful?

Solution

You're passing root as the parent to VerticalScrolledFrame, you need to pass self.top instead:

class SampleApp(Frame):

     # ...Other code...

     def open_new_window_with_text_and_scrollbar(self):
        self.top = tk.Toplevel(self)
        frame = VerticalScrolledFrame(self.top)
        frame.pack()
        # Other widgets

That's why it's adding itself to the main root window instead of the Toplevel.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top