我无法绑定箭头键事件
Posted
技术标签:
【中文标题】我无法绑定箭头键事件【英文标题】:I can't bind the arrow key events 【发布时间】:2021-12-28 16:29:01 【问题描述】:我目前有一个下一个切片和上一个切片按钮,可以单击它们以在图像中移动。我还希望键盘左右箭头允许用户浏览上一个和下一个切片。所以应该有两种方法来浏览图像。我无法在prev_image
和next_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()
图片:
【问题讨论】:
您只需绑定一次。也许使用self.master.bind()
而不是self.canvas.bind()
。或者它可能需要在canvas
上设置focus()
。或者先创建root = tk.Tk()
,然后使用root.bind()
当我删除第二个 self.canvas.bind 并将第一个更改为 self.master.bind() 时,我收到错误消息“next_image() 需要 1 个位置参数但 2被给予”
可能先在函数中使用print()
,看看是否执行。也许它运行这些功能,但你可能有不同的问题 - 比如bug
in PhotoImage
如果您创建最小的工作代码,我们可以简单地复制和测试它会更简单。当前代码缺少Canvas
、load_image
、image_set_rows
、current_image_index
。
请edit 提出您的问题并提供runnable minimal reproducible example 的代码,我相信有人可以提供帮助。
【参考方案1】:
您必须在canvas
上设置focus
才能获取canvas
中的密钥
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)
第二个版本可能会更好,因为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()
【讨论】:
谢谢!!如果我按下下一个箭头键,您对添加 self.canvas.focus_set() 的建议的最小工作示例适用于下一个图像,但对于上一个图像,它给了我相同的“prev_image() 需要 1 个位置参数,但给出了 2 个" 错误 我的例子没有问题。您必须在next_image
和 previous_image
两个函数中使用 event=None
搞定了,谢谢!!以上是关于我无法绑定箭头键事件的主要内容,如果未能解决你的问题,请参考以下文章
是否有可能看到我在C#WPF中按下数据网格上的向下箭头如何将事件绑定到该?
Tkinter中的多个键事件绑定 - “Control + E”“Command(apple)+ E”等
为啥 Python 会在 Pygame 中为“事件”变量抛出未绑定的本地错误? [关闭]