在Tkinter中堆叠订单维护

时间:2012-03-06 00:06:33

标签: tkinter

有没有办法在Tkinter中保持小部件(特别是图像)的一致堆叠顺序?例如,我可能在画布上的相同位置有两个矩形,两个三角形和一个圆圈。圆圈移动到鼠标最后点击的位置,但我总是希望它在矩形顶部和三角形后面绘制。默认行为当然是将最后绘制的对象放在最上面的给定位置。

到目前为止,我只发现了lift()和lower()方法来解决Tkinter中的堆叠问题。理论上,我可以在每次重新绘制时进行一些杂乱的检查,看看三角形是否存在于目的地,并为那里的每个形状做一些lift()/ lower(),直到我想要的方式,但这似乎是一个荒谬的解决方案。我期望在画布对象上有一种“层”变量,因此它会被动地记住第3层的项应该总是在第1层的后面。

如果有一个简单的方法可以解决我的问题,我很抱歉,但到目前为止我所有的搜索都无济于事。我会感激任何意见!

1 个答案:

答案 0 :(得分:6)

用“三角形”标记所有三角形,用“矩形”标记所有矩形,用“圆形”标记所有圆形。然后,您可以使用liftlower方法一次升高或降低所有三角形,圆形或矩形。这需要几个陈述,即使你有数以千计的物品,也会在不到一眨眼的时间内发生。

因为您询问了内置层机制:tk没有这样的东西,但它很容易添加,所有工具都在那里。因此,不要在任何地方撒上liftlower命令,而是让所有绘图都通过一个特殊的命令来处理分层。

例如,这是一个接受图层编号的命令示例,并确保它绘制的所有内容都在该图层上:

def add_to_layer(self, layer, command, coords, **kwargs):
    layer_tag = "layer %s" % layer
    if layer_tag not in self._layers: self._layers.append(layer_tag)
    tags = kwargs.setdefault("tags", [])
    tags.append(layer_tag)
    item_id = command(coords, **kwargs)
    self._adjust_layers()
    return item_id

def _adjust_layers(self):
    for layer in sorted(self._layers):
        self.canvas.lift(layer)

然后你会这样称呼它:

# draw a circle on layer 1:
self.add_to_layer(1, self.canvas.create_oval, (x0,y0,x1,y1), outline="red")
# draw a square on layer 2:
self.add_to_layer(2, self.canvas.create_rectangle, (x0,y0,x1,y1), fill="blue")

还有很多其他方法可以完成同样的事情,上面只是一个快速而肮脏的例子,我的头顶(并不保证100%正确,但我认为这说明了这一点)。

基本思想是所有对象创建都通过一个功能,可以在每次创建项目时调整堆叠顺序。这样你只需要在一个地方添加这些提升/降低命令。