Tkinter中的item configure方法无效
我尝试在我的小项目中使用Tkinter库,这个项目是用Python写的。我创建了一个500乘500的正方形,里面有10000个小正方形。
我希望每当用户点击一个小正方形时,它就变成黑色。有人能告诉我为什么吗?我会非常感激的。下面是我的图形代码:
from Tkinter import *
from button import *
class AppFrame(Frame):
def __init__(self):
self.root = Tk()
self.root.geometry = ("1000x1000")
self.f = Frame(self.root, relief = 'sunken', width = 600, height = 600)
self.w = Canvas(self.f,width = 505, height =505)
##get the x, y value whenever the user make a mouse click
self.w.bind("<Button-1>", self.xy)
self.bolist = []
for k in range(1,101):
for i in range(1, 101):
button = Buttons(self.w, i * 5, k * 5, i * 5 + 5, k * 5 + 5)
self.bolist.append(button)
self.f.grid(column =0, columnspan = 4)
self.w.grid(column = 0)
self.root.mainloop()
def xy (self, event):
self.x, self.y = event.x, event.y
print (self.x, self.y)
##check each button if it's clicked
for hb in self.bolist:
if hb.clicked(self.x, self.y):
print ("hurry")
hb.activate()
还有
##button.py
from Tkinter import *
class Buttons:
def __init__(self,canvas,bx,by,tx,ty):
self.canvas = canvas
self.rec = canvas.create_rectangle((bx,by,tx,ty),fill = "lightgray",
activefill= 'black', outline = 'lightgray')
self.xmin = bx
self.xmax = tx
self.ymin = by
self.ymax = ty
##print (bx, by, tx, ty)
def clicked(self, px, py):
return (self.active and self.xmin <= px <= self.xmax and
self.ymin <= py <= self.ymax)
def activate(self):
self.canvas.itemconfigure(slef.rec, fill = 'black')
self.active = True
2 个回答
1
我看了你的代码,调试了一下,并做了一些调整。现在它可以正常工作了。只要把这两个脚本放在同一个文件夹里,然后运行你的AppFrame脚本(就是这个回答中的第二个脚本)就可以了。
##button.py
from Tkinter import *
class Buttons:
def __init__(self,canvas,bx,by,tx,ty):
self.canvas = canvas
self.rec = canvas.create_rectangle((bx,by,tx,ty),fill = "lightgray", activefill= 'black', outline = 'lightgray')
self.xmin = bx
self.xmax = tx
self.ymin = by
self.ymax = ty
##print (bx, by, tx, ty)
def clicked(self, px, py):
return (self.xmin <= px <= self.xmax and
self.ymin <= py <= self.ymax)
def activate(self):
self.canvas.itemconfigure(self.rec, fill = 'black')
还有
from Tkinter import *
from button import *
class AppFrame(Frame):
def __init__(self):
self.root = Tk()
self.root.geometry = ("1000x1000")
self.f = Frame(self.root, relief = 'sunken', width = 600, height = 600)
self.w = Canvas(self.f,width = 505, height =505)
##get the x, y value whenever the user make a mouse click
self.w.bind("<Button-1>", self.xy)
self.bolist = []
for k in range(1,101):
for i in range(1, 101):
button = Buttons(self.w, i * 5, k * 5, i * 5 + 5, k * 5 + 5)
self.bolist.append(button)
self.f.grid(column =0, columnspan = 4)
self.w.grid(column = 0)
self.root.mainloop()
def xy (self, event):
self.x, self.y = event.x, event.y
print (self.x, self.y)
##check each button if it's clicked
for hb in self.bolist:
if hb.clicked(self.x, self.y):
print ("hurry")
hb.activate()
newApp = AppFrame()
1
问题在于你没有初始化 active
属性,所以在单元格变为活动状态之前,它是不存在的。要解决这个问题,可以在 Buttons
类的 __init__
方法里添加 self.active = False
。
你在这一行也有个拼写错误(注意你写成了 slef
而不是 self
):
self.canvas.itemconfigure(slef.rec, fill = 'black')
与其在画布上使用全局绑定,不如在每个单独的矩形上设置绑定,这样会更高效。你可以利用这个绑定把 Buttons
类的实例传递给回调函数。这样你就不需要遍历几千个小部件去寻找被点击的那个了。
要做到这一点,可以使用画布的 tag_bind
方法。你可以让主程序传入一个函数的引用,当矩形被点击时就调用这个函数,然后绑定可以调用这个方法并传递对自身的引用。
例如:
class Buttons:
def __init__(self,canvas,bx,by,tx,ty, callback):
...
self.rec = canvas.create_rectangle(...)
self.canvas.tag_bind(self.rec, "<1>",
lambda event: callback(self))
...
class AppFrame(Frame):
def __init__(...):
...
button = Buttons(..., self.callback)
...
def callback(self, b):
b.activate()