如何清空Tkinter画布?

58

当我使用以下命令绘制形状:

canvas.create_rectangle(10, 10, 50, 50, color="green")

Tkinter是否会跟踪它被创建的事实?

在我编写的一个简单游戏中,我的代码有一个Frame来创建一堆矩形,然后绘制一个大的黑色矩形来清除屏幕,然后再绘制另一组更新后的矩形,以此类推。

我是否正在内存中创建数千个矩形对象?

我知道你可以将上面的代码分配给一个变量,但如果我不这样做,直接绘制到画布上,它是否会保留在内存中,还是只是像HTML5画布一样绘制像素?

答案:

Tkinter会跟踪其创建的事实。如果不将代码分配给变量并直接绘制到画布上,则会在每次绘制时创建新的矩形对象,可能会导致内存问题。

3个回答

114
每个画布项都是Tkinter跟踪的对象。如果您只是通过绘制黑色矩形来清除屏幕,则实际上已经创建了内存泄漏--最终,由于已绘制了数百万个项,您的程序将崩溃。
要清除画布,请使用delete方法。给它特殊参数"all"以删除画布上的所有项(字符串"all""是表示画布上所有项的特殊标记):
canvas.delete("all")

如果您想仅删除画布上的特定项目(例如前景对象),而保留背景对象,则可以为每个项目分配标签。然后,您可以提供标签名称而不是“all”。如果您正在创建游戏,则可能不需要删除和重新创建项目。例如,如果您有一个在屏幕上移动的对象,可以使用movecoords方法来移动该项。

如果您没有将该行分配给变量,该如何获取标签的名称? - Andrei
这个方法对我不起作用。错误信息:``File "C:\Users\Wei-shan\Desktop\macauWorldHeritageSites.py", line 127, in <module> canvas.delete("all") File "D:\anaconda3\lib\site-packages\vpython\vpython.py", line 2836, in delete self.addmethod('delete','None')AttributeError: 'str' object has no attribute 'addmethod'`` - Wei Shan Lee
@LEEWEISHAN:这个错误提示你的 canvas 变量包含一个字符串。它不是一个画布,因此它没有与画布相同的方法。 - Bryan Oakley
我稍微修改了一下,首先设置了画布的实例: scene = canvas(center=vector(0.5, 0, 5, 0), background=color.white) 然后 scene.delete() - Wei Shan Lee
我的程序为什么每次更新画布都会变得越来越慢呢? - M lab

12

绘制到画布上的图形是持久存在的。 create_rectangle 返回一个项目 ID,您需要跟踪它。如果不删除旧项目,程序最终会变慢。

来自Fredrik Lundh的An Introduction to Tkinter:

请注意,添加到画布的项目将保留,直到您将其删除。如果您想要更改绘图,可以使用像 coordsitemconfigmove 这样的方法修改项目,或者使用 delete 删除它们。


1
有没有一种不需要持久性的绘图方式? - Taylor Hill
3
@TaylorHill: 不行。但是,作为DaveTheScientist,你可以使用canvas标签来收集你的画布小部件。创建小部件时添加参数 tags='my_tag'。然后当你想要清除屏幕时,你可以执行 canvas.delete('my_tag')。所有带有 'my_tag' 标签的canvas小部件都将被删除。 - Steven Rumbalski

3

是的,我相信你正在创建成千上万个对象。如果你想找一个简单的方法一次性删除它们中的许多,可以使用画布标签在这里描述。这样可以在大量对象上执行相同的操作(如删除)。


如果我给一堆形状分配相同的ID,比如“tile”,然后在ID“tile”上执行删除方法,它会一次性删除所有形状吗? - Taylor Hill
1
@TaylorHill 这个旧帖子,但我仍然要指出:Canvas项目ID都是唯一的,你说的是标签。 - Artemis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接