问题描述
我有一个tkinter画布窗口,试图使用方法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,'<Enter> <p>',self.parameter_window_operator )
self.element_block = self.canvas.create_window( (0,'<Enter p>','<Enter-p>','<Enter+p>',self.parameter_window_operator )
以上方法均无法提供我想要的结果,当鼠标悬停在画布窗口上方并按下Alpha键时,会启动回调方法。
感谢您的帮助,谢谢。
解决方法
甚至不用担心tag_bind
。您可能移动得太快而无法注册事件。我知道原因,这是我的第一个解决方案,即使正常使用鼠标也可以,但是如果不使用它,则很容易损坏。请尝试以下方法。
基本上HoverPool
使画布不断检查鼠标下的内容。如果某个东西在“ hoverpool”中被触发,则focus_set()
被触发,这使得它的键绑定起作用。
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,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,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()