我无法绑定方向键事件

I can't bind the arrow key events

我目前有下一个切片和上一个切片按钮,可以单击它们在图像中移动。我还希望键盘左右箭头允许用户浏览上一个和下一个切片。所以应该有两种方法来浏览图像。我无法在 prev_imagenext_image.

中让键盘点击工作
import tkinter as tk

class App(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)  # python3 style
    
        self.master.title("Slideshow")

        top_frame = tk.Frame(self)
        top_frame.pack()
    
        image_frame = tk.Frame(self)
        image_frame.pack()

        previous_button = tk.Button(top_frame, text="Previous Slice", command=self.prev_image)
        previous_button.pack(side="left")

        next_button = tk.Button(top_frame, text="  Next Slice  ", command=self.next_image)
        next_button.pack(side="left")

        self.canvas = tk.Canvas(image_frame, bg='red')
        self.canvas.pack()
    
        self.canvas.bind('<Left>', self.prev_image)
        self.canvas.bind('<Right>', self.next_image)
        self.canvas.focus_set()

        self.master.bind('<Left>', self.prev_image)
        self.master.bind('<Right>', self.next_image)
    
    def prev_image(self, event=None):
        print('prev_image')
        if event:
            print('even:', event)

    def next_image(self, event=None):
        print('next_image')
        if event:
            print('even:', event)

root = tk.Tk()
app = App(root)
app.pack()
root.mainloop()

 

图片:

您必须在 canvas 上设置 focus 才能在 canvas

中获取密钥
        self.canvas.bind('<Left>', self.prev_image)
        self.canvas.bind('<Right>', self.next_image)
        self.canvas.focus_set()

或者您可以将密钥绑定到 master window

        self.master.bind('<Left>', self.prev_image)
        self.master.bind('<Right>', self.next_image)

第二个版本可能更好,因为 canvas 可能会丢失 focus - 即。当您使用键 tab 从一个小部件跳转到另一个小部件时。


其他问题。

command= 需要不获取参数的函数,但 bind() 需要获取一个参数的函数 - 因为它发送有关事件的信息(即按下的键、鼠标位置等)

要在 command=bind() 中使用相同的函数,您需要具有默认值的参数 - 即。 even=None

    def prev_image(self, event=None):
        # ... code ...

    def next_image(self, event=None):
        # ... code ...

最小工作示例:

import tkinter as tk

class App(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)  # python3 style
        
        self.master.title("Slideshow")

        top_frame = tk.Frame(self)
        top_frame.pack()
        
        image_frame = tk.Frame(self)
        image_frame.pack()
    
        previous_button = tk.Button(top_frame, text="Previous Slice", command=self.prev_image)
        previous_button.pack(side="left")

        next_button = tk.Button(top_frame, text="  Next Slice  ", command=self.next_image)
        next_button.pack(side="left")

        self.canvas = tk.Canvas(image_frame, bg='red')
        self.canvas.pack()
        
        #self.canvas.bind('<Left>', self.prev_image)
        #self.canvas.bind('<Right>', self.next_image)
        #self.canvas.focus_set()

        self.master.bind('<Left>', self.prev_image)
        self.master.bind('<Right>', self.next_image)
        
    def prev_image(self, event=None):
        print('prev_image')
        self.canvas['bg'] = 'blue'
        if event:
            print('even:', event)

    def next_image(self, event=None):
        print('next_image')
        self.canvas['bg'] = 'green'
        if event:
            print('even:', event)


if __name__ == "__main__":
    app = App()
    app.pack()
    app.mainloop()
    
    #root = tk.Tk()
    #app = App(root)
    #app.pack()
    #root.mainloop()