Python 3.x 如果使用鼠标滚轮滚动,画布将离开滚动区域

Python 3.x 如果使用鼠标滚轮滚动,画布将离开滚动区域,python-3.x,scroll,tkinter,mousewheel,tkinter-canvas,Python 3.x,Scroll,Tkinter,Mousewheel,Tkinter Canvas,问题:您可以向上滚动,即使第一项应该在画布的最顶端 如何重现问题:画布上至少有一个项目,并使用鼠标滚动(按空格键制作项目) 注意:一旦项目比画布本身宽,问题就停止了 示例代码 import tkinter as tk class App(tk.Tk): def __init__(self): tk.Tk.__init__(self) self.bind("<MouseWheel>", self.scroll) self.bin

问题:您可以向上滚动,即使第一项应该在画布的最顶端

如何重现问题:画布上至少有一个项目,并使用鼠标滚动(按空格键制作项目)

注意:一旦项目比画布本身宽,问题就停止了

示例代码

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()
将tkinter作为tk导入
类应用程序(tk.tk):
定义初始化(自):
tk.tk.\uuuuu初始化(self)
self.bind(“,self.scroll)
self.bind(“,self.keypressed)
self.TargetCanvas=None
self.makeui()
def makeui(自我):
self.Canvas=tk.Canvas(self,bg=“白色”)
self.Canvas.grid(行=0,列=0,sticky=“W”)
sby=tk.Scrollbar(self,orient=“vertical”,command=self.Canvas.yview)
sby.grid(行=0,列=1,sticky=“ns”)
self.Canvas.configure(yscrollcommand=sby.set)
self.CanvFrame=tk.Frame(self.Canvas,bg=“白色”)
self.Canvas.create_window((0,0),window=self.CanvFrame,anchor=“nw”)
self.CanvFrame.bind(“,lambda事件:self.Canvas.configure(scrollregion=self.Canvas.bbox(“全部”))
self.Canvas.bind(“,lambda事件:self.settarget(事件,True))
self.Canvas.bind(“,lambda事件:self.settarget(事件,False))
tk.Label(self,text=“space=additem,c=clear all”).grid(行=1,列=0)
def设置目标(自身、事件、检查):
如果检查:
self.TargetCanvas=event.widget
其他:
self.TargetCanvas=None
def滚动(自我、事件):
如果self.TargetCanvas不是无:
方向=0
如果event.num==5或event.delta==120:
方向=1
如果event.num==4或event.delta==120:
方向=-1
self.TargetCanvas.yview_滚动条(方向,传统单位)
按def键(自身,事件):
如果event.keysym==“空格”:
self.additem()
elif event.keysym==“c”:
self.clearall()
def clearall(自身):
因为我在self.CanvFrame.winfo_children()中:
i、 销毁
x=tk.Label(self.CanvFrame)
#输入帧大小调整
x、 包()
self.update()
self.Canvas.configure(scrollregion=self.Canvas.bbox(“全部”))
x、 销毁
def附加项(自身):
标签(self.CanvFrame,text=“asd”).pack(side=tk.TOP)
def main():
App().mainloop()
如果名称=“\uuuuu main\uuuuuuuu”:
main()

您的问题是什么?如何停止这种行为。它应该像滚动条一样工作。因此,如果项目宽度不超过可见画布区域,则不应进行滚动。在调用
additem
时,您正在设置滚动区域。我不知道这是否是唯一的问题,但这肯定是个问题。画布上的滚动小部件:-我正在使用你的解决方案。这是否意味着我的案子错了?我的错。我没有注意到绑定到