初始化Manipulate,Dynamic,Refresh的问题

时间:2011-09-04 11:48:15

标签: wolfram-mathematica

我在Manipulate中使用以下模式

Dynamic[Refresh[....logic to handle v changes...., TrackedSymbols->{v}]]

设置逻辑。

我使用上面的代码来表示'事件处理程序',其中'v'是用户更改的控件变量。因此,当特定控制变量发生变化时,会有特定的代码来处理处理这个变量所需的逻辑所需的逻辑。这模拟了其他GUI编程系统中的“回调”。

这非常有效。除了初始化时,由于Manipulate首先出现在屏幕上,即使没有我更改幻灯片,Manipulate也会“触发”这些刷新。

此外,它不能依赖于它决定“触发”刷新的顺序。这使得初始化程序状态变得很困难。

这是一个例子

Manipulate[

 Row[{
   Dynamic[Refresh[Print["x changed"]; {x, y, z}, TrackedSymbols -> {x}]],
   Dynamic[Refresh[Print["y changed"];  "", TrackedSymbols -> {y}]],
   Dynamic[Refresh[Print["z changed"];  "", TrackedSymbols -> {z}]]
   }
  ]
 ,
 {{x, 1, "x"}, 0, 10},
 {{y, 1, "y"}, 0, 10},
 {{z, 1, "z"}, 0, 10}
 ]

如果您运行上述操作,您会注意到3条打印消息,而不触及控件。

我的问题:有没有办法阻止这种初始刷新?我希望在使用滑块实际更改变量时运行刷新代码。

你可能会说,最重要的是,让它最初刷新并运行逻辑,好像变量确实由用户改变了一样。

是的,我现在就这样做。但我试图通过减少不必要的工作来提高效率。由于每次控制变量发生变化时代码都会运行一些长计算,这使得Manipulate在首次出现时花费的时间比需要的时间多,因为每个控制变量中的计算必须运行一次。

我可以引入一个额外的'状态变量'来控制它,并在开始实际工作之前通过计数检查所有事件是否已“触发”一次。一旦所有事件触发一次,我可以将此变量设置为True,并且仅在事件触发时运行实际代码,并且此状态变量也为真。

但我想问一下,如果没有在代码中引入更复杂的逻辑,可能会有内置方式或更智能的方法来处理这个问题,因为我找不到一个选项或设置来处理这个问题。

谢谢,

1 个答案:

答案 0 :(得分:2)

所以,这不是一般而且不漂亮,只是一种解决方法,但它可以做你想要的:

  Manipulate[Module[{refx, refy, refz}, 
   If[{x,y,z} == {1,1,1}, {x, y, z}, 
    Row[{Dynamic[Refresh[
        Print["x changed"]; 
         {x, y, z}, TrackedSymbols -> 
         {x}]], Dynamic[Refresh[
        Print["y changed"]; "", 
        TrackedSymbols -> {y}]], 
      Dynamic[Refresh[
        Print["z changed"]; "", 
        TrackedSymbols -> {z}]]}]]], 
  {{x, 1, "x"}, 0, 10}, 
  {{y, 1, "y"}, 0, 10}, 
  {{z, 1, "z"}, 0, 10}]