首页 > 解决方案 > python tkinter 可滚动框架

问题描述

我已经制作了一个可滚动的框架,tkinter但有一些东西不起作用。

- 有没有办法让scrollbar距离更近labels

- 有没有办法从scrollbar顶部而不是中间开始?

-当我使用bind时,当我的鼠标悬停在时,我无法滚动labels,而当我使用时,bind_all我可以在窗口上到处滚动。有没有办法只有当我的鼠标在上面时才能滚动label

我的代码:

from tkinter import *

class Example:
    def __init__(self, root):
        self.master = root
        self.init_scrollframe()

    def init_scrollframe(self):
        self.big_frame = Frame(self.master)
        self.big_frame.grid(row=0, column=0)
        self.title = Label(self.big_frame, text="TITLE", font=("Arial", 30))
        self.title.grid(row=0, column=0, columnspan=2)
        self.frame = Frame(self.big_frame)
        self.frame.grid(row=1, column=0)
        self.scrollb = Scrollbar(self.frame, orient=VERTICAL)
        self.scrollb.grid(row=0, column=1, sticky=N+S+W)
        self.scroll_canvas = Canvas(self.frame, yscrollcommand=self.scrollb.set)
        self.scroll_canvas.grid(row=0, column=0, sticky=N+S+E)
        self.scrollb.config(command=self.scroll_canvas.yview)
        ##this doesn't work                                                                   
        """self.frame.bind("<MouseWheel>", self._on_mousewheel)                               
        self.frame.bind("<Button-5>", self._on_mousewheel)                                    
        self.frame.bind("<Button-4>", self._on_mousewheel)"""
        ##this works but it is scrolling also when I am not above the labels                  
        self.scroll_canvas.bind_all("<MouseWheel>", self._on_mousewheel)
        self.scroll_canvas.bind_all("<Button-5>", self._on_mousewheel)
        self.scroll_canvas.bind_all("<Button-4>", self._on_mousewheel)
        self.my_frame = Frame(self.scroll_canvas)
        ##put some labels into the scrollable frame                                           
        for i in range(100):
            self.lbl = Label(self.my_frame, text=str("label number " + str(i)))
            self.lbl.grid(row=i, column=0)
        self.scroll_canvas.create_window(0, 0, window=self.my_frame)
        self.my_frame.update_idletasks()
        self.scroll_canvas.config(scrollregion=self.scroll_canvas.bbox("all"))

    ##this is for scrolling                                                                   
    def _on_mousewheel(self, event):
        if event.num == 5 or event.delta == -120:
            self.scroll_canvas.yview_scroll(1, "units")
        if event.num == 4 or event.delta == 120:
            self.scroll_canvas.yview_scroll(-1, "units")

if __name__ == "__main__":
    root = Tk()
    ex = Example(root)
    root.mainloop()

标签: pythontkinter

解决方案


对于您的第三个问题,您可以简单地检查事件是否在您之前的框架内scroll_canvas

from tkinter import *

class Example:
    def __init__(self, root):
        self.master = root
        self.init_scrollframe()

    def init_scrollframe(self):
        self.big_frame = Frame(self.master)
        self.big_frame.grid(row=0, column=0)
        self.title = Label(self.big_frame, text="TITLE", font=("Arial", 30))
        self.title.grid(row=0, column=0, columnspan=2)
        self.frame = Frame(self.big_frame,name="test") #give it a name to check
        self.frame.grid(row=1, column=0)
        self.scrollb = Scrollbar(self.frame, orient=VERTICAL)
        self.scrollb.grid(row=0, column=1, sticky=N+S+W)
        self.scroll_canvas = Canvas(self.frame, yscrollcommand=self.scrollb.set)
        self.scroll_canvas.grid(row=0, column=0, sticky=N+S+E)
        self.scrollb.config(command=self.scroll_canvas.yview)
        self.scroll_canvas.bind_all("<MouseWheel>", self._on_mousewheel)
        self.scroll_canvas.bind_all("<Button-5>", self._on_mousewheel)
        self.scroll_canvas.bind_all("<Button-4>", self._on_mousewheel)
        self.my_frame = Frame(self.scroll_canvas)
        for i in range(100):
            self.lbl = Label(self.my_frame, text=str("label number " + str(i)))
            self.lbl.grid(row=i, column=0)
        self.scroll_canvas.create_window(0, 0, window=self.my_frame)
        self.my_frame.update_idletasks()
        self.scroll_canvas.config(scrollregion=self.scroll_canvas.bbox("all"))

    def _on_mousewheel(self, event):
        caller = event.widget
        if "test" in str(caller): #check if event is within frame
            if event.num == 5 or event.delta == -120:
                self.scroll_canvas.yview_scroll(1, "units")
            if event.num == 4 or event.delta == 120:
                self.scroll_canvas.yview_scroll(-1, "units")

if __name__ == "__main__":
    root = Tk()
    ex = Example(root)
    root.mainloop()

推荐阅读