我试图看看我是否可以在Manipulate中创建自己的模拟循环,因为我对Trigger控件或使用Tasks都不满意(两者都有我想做的问题和限制)。
所以,我试图看看我是否可以创建自己的控制循环,这样我可以更好地控制事物,点击“运行”按钮,模拟循环将开始,直到点击“停止”按钮。
一个基本问题是即使我使用SynchronousUpdating -> False
,操作也会在5秒后超时。即,当我单击“运行”按钮时,我开始循环(当然在其中有一些Pause[]
),然后将在循环中更新某些内容。这样可以正常工作,但是5秒后,循环自行停止,因为Manipulate决定超时。
我可能会误解一些基本的东西。我在下面举例说明:
Manipulate[
Dynamic[Refresh[Text@x,TrackedSymbols->{x}]],
{{x,0},ControlType->None},
{{running,True},ControlType->None},
Button[Text["play"],
{
running=True,
While[running,
x+=1;
FinishDynamic[];
Pause[0.1]
]
}],
Button[Text["stop"],
running=False
],
TrackedSymbols->{None},
SynchronousUpdating->False,
SynchronousInitialization->False
]
当运行上述内容时,它总是在大约58秒左右停止,大约是5秒,Manipulate的超时值
Outside Manipulate,它按预期工作正常:
x = 0;
Dynamic[Refresh[x, UpdateInterval -> 0.001]]
Do[
(
x += 1;
FinishDynamic[];
Print[x];
Pause[0.01]
), {i, 0, 200}
]
我可以将上面的数量调到我想要的数量,没问题。
因此,它似乎是Manipulate的一个配置选项,但我现在无法找到我需要使用哪个选项才能使用它。
由于
更新
使用Simon下面给出的Method->“Queued”,现在循环工作了。但是这个方法存在一些问题:在Button运行时我不能使用Mathematica,即使循环中有大的Pauses,因为它会阻塞整个前端。它的行为就像按下按钮一直一样。所以,这个想法是不可能的。嗯,这是尝试的东西。
顺便说一下,现在是提及这一点的好时机,我发现使用'code'类型的单元而不是默认的'input'导致内核中出现很多崩溃。刚试过单元格类型'代码',点击几下按钮后,内核崩溃了:
所以我不再使用“代码”类型的单元格。
回到绘图板。
更新2:8/29/11,下午6点
使用Mathematica 8.0.1,在Windows 7,SP1,intel pc上,这是使用“代码”单元格时崩溃的代码
Manipulate[
Dynamic[Refresh[Text@x,TrackedSymbols->{x},UpdateInterval->0.005]],
{{x,0},ControlType->None},
{{running,True},ControlType->None},
Button[Text["play"],
{
running=True,
While[running,
x+=1;
FinishDynamic[];
]
},Method->"Queued"],
Button[Text["stop"],
running=False
],
TrackedSymbols->{None},
SynchronousUpdating->False,
SynchronousInitialization->False
]
可能有人可以尝试以上?不得不点击开始/停止几次以使其崩溃。
我可以重现这一点。
更新9/2/11
关于新答案:看起来西蒙版(下面的第二篇)在我的电脑上似乎更快,Mathematica 8.0.1。我同时开始,Simon版本似乎运行得更快(计数器运行得更快)。
屏幕截图:
答案 0 :(得分:8)
我认为实际上是Button
超时,而不是Manipulate
。
引用Button docs的Options > Method
部分,
默认情况下,按钮功能在抢先链接上进行评估 5秒后超时:
为按钮设置选项Method -> "Queued"
,一切都按预期工作。
答案 1 :(得分:1)
如果让Manipulate
控制“循环”,您可能会得到更好的结果:
Manipulate[
If[running, x++, x]
, {{x, 0}, ControlType -> None}
, {{running, True}, ControlType -> None}
, Button["play", running = True]
, Button["stop", running = False]
]
我认为此处使用Manipulate
来支持实际应用程序中的进一步控制。如果没有,那么DynamicModule
就足够了。
DynamicModule[{x = 0, running = True}
, Column[
{ Button["play", running = True]
, Button["stop", running = False]
, Dynamic[If[running, x++, x]]
}
]
]
以下示例使用此技术为移动磁盘设置动画:
DynamicModule[{t = 0, running = True}
, Column[
{ Button["play", running = True]
, Button["stop", running = False]
, Dynamic[
If[running, t++, t] /.
t_ :> Graphics[Disk[{Cos[t/10], Sin[t/10]}]
, PlotRange -> {{-3,3},{-3,3}}
, Axes -> True
]
]
}
]
]