到目前为止,每当我需要在tkinter画布上使用多种形状时,它们就是那种形状。我用canvas.find_all()
得到了他们的标签,并通过移动,调整大小等来操纵他们的几何
但我碰到了这个问题,我似乎无法解决这个问题
如果我定义了一个自己的类并将该对象绘制到画布上,我如何跟踪画布上的所有对象,以便调用它们的方法?
假设我定义了一个Bubble
类,它会在屏幕上绘制一个起泡的东西。每一秒之后,我希望它能改变所有气泡。使用change_colour
方法将颜色转换为其他颜色。
my_list = []
for n in range(10):
bubble = Bubble()
my_list.append(bubble)
while True:
time.sleep(1)
for item in my_list:
item.change_colour()
我可以将它附加到一个大的列表中,然后像我在这里一样迭代它,但对于有更多对象的情况,这太慢了!
这样做的正确方法是什么?
像往常一样,谢谢你的帮助!
正如所指出的,time.sleep()
没有任何意义,但这不是我想要解决的问题。
答案 0 :(得分:1)
如果您想对每个项目执行自定义的个别更改(例如,将每个项目的颜色更改为全新的随机颜色),那么除了遍历每个项目并调用itemconfig
之外,您无法做得更好他们个人。
但是,如果您想对每个项目进行相同的更改,则可以使用该标记作为说明符标记您的项目并一次调用itemconfig
。
示例:
import Tkinter
import random
root = Tkinter.Tk()
canvas = Tkinter.Canvas(root, width=400, height=400)
canvas.pack()
for i in range(1000):
x = random.randint(0, 400)
y = random.randint(0, 400)
canvas.create_oval((x-5,y-5,x+5,y+5), fill="white", tags=("bubble"))
current_color = "white"
def change_colors():
global current_color
current_color = "white" if current_color == "black" else "black"
canvas.itemconfig("bubble", fill = current_color)
root.after(1000, change_colors)
root.after(1000, change_colors)
root.mainloop()
结果:
然而,正如我在之前的评论中指出的那样,我仍然认为这是一个不成熟的优化。即使你有一千个项目,迭代它们并单独配置它们并不比使用标签那么慢。例如:
import Tkinter
import random
root = Tkinter.Tk()
canvas = Tkinter.Canvas(root, width=400, height=400)
canvas.pack()
items = []
for i in range(1000):
x = random.randint(0, 400)
y = random.randint(0, 400)
id = canvas.create_oval((x-5,y-5,x+5,y+5), fill="white")
items.append(id)
current_color = "white"
def change_colors():
global current_color
current_color = "white" if current_color == "black" else "black"
for id in items:
canvas.itemconfig(id, fill = current_color)
root.after(1000, change_colors)
root.after(1000, change_colors)
root.mainloop()
答案 1 :(得分:1)
Canvas.find_withtag()
方法将返回第一个参数指定的所有匹配对象的ID列表。您可以将它与字典结合使用,将它们映射回类的相应实例。一旦你有了,你可以调用它的任何方法。
import Tkinter
import random
BUBBLE_TAG = 'Bubble'
current_color = 'white'
class Bubble(object):
def __init__(self, canvas, x, y, size, color):
self.canvas = canvas
self.id = canvas.create_oval((x-5,y-5,x+5,y+5), fill=color,
tags=BUBBLE_TAG)
def change_color(self, new_color):
self.canvas.itemconfigure(self.id, fill=new_color)
root = Tkinter.Tk()
canvas = Tkinter.Canvas(root, width=400, height=400)
canvas.pack()
mapping = {}
for i in range(1000):
x, y = random.randint(0, 400), random.randint(0, 400)
color = 'black' if random.randint(0, 1) else 'white'
obj = Bubble(canvas, x, y, 5, color)
mapping[obj.id] = obj
def change_colors():
for id in canvas.find_withtag(BUBBLE_TAG):
current_color = canvas.itemcget(id, 'fill')
new_color = 'black' if current_color == 'white' else 'white'
mapping[id].change_color(new_color) # calls method of object
root.after(1000, change_colors)
root.after(1000, change_colors)
root.mainloop()
以下是其运行示例: