【发布时间】:2026-01-28 22:45:01
【问题描述】:
我有一个 Mathematica 笔记本,它采用相当复杂的用户界面来控制长时间运行的计算。除此之外,该界面充分利用了Button、RadioButtonBar、Checkbox 和InputField。
当单击Button 的效果是一个可能需要几秒钟以上才能完成的中间计算时,我喜欢提供一个视觉指示,表明代码没有崩溃并且实际上正在做一些有用的事情.一个很好的方法是在中间计算开始之前启动ProgressIndicator,然后在计算完成后将其关闭。我发现这对于单击Button 开始的计算很简单。
但是,对于由更改 InputField 值启动的计算,相同的方法不起作用。下面的简化代码是为此而编写的,但失败了。 Grid 的最后两行应该会在内部Dynamic 命令中的updatingQ 更改为True 时自动更改,然后在updatingQ 恢复为True 时更改回来,但它永远不会发生。看起来外部Dynamic 代码在内部Dynamic 代码运行时被阻止,因此它甚至从未注意到updatingQ 的更改。
另一方面,如果在单独的输入行上手动设置updatingQ=True,Grid 的最后两行将按预期响应。
(BTW, i) Pause[2] 只是中间计算的替身,ii) 我将输入值乘以 Pi 只是为了在替身计算完成时更明显。)
显然,Button 的 action 部分的行为有所不同。同一Dynamic 块中的其他代码可以看到并在更改标志时快速响应。值得注意的是,在这种情况下我使用Method->"Queued"。我对 InputField 进行了同样的尝试(对此它不是一个记录的选项),但没有效果。
我尝试了这里没有显示的其他各种方法,但都没有成功。
我们将不胜感激。
Clear[ProgressIndicatorTest]
updatingQ = False;
ProgressIndicatorTest = {
TextCell["ProgressIndicatorTest", "Subsubsection", Background -> LightBlue],
DynamicModule[
{filterTypes = {"Max energy", "Max length"}, filterValue, workingOn = "", iter = 0},
Scan[(filterValue[#[[1]]] = #[[2]]) &, Transpose@{filterTypes, {0.1, 100.}}];
Dynamic[
Grid[
Join[
Map[
Function[
filterType,
{filterType,
Dynamic@
InputField[
Dynamic[
filterValue[filterType],
Function[
value,
If[value > 0,
updatingQ = True;
Pause[2];
filterValue[filterType] = \[Pi] value;
updatingQ = False
]
]
], FieldSize -> 5, Alignment -> Right
]
}
], filterTypes
],
{{updatingQ, "-------"}},
{If[updatingQ,
{"Updating ... ",
ProgressIndicator[Appearance -> "Indeterminate"]},
Nothing
]}
], Alignment -> Left,
Background -> {None, {LightGreen, LightGreen, LightYellow, LightYellow}}
]
]
]
};
CellGroup[ProgressIndicatorTest]
【问题讨论】:
标签: dynamic wolfram-mathematica