Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

table display in tkinter with scroll bars

I'm writing a small GUI in python3/tkinter. What I want to do is generate a window with a table of data (like a spreadsheet) and have the table be scrollable both horizontally and vertically. Right now I'm just trying to display data, so I'm using a grid of Labels. The data display works fine but I can't get the scroll bars to act correctly. Here is the relevant part of my code; the class that this is in inherits from tk.Toplevel

frame = self.frame = tk.Frame(self)
self.frame.grid(row=1, columnspan=2, padx=2, pady=2, sticky=tk.N+tk.E+tk.S+tk.W)

self.text_area = tk.Canvas(self.frame, background="black", width=400, height=500, scrollregion=(0,0,1200,800))
self.hscroll = tk.Scrollbar(self.frame, orient=tk.HORIZONTAL, command=self.text_area.xview)
self.vscroll = tk.Scrollbar(self.frame, orient=tk.VERTICAL, command=self.text_area.yview)
self.text_area['xscrollcommand'] = self.hscroll.set
self.text_area['yscrollcommand'] = self.vscroll.set

self.text_area.grid(row=0, column=0, sticky=tk.N+tk.S+tk.E+tk.W)
self.hscroll.grid(row=1, column=0, sticky=tk.E+tk.W)
self.vscroll.grid(row=0, column=1, sticky=tk.N+tk.S)

self._widgets = []

for row in range(rows):
    current_row = []
    for column in range(columns):
        label = tk.Label(self.text_area, text="", 
                         borderwidth=0, width=width)
        label.grid(row=row, column=column, sticky="nsew", padx=1, pady=1)
        current_row.append(label)
    self._widgets.append(current_row)

The table displays OK and the scrollbars appear but are not functional: enter image description here

Any ideas?

like image 716
Alex Z Avatar asked Oct 16 '25 05:10

Alex Z


1 Answers

You have a couple of problems. First, you can't use grid to place labels in the canvas and expect them to scroll. When you scroll a canvas, only the widgets added with create_window will scroll. However, you can use grid to put the labels in a frame, and then use create_window to add the frame to the canvas. There are several examples of that technique on this site.

Second, you need to tell the canvas how much of the data in the canvas should be scrollable. You use this by setting the scrollregion attribute of the canvas. There is a method, bbox which can give you a bounding box of all of the data in the canvas. Usually it's used like this:

canvas.configure(scrollregion=canvas.bbox("all"))
like image 164
Bryan Oakley Avatar answered Oct 18 '25 19:10

Bryan Oakley