Python tkinter 绑定悬停和按键
Python tkinter bind hover and keypress
我有一个 tkinter canvas window 并尝试使用方法 tag_bind 绑定事件组合,鼠标悬停并按下特定字母。
我试过的是:
self.element_block = self.canvas.create_window( (0, 0), window=self.block_main, anchor="nw", width=self.block_width, height=self.block_height )
self.canvas.tag_bind( self.element_block, '<Enter><p>', self.parameter_window_operator )
self.element_block = self.canvas.create_window( (0, 0), window=self.block_main, anchor="nw", width=self.block_width, height=self.block_height )
self.canvas.tag_bind( self.element_block, '<Enter> <p>', self.parameter_window_operator )
self.element_block = self.canvas.create_window( (0, 0), window=self.block_main, anchor="nw", width=self.block_width, height=self.block_height )
self.canvas.tag_bind( self.element_block, '<Enter p>', self.parameter_window_operator )
self.element_block = self.canvas.create_window( (0, 0), window=self.block_main, anchor="nw", width=self.block_width, height=self.block_height )
self.canvas.tag_bind( self.element_block, '<Enter-p>', self.parameter_window_operator )
self.element_block = self.canvas.create_window( (0, 0), window=self.block_main, anchor="nw", width=self.block_width, height=self.block_height )
self.canvas.tag_bind( self.element_block, '<Enter+p>', self.parameter_window_operator )
None 以上方法提供了我正在寻找的结果,当鼠标悬停在 canvas window 上并按下 alpha 键时启动回调方法。
感谢您的帮助,谢谢。
甚至不用担心 tag_bind
。您可以移动得太快而无法注册事件。我知道原因,这是我为您提供的第一个解决方案,即使您正常使用鼠标它也能正常工作,但如果您不使用它,它就会损坏。请尝试以下方法。
基本上 HoverPool
canvas 不断检查鼠标下方的内容。如果它是“悬浮池”中的某物,它就会被 focus_set()
触发,这使得它 key-bindings 可以工作。
import tkinter as tk
class HoverPool:
def __init__(self, canvas):
self.hoverpool = dict()
self.canvas = canvas
self.canvas.bind("<Motion>", self.check)
def addWidget(self, target, tag, pos, **kwargs):
self.hoverpool[tag] = target
win = self.canvas.create_window(pos, window=target, **kwargs)
self.canvas.itemconfig(win, tag=(tag))
def check(self, event):
if len(self.canvas.gettags('current')):
for k, v in self.hoverpool.items():
if k in self.canvas.gettags('current'):
v.focus_set()
return
self.canvas.master.focus_set()
class App(tk.Tk):
WIDTH, HEIGHT, TITLE = 800, 600, 'Application'
def __init__(self):
tk.Tk.__init__(self)
self.canvas = tk.Canvas(self, background='red')
self.canvas.pack(fill='both', expand=True, side='left')
#init hoverpool
hoverpool = HoverPool(self.canvas)
self.frame1 = tk.Frame(self, background='green', height=50, width=50)
self.frame1.bind('<Key-p>', self.onFrame1Action)
self.frame1.bind('<Key-b>', self.onFrame1Action)
#add frame1 to the hover pool
hoverpool.addWidget(self.frame1, 'frame1', (50,50), anchor='nw')
self.frame2 = tk.Frame(self, background='green', height=50, width=50)
self.frame2.bind('<Key-p>', self.onFrame2Action)
self.frame2.bind('<Key-b>', self.onFrame2Action)
#add frame2 to the hover pool
hoverpool.addWidget(self.frame2, 'frame2', (105,50), anchor='nw')
def onFrame1Action(self, event):
if event.char == 'p':
self.frame1['background'] = 'purple'
if event.char == 'b':
self.frame1['background'] = 'black'
def onFrame2Action(self, event):
if event.char == 'p':
self.frame2['background'] = 'pink'
if event.char == 'b':
self.frame2['background'] = 'blue'
if __name__ == '__main__':
app = App()
app.title(App.TITLE)
app.geometry(f'{App.WIDTH}x{App.HEIGHT}')
app.resizable(width=False, height=False)
app.mainloop()
我有一个 tkinter canvas window 并尝试使用方法 tag_bind 绑定事件组合,鼠标悬停并按下特定字母。
我试过的是:
self.element_block = self.canvas.create_window( (0, 0), window=self.block_main, anchor="nw", width=self.block_width, height=self.block_height )
self.canvas.tag_bind( self.element_block, '<Enter><p>', self.parameter_window_operator )
self.element_block = self.canvas.create_window( (0, 0), window=self.block_main, anchor="nw", width=self.block_width, height=self.block_height )
self.canvas.tag_bind( self.element_block, '<Enter> <p>', self.parameter_window_operator )
self.element_block = self.canvas.create_window( (0, 0), window=self.block_main, anchor="nw", width=self.block_width, height=self.block_height )
self.canvas.tag_bind( self.element_block, '<Enter p>', self.parameter_window_operator )
self.element_block = self.canvas.create_window( (0, 0), window=self.block_main, anchor="nw", width=self.block_width, height=self.block_height )
self.canvas.tag_bind( self.element_block, '<Enter-p>', self.parameter_window_operator )
self.element_block = self.canvas.create_window( (0, 0), window=self.block_main, anchor="nw", width=self.block_width, height=self.block_height )
self.canvas.tag_bind( self.element_block, '<Enter+p>', self.parameter_window_operator )
None 以上方法提供了我正在寻找的结果,当鼠标悬停在 canvas window 上并按下 alpha 键时启动回调方法。
感谢您的帮助,谢谢。
甚至不用担心 tag_bind
。您可以移动得太快而无法注册事件。我知道原因,这是我为您提供的第一个解决方案,即使您正常使用鼠标它也能正常工作,但如果您不使用它,它就会损坏。请尝试以下方法。
基本上 HoverPool
canvas 不断检查鼠标下方的内容。如果它是“悬浮池”中的某物,它就会被 focus_set()
触发,这使得它 key-bindings 可以工作。
import tkinter as tk
class HoverPool:
def __init__(self, canvas):
self.hoverpool = dict()
self.canvas = canvas
self.canvas.bind("<Motion>", self.check)
def addWidget(self, target, tag, pos, **kwargs):
self.hoverpool[tag] = target
win = self.canvas.create_window(pos, window=target, **kwargs)
self.canvas.itemconfig(win, tag=(tag))
def check(self, event):
if len(self.canvas.gettags('current')):
for k, v in self.hoverpool.items():
if k in self.canvas.gettags('current'):
v.focus_set()
return
self.canvas.master.focus_set()
class App(tk.Tk):
WIDTH, HEIGHT, TITLE = 800, 600, 'Application'
def __init__(self):
tk.Tk.__init__(self)
self.canvas = tk.Canvas(self, background='red')
self.canvas.pack(fill='both', expand=True, side='left')
#init hoverpool
hoverpool = HoverPool(self.canvas)
self.frame1 = tk.Frame(self, background='green', height=50, width=50)
self.frame1.bind('<Key-p>', self.onFrame1Action)
self.frame1.bind('<Key-b>', self.onFrame1Action)
#add frame1 to the hover pool
hoverpool.addWidget(self.frame1, 'frame1', (50,50), anchor='nw')
self.frame2 = tk.Frame(self, background='green', height=50, width=50)
self.frame2.bind('<Key-p>', self.onFrame2Action)
self.frame2.bind('<Key-b>', self.onFrame2Action)
#add frame2 to the hover pool
hoverpool.addWidget(self.frame2, 'frame2', (105,50), anchor='nw')
def onFrame1Action(self, event):
if event.char == 'p':
self.frame1['background'] = 'purple'
if event.char == 'b':
self.frame1['background'] = 'black'
def onFrame2Action(self, event):
if event.char == 'p':
self.frame2['background'] = 'pink'
if event.char == 'b':
self.frame2['background'] = 'blue'
if __name__ == '__main__':
app = App()
app.title(App.TITLE)
app.geometry(f'{App.WIDTH}x{App.HEIGHT}')
app.resizable(width=False, height=False)
app.mainloop()