有没有办法提供事件参数?

时间:2020-02-23 16:24:47

标签: events canvas tkinter mouseevent scrollbar

我正在尝试制作滚动框架类,但是事件对我来说仍然是新事物。

因此,我的框架很好,但是当我尝试使鼠标滚轮发生事件时,出现了一个错误,我错过了给出“ event”自变量的错误。我了解这一点,但我不明白我需要在此处提出哪种类型的论点。

从Google搜索中,我得到了一些答案,但是代码未放置在类中,当我尝试将其放置到类中时,出现错误消息,提示我忘记提供事件参数。

如果使用 lambda 进行设置,我会在某处阅读,它将解决该错误,但是我收到另一个错误,告诉我lambda不接受任何参数,但是给出了一个参数...

如果我得到有关这些事件如何工作的纪录片,我并没有要求解决问题,那将是非常有帮助的。也许有人可以向我解释它如何在类中处理它,因为我发现了有关事件如何工作的一些信息,而只是一些一般性的事情。

我的测试代码在这里:

from tkinter import Tk, Frame, Canvas, Scrollbar, Grid
from tkinter import Label
from tkinter.ttk import Sizegrip

root = Tk()
appWidth = 500
appHeight = 300
appError = "[ ERROR ] >> "

class ASI:
    def Extend(master=None, row=0, column=0):
        if master != None:
            Grid.rowconfigure(master, row, weight=1)
            Grid.columnconfigure(master, column, weight=1)
        else:
            print(f"{appError}You still need to type witch frame to expend!")

class ScrollFrame(Frame):
    def __init__(self, master, *args, **kwargs):
        #super().__init__(master, *args, **kwargs)
        super(ScrollFrame, self).__init__(master, *args, **kwargs)

        # Display container
        canvas = Canvas(self)
        ASI.Extend(canvas)

        # Scrollbar for the display container
        scrollbarV = Scrollbar(self, orient="vertical", command=canvas.yview)
        scrollbarH = Scrollbar(self, orient="horizontal", command=canvas.xview)
        resize = Sizegrip(self)

        # Frame inside the container
        self.frame = Frame(canvas, bg="red")
        ASI.Extend(self.frame)

        # Configure some settings
        # Bind the "frame" to the canvas size
        self.frame.bind(
            "<Configure>", lambda e: canvas.configure(
                scrollregion=canvas.bbox("all")
            )
        )
        # Place the "frame" inside the canvas on top left
        canvas.create_window((0,0), window=self.frame, anchor="nw")
        # Set scrollbars to the canvas functions
        canvas.configure(yscrollcommand=scrollbarV.set)
        canvas.configure(xscrollcommand=scrollbarH.set)

        # Paking
        canvas.grid(row=0, column=0, sticky="nesw")
        scrollbarV.grid(row=0, column=1, sticky="ns")
        scrollbarH.grid(row=1, column=0, sticky="we")
        resize.grid(row=1, column=1)

        # Events
        def ScrollEvent(self, event):
            self.canvas.yview_scroll(init(-1*(event.delta/120)), "units")
        def ScrollEvent_Bound(self, event):
            self.canvas.bind_all("<MouseWheel>", self.ScrollEvent)
        def ScrollEvent_UnBound(self, event):
            self.canvas.unbind_all("<MouseWheel>")

        canvas.bind("<Enter>", ScrollEvent_Bound)
        canvas.bind("<Leave>", ScrollEvent_UnBound)

        # This will solve error messages but the event will still not work
        #canvas.bind("<Enter>", lambda e:ScrollEvent_Bound)
        #canvas.bind("<Leave>", lambda e:ScrollEvent_UnBound)
        # This will show me same error like with not lambda
        #canvas.bind("<Enter>", lambda e:ScrollEvent_Bound(e))

class App:
    def __init__(self, master):
        self.master = master
        ASI.Extend(master)

        # Main App Configurations
        master.title("Scroll Frame")
        centerW = int((master.winfo_screenwidth() - appWidth) / 2)
        centerH = int((master.winfo_screenheight() - appHeight) / 2)
        master.geometry(f"{appWidth}x{appHeight}+{centerW}+{centerH}")

        # App Content
        info = ScrollFrame(master)
        info.grid(row=0, column=0, sticky="nesw")
        ASI.Extend(info)
        for i in range(30):
            if i <= 9: row = f"0{i}"
            else: row = i
            txt = f"Row: {row} // Column: 00"
            Label(info.frame, text=txt, bg="pink"
                  ).grid(row=i, column=0)

# Run if this is the main file opened
if __name__ == "__main__":
    App(root)
    root.mainloop()

Python 3.8.1 // OS:Window (7)

1 个答案:

答案 0 :(得分:0)

我在玩在Google上找到的其他示例代码,所以所有问题都是 self 的宽度。我从事件函数中删除了所有自变量,现在一切正常。

更新的代码:

class ScrollFrame(Frame):
    def __init__(self, master, *args, **kwargs):
        super(ScrollFrame, self).__init__(master, *args, **kwargs)

        # Display container
        canvas = Canvas(self)
        ASI.Extend(canvas)

        # Scrollbar for the display container
        scrollbarV = Scrollbar(self, orient="vertical", command=canvas.yview)
        scrollbarH = Scrollbar(self, orient="horizontal", command=canvas.xview)

        # Frame inside the container
        self.frame = Frame(canvas)
        ASI.Extend(self.frame)

        # Configure some settings
        # Bind the "frame" to the canvas size
        self.frame.bind(
            "<Configure>", lambda e: canvas.configure(
                scrollregion=canvas.bbox("all")
            )
        )
        # Place the "frame" inside the canvas on top left
        canvas.create_window((0,0), window=self.frame, anchor="nw")
        # Set scrollbars to the canvas functions
        canvas.configure(yscrollcommand=scrollbarV.set)
        canvas.configure(xscrollcommand=scrollbarH.set)

        # Paking
        canvas.grid(row=0, column=0, sticky="nesw")
        scrollbarV.grid(row=0, column=1, sticky="ns")
        scrollbarH.grid(row=1, column=0, sticky="we")

        # Events
        def ScrollEventKey(event):
            # Arrow Left // Numpad 4
            if event.keycode == 37 or event.keycode == 100:
                canvas.xview_scroll(-1, "units")
            # Arrow Right // Numpad 6
            elif event.keycode == 39 or event.keycode == 102:
                canvas.xview_scroll(1, "units")
            # Arrow Up // Numpad 8
            elif event.keycode == 38 or event.keycode == 104:
                canvas.yview_scroll(-1, "units")
            # Arrow Down // Numpad 2
            elif event.keycode == 40 or event.keycode == 98:
                canvas.yview_scroll(1, "units")

        def ScrollEventV(event):
            canvas.yview_scroll(int(-1*(event.delta/120)), "units")
        def ScrollEventH(event):
            canvas.xview_scroll(int(-1*(event.delta/120)), "units")

        def ScrollEvent_Bound(event):
            canvas.bind_all("<MouseWheel>", ScrollEventV)
            canvas.bind_all("<Shift-MouseWheel>", ScrollEventH)
            canvas.bind_all("<KeyPress>", ScrollEventKey)
        def ScrollEvent_UnBound(event):
            canvas.unbind_all("<MouseWheel>")
            canvas.unbind_all("<Shift-MouseWheel>")
            canvas.unbind_all("<KeyPress>")

        canvas.bind("<Enter>", ScrollEvent_Bound)
        canvas.bind("<Leave>", ScrollEvent_UnBound)