I used a scrollbar for my tkinter app with Canvas. I am using Pack to set up the scrollbars. But I have a problem. The horizontal scrollbar works fine, but the vertical scrollbar does not. The location is misconfigured.
My code:
self.scroll_x = tk.Scrollbar(self, orient=tk.HORIZONTAL)
self.scroll_y = tk.Scrollbar(self, orient=tk.VERTICAL)
self.canvas = tk.Canvas(self, width=600, height=100,
xscrollcommand=self.scroll_x.set,
yscrollcommand=self.scroll_y.set)
self.scroll_x.config(command=self.canvas.xview)
self.scroll_y.config(command=self.canvas.yview)
self.frame = tk.Frame(self.canvas)
self.canvas.create_window((0, 0), window=self.frame,anchor=tk.NW)
self.canvas.bind_all("<MouseWheel>", self.on_mousewheel)
self.canvas.config(scrollregion=self.canvas.bbox(tk.ALL))
self.canvas.pack(side=tk.LEFT,expand=True,fill=tk.BOTH)
self.scroll_x.pack(side=tk.BOTTOM,fill=tk.X)
self.scroll_y.pack(side=tk.RIGHT,fill=tk.Y)
self.bind("<Configure>", self.resize)
self.update_idletasks()
def on_mousewheel(self, event):
shift = (event.state & 0x1) != 0
scroll = -1 if event.delta > 0 else 1
if shift:
self.canvas.xview_scroll(scroll, "units")
else:
self.canvas.yview_scroll(scroll, "units")
def resize(self, event):
region = self.canvas.bbox(tk.ALL)
self.canvas.configure(scrollregion=region)
I recommand using grid in this case. See more
import tkinter as tk
class MyFigure(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.scroll_x = tk.Scrollbar(self, orient=tk.HORIZONTAL)
self.scroll_y = tk.Scrollbar(self, orient=tk.VERTICAL)
self.canvas = tk.Canvas(self, width=600, height=100, bg='red',
xscrollcommand=self.scroll_x.set,
yscrollcommand=self.scroll_y.set)
self.scroll_x.config(command=self.canvas.xview)
self.scroll_y.config(command=self.canvas.yview)
self.frame = tk.Frame(self.canvas)
self.canvas.create_window((0, 0), window=self.frame,anchor=tk.NW)
self.canvas.bind_all("<MouseWheel>", self.on_mousewheel)
self.canvas.config(scrollregion=self.canvas.bbox(tk.ALL))
self.canvas.grid(column=0,row=0)
self.scroll_x.grid(column=0,row=1,sticky='ew')
self.scroll_y.grid(column=1,row=0,sticky='ns')
self.bind("<Configure>", self.resize)
def on_mousewheel(self, event):
shift = (event.state & 0x1) != 0
scroll = -1 if event.delta > 0 else 1
if shift:
self.canvas.xview_scroll(scroll, "units")
else:
self.canvas.yview_scroll(scroll, "units")
def resize(self, event):
region = self.canvas.bbox(tk.ALL)
self.canvas.configure(scrollregion=region)
root = tk.Tk()
mf = MyFigure(root)
mf.pack()
root.mainloop()
If you really need to use pack, than be aware that by using it in a complex way the order of packing the widgets is important. I think its easier to order the rest of your frame with grid instead trying to pack them together.
Anyway, replace these lines in the above code and it works:
self.scroll_x.pack(side=tk.BOTTOM,fill=tk.X)
self.canvas.pack(side=tk.LEFT,expand=True,fill=tk.BOTH)
self.scroll_y.pack(side=tk.LEFT,fill=tk.Y)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.