Reputation: 5625
I cannot get x and y scrollbars to work in Tkinter with Python, although I have followed multiple examples:
The scrollbars appear, but do not activate when the window is smaller than the frame. How can I get this to work (see image below)?
Below is the minimal code that is producing my problem (Python 3.7)
import tkinter as tk
from tkinter import ttk
big_font = ("Arial", 50)
class DoubleScrollbarFrame(ttk.Frame):
def __init__(self,
parent,
*args,
**kwargs):
self.parent = parent
super().__init__(self.parent,
*args,
**kwargs)
#Set widgets to fill main window such that they are
#all the same size
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.create_widgets()
self.position_widgets()
def create_widgets(self):
self.canvas = tk.Canvas(self)
self.frame = ttk.Frame(self.canvas)
self.scroll_x = ttk.Scrollbar(self,
orient = tk.HORIZONTAL,
command = self.canvas.xview)
self.scroll_y = ttk.Scrollbar(self,
orient = tk.VERTICAL,
command = self.canvas.yview)
self.canvas.config(xscrollcommand = self.scroll_x.set,
yscrollcommand = self.scroll_y.set)
self.canvas.create_window((0,0),
window = self.frame,
anchor = 'nw')
self.frame.bind('<Configure>',
self.set_scrollregion)
self.sizegrip = ttk.Sizegrip(self)
#Test
self.test1 = tk.Label(self.frame,
text = 'Test 1',
font = big_font)
self.test2 = tk.Label(self.frame,
text = 'Test 2',
font = big_font)
self.test3 = tk.Label(self.frame,
text = 'Test 3',
font = big_font)
def position_widgets(self,
**kwargs):
self.test1.grid(row = 0,
column = 0,
sticky = 'w')
self.test2.grid(row = 1,
column = 0,
sticky = 'w')
self.test3.grid(row = 2,
column = 0,
sticky = 'w')
self.scroll_x.grid(row = 1,
column = 0,
sticky = 'ew')
self.scroll_y.grid(row = 0,
column = 1,
sticky = 'ns')
self.canvas.grid(row = 0,
column = 0,
sticky = 'nsew')
self.frame.grid(row = 0,
column = 0,
sticky = 'nsew')
self.sizegrip.grid(row = 1,
column = 1,
sticky = 'se')
def set_scrollregion(self,
event):
print('Frame Dimensions: {} x {}'.format(self.frame.winfo_width(),
self.frame.winfo_height()))
print('Canvas Dimensions: {} x {}'.format(self.canvas.winfo_width(),
self.canvas.winfo_height()))
self.canvas.configure(scrollregion = self.canvas.bbox('all'))
class MainApp(tk.Tk):
def __init__(self,
*args,
**kwargs):
super().__init__(*args,
**kwargs)
#Set widgets to fill main window such that they are
#all the same size
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.create_widgets()
self.position_widgets()
def create_widgets(self):
self.frame = DoubleScrollbarFrame(self)
def position_widgets(self):
self.frame.grid(row = 0,
column = 0,
sticky = 'nsew')
def exit(self):
self.destroy()
if __name__ == '__main__':
#Create GUI
root = MainApp()
#Run program
root.mainloop()
Upvotes: 0
Views: 547
Reputation: 385870
The problem is in these lines of code inside DoubleScrollbarFrame.position_widgets
:
self.frame.grid(row = 0,
column = 0,
sticky = 'nsew')
This removes control of the widget from the canvas and gives control to grid
. It is no longer a canvas object, so self.canvas.bbox("all")
is returning (0, 0, 1, 1)
. If the scrollregion is set incorrectly, the scrollbars don't know how much to scroll.
The solution is simple: don't call grid
on self.frame
.
Upvotes: 1