我可以在行走时修改Tcl struct :: graph吗?

时间:2019-05-09 11:52:11

标签: tcl

Tcl struct::graph有一个walk命令,我想用它来删除节点并清理可由节点属性访问的数据,例如小部件名称。该文档没有说明在行走图形时可以做什么和不能做什么,因此我想知道如果我开始移除行走节点附近的弧线会如何工作。

这是我想要的行走命令(几乎完成了,可能是其中的错误):

proc csp_scene_walk_remove {mode g n} {
  set canvas [$g get canvas]
  foreach arc [$g arcs -adj $n] {
    $canvas delete [$g arc get $arc widget]
  }
  $canvas delete [$g node get $n widget] [$g node get $n widgetanno] [$g node get $n widgetanno].bg
  $g node delete $n
}

我想如果walk在实际的图形对象上而不是副本上工作,数据会在适当的时候在内部复制等,那么它可能会起作用。

问:如果在行走时修改图形,则stuct :: graph walk的行为是什么?


编辑:该命令似乎可以执行我想要的操作:

# destroy all nodes downstream with associated widgets
mygraph walk $node -order post -type dfs -dir forward -command csp_scene_walk_remove;

但是我不能确定这是否是Tcllib看到的实现定义的行为。

1 个答案:

答案 0 :(得分:1)

尽管您的工作可以正常进行,但您可以置疑,因为并发修改错误很容易解决。因此,最简单的方法是累积遍历树时要删除的节点列表,然后使用$graph node delete {*}$theNodes之后将其全部删除。除了我们可以将要累积的节点列表保留在图形本身之外,这可以简化一些事情。

proc csp_scene_walk_remove {mode g n} {
    upvar #0 $nodeAccumulator nodes
    set canvas [$g get canvas]
    foreach arc [$g arcs -adj $n] {
        $canvas delete [$g arc get $arc widget]
    }
    $canvas delete [$g node get $n widget] [$g node get $n widgetanno] \
            [$g node get $n widgetanno].bg
    $g lappend deadNodes $n
}

mygraph set deadNodes {}
# Order of traversal is unimportant; nodes remain until afterwards
mygraph walk $node -command csp_scene_walk_remove
# NB: Expanding substitution is very useful here!
mygraph node delete {*}[mygraph get deadNodes]
mygraph unset deadNodes

我很想给每个节点的画布项目一个通用标签(例如,节点ID!),然后使用它来删除它们,这样我就不需要跟踪很多东西的画布ID。 ,但这取决于您…