关于动态,同步更新的问题,在Manipulate中

时间:2011-08-29 10:39:33

标签: wolfram-mathematica

我试图看看我是否可以在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的超时值

enter image description here

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'导致内核中出现很多崩溃。刚试过单元格类型'代码',点击几下按钮后,内核崩溃了:

enter image description here

所以我不再使用“代码”类型的单元格。

回到绘图板。

更新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
]
可能有人可以尝试以上?不得不点击开始/停止几次以使其崩溃。

我可以重现这一点。

enter image description here

更新9/2/11

关于新答案:看起来西蒙版(下面的第二篇)在我的电脑上似乎更快,Mathematica 8.0.1。我同时开始,Simon版本似乎运行得更快(计数器运行得更快)。

屏幕截图:

enter image description here

2 个答案:

答案 0 :(得分:8)

我认为实际上是Button超时,而不是Manipulate

引用Button docsOptions > 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
                       ]
      ]
    }
  ]
]