我在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,并且仅在事件触发时运行实际代码,并且此状态变量也为真。
但我想问一下,如果没有在代码中引入更复杂的逻辑,可能会有内置方式或更智能的方法来处理这个问题,因为我找不到一个选项或设置来处理这个问题。
谢谢,
答案 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}]