我尝试在每个单元格上绘制一个带有标记的3x3板。 只有在用鼠标触摸细胞时,才会显示此标记。 这可以工作一次,两次,有时是三次 - 但事件循环会激活'无限地(总是同一个事件)......
import tkinter as tk
cellsize = 50
class Board(tk.Canvas):
def __init__(self):
tk.Canvas.__init__(self)
for row in range(3):
for column in range(3):
ulx, uly = column*cellsize, row*cellsize
lrx, lry = ulx+cellsize, uly+cellsize
_cell = self.create_rectangle(ulx, uly, lrx, lry,
fill='green')
_right = self.create_rectangle(ulx+39, uly+20, lrx-1, lry-20,
fill='red',
state='hidden')
self.tag_bind(_cell, '<Enter>',
lambda e, r=_right: self.show_pos('on', r))
self.tag_bind(_cell, '<Leave>',
lambda e, r=_right: self.show_pos('off', r))
def show_pos(self, onoff, right):
print('{} {}'.format(onoff, right))
if onoff == 'on':
self.itemconfig(right, state='normal')
elif onoff == 'off':
self.itemconfig(right, state='hidden')
root = tk.Tk()
Board().grid()
root.mainloop()
也许这很适合self.itemconfigure语句,因为做其他事情(例如更新状态行)按预期工作。
有解决方法吗?
提前谢谢
马文
增加:
更确切地说:它似乎坚持“状态= ......&#34;
将itemconfig更改为&#39; fill = ...&#39;在&#39; show_pos&#39;按预期工作。
所以标题应该是
&#39; canvas.itemconfig(state =&#39; ...&#39;导致无限的事件循环&#39;
答案 0 :(得分:0)
使用鼠标位置方法,您可以使用:
class BoardX(tk.Canvas):
__cells=None
__indicators=None
def __init__(self):
tk.Canvas.__init__(self)
self.__cells=[]
self.__indicators=[]
self.bind('<Motion>', self.show_pos)
for row in range(3):
for column in range(3):
ulx, uly = column*cellsize, row*cellsize
lrx, lry = ulx+cellsize, uly+cellsize
self.__cells.append(self.create_rectangle(ulx, uly, lrx, lry,
fill='green', tags="cell"))
self.__indicators.append(self.create_rectangle(ulx+39, uly+20, lrx-1, lry-20,
fill='red',
state='hidden', tags="indicator"))
def show_pos(self, event):
""" Get closest widget or widget that we are above,
tagged "cell" and indicate it
"""
# the loop is needed for not to run into value errors
halo=0
widget = self.find_closest(event.x, event.y, halo=halo)
# edit - avoid loop!
if not widget[0] in self.find_withtag("cell"):
return
index = self.__cells.index(widget[0])
for i in range(len(self.__indicators)):
state='hidden'
if i == index:
state='normal'
self.itemconfig(self.__indicators[i], state=state)
这不会触发您在进场中绑定的事件,因此应解决您的问题。
如果您因任何原因不想采用此方法,则只能绑定enter
并使用find_withtag("indicator")
隐藏所有其他指标 - 方法
修改的 纠正代码示例以避免循环。