Problem: you can scroll upwards even though the first item should be at the very top of the canvas
How to reproduce the problem: have at least one item on the canvas and scroll using the mouse ( press space to make an item )
Note: the problem ceases once the items are wider than the canvas itself
Sample code
import tkinter as tk
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.bind("<MouseWheel>", self.scroll)
self.bind("<KeyPress>", self.keypressed)
self.TargetCanvas = None
self.makeui()
def makeui(self):
self.Canvas = tk.Canvas(self, bg = "white")
self.Canvas.grid(row = 0, column = 0, sticky = "W")
sby = tk.Scrollbar(self, orient = "vertical", command = self.Canvas.yview)
sby.grid(row = 0, column = 1, sticky = "ns")
self.Canvas.configure(yscrollcommand = sby.set)
self.CanvFrame = tk.Frame(self.Canvas, bg = "white")
self.Canvas.create_window((0, 0), window = self.CanvFrame, anchor = "nw")
self.CanvFrame.bind("<Configure>", lambda event: self.Canvas.configure(scrollregion = self.Canvas.bbox("all")))
self.Canvas.bind("<Enter>", lambda event: self.settarget(event, True))
self.Canvas.bind("<Leave>", lambda event: self.settarget(event, False))
tk.Label(self, text = "space = add item, c = clear all").grid(row = 1, column = 0)
def settarget(self, event, check):
if check:
self.TargetCanvas = event.widget
else:
self.TargetCanvas = None
def scroll(self, event):
if self.TargetCanvas is not None:
direction = 0
if event.num == 5 or event.delta == -120:
direction = 1
if event.num == 4 or event.delta == 120:
direction = -1
self.TargetCanvas.yview_scroll(direction, tk.UNITS)
def keypressed(self, event):
if event.keysym == "space":
self.additem()
elif event.keysym == "c":
self.clearall()
def clearall(self):
for i in self.CanvFrame.winfo_children():
i.destroy()
x = tk.Label(self.CanvFrame)
#kick in frame resizing
x.pack()
self.update()
self.Canvas.configure(scrollregion = self.Canvas.bbox("all"))
x.destroy()
def additem(self):
tk.Label(self.CanvFrame, text = "asd").pack(side = tk.TOP)
def main():
App().mainloop()
if __name__ == "__main__":
main()