Alex Z
Alex Z

Reputation: 1539

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?

Upvotes: 4

Views: 22334

Answers (2)

jimscafe
jimscafe

Reputation: 1091

An option I have used is the leave the labels static and changed the data when the scrollbar is used. This is easy for vertical scrolling but if the columns are of different widths does not work for horizontal scrolling - it would require resizing the labels.

Upvotes: 0

Bryan Oakley
Bryan Oakley

Reputation: 386010

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

Upvotes: 3

Related Questions