How to| 在 Dynamic 或 Manipulate 内部计算表达式
Dynamic 和 Manipulate 的持有属性对于它们能够正确工作是至关重要的. 然而,这些持有属性可能会对您想进行的其它结构式运算产生干扰. 本 "How to" 将介绍关于 Dynamic、Manipulate 及其它持有结构的有用方法.
请注意,由于这些范例的性质使然,有些输出没有在文件中存储. 您必须随着阅读对输入进行运算,这些范例才有意义.
numbers = RandomReal[1, 5];Dynamic[numbers]接下来的输入创建了一个滑块列表,其中,第一个滑块显著改变数列中的第一个值,第二个滑块改变第二个值,依此类推:
{Slider[Dynamic[numbers[[1]]]], Slider[Dynamic[numbers[[2]]]], Slider[Dynamic[numbers[[3]]]], Slider[Dynamic[numbers[[4]]]], Slider[Dynamic[numbers[[5]]]]}您可能希望更轻松地创建该滑块列表,例如使用 Table. Dynamic 的属性 HoldFirst 这时可以起作用,阻止 Table 变量的值被筛到表达式中. 因此下面的这个尝试失败,我们看到的是 numbers[[i]],而不是numbers[[1]]、numbers[[2]] 等. 注意到 i 的语法着色,对这一操作发出警告:
Table[Slider[Dynamic[numbers[[i]]]], {i, 1, 5}]//InputForm要克服这一问题,可用作用域结构 With 将局部变量 i 的所有值立即替换为它所对应的值:
Table[With[{i = i}, Slider[Dynamic[numbers[[i]]]]], {i, 1, 5}]//InputForm去除 InputForm 的包装,带给我们的是格式化的滑块:
Table[With[{i = i}, Slider[Dynamic[numbers[[i]]]]], {i, 1, 5}]Dynamic[numbers]在 Manipulate 中构建控件集时,也可使用同样的方法. 下面是一个 Manipulate,它的第一个滑块指定的是要显示的其它滑块的数目. 其它滑块被包在 Panel 中,以便视觉上清晰. 请再次注意在创建滑块的 Table 中 With 的使用:
Manipulate[Take[lis, n], {{lis, ConstantArray[0, 20]}, ControlType -> None}, {n, 1, 20, 1}, Dynamic[Panel[Column[Table[With[{i = i}, Slider[Dynamic[lis[[i]]]]], {i, n}]]]]]这是一个相似的情形,其中与数据变量相关的复选框的个数基于其它 Manipulate 控件的值而变化:
Manipulate[Grid[Take[data, h, w]], {{data, RandomInteger[1, {10, 20}]}, ControlType -> None}, {{w, 10}, 1, 20, 1}, {{h, 3}, 1, 10, 1}, Dynamic[Panel[Grid[Table[With[{i = i, j = j}, Checkbox[Dynamic[data[[i, j]]], {0, 1}]], {i, h}, {j, w}]]]]]建立一个对控件编号的 Manipulate:
Manipulate[{x[1], x[2], x[3]}, {x[1], 0, 1}, {x[2], 0, 1}, {x[3], 0, 1}]您也可以通过直接建立必要的编号控件结构,建立一个具有任意控件数目的 Manipulate. 在该例中,Block 用于防止 x 的任何全局定义对这些结构化操作产生干扰:
Block[{x, n = 10},
Manipulate @@ {
Table[x[i], {i, n}],
Sequence @@ Table[{x[i], 0, 1}, {i, n}]}]