Mathematica 中 Manipulate[] 的自定义控制器

发布于 2024-12-26 07:23:04 字数 800 浏览 2 评论 0原文

我创建了一个函数 test[],如果需要的话,它也可以是符号测试,并且我正在尝试在操作中实现它。 test[] 看起来像这样:

test[]:=Button["Label",Functionality[]];

如果直接在 Manipulate[] 中使用,这将返回错误,但如果它包装在 Dynamic 或 Evaluate 中,则有效。

Manipulate[content,test[]];

Manipulate::vsform:Manipulate 参数 test[] 没有变量规范的正确形式。

Manipulate[content,Dynamic[test[]]]

这个有效

Manipulate[content,Evaluate[test]]

请注意,虽然这个有效,但测试不是一个函数

Manipulate[content,Evaluate[test[]]]

这适用于我的 mac,但不适用于我工作的 PC...

我认为问题与 Manipulate 为 HoldAll 有关,但不明白为什么 Dynamic[ ] 应该解决这个问题。另外,Evaluate[] 只能在某些时候起作用。

那么,为什么需要 Dynamic[] 或 Evaluate[] 呢?查看高级操作教程的自定义控制器部分,我没有看到任何对此问题的引用,并且在其他地方找不到任何内容。

I've created a function test[], which could also be a symbol test, if need be, and I'm trying to implement it in a manipulate. test[] looks like this:

test[]:=Button["Label",Functionality[]];

This will return an error if used directly in a Manipulate[], but works if it is wrapped in a Dynamic or an Evaluate.

Manipulate[content,test[]];

Manipulate::vsform: Manipulate argument test[] does not have the correct form for a variable specification.

Manipulate[content,Dynamic[test[]]]

This one works

Manipulate[content,Evaluate[test]]

Note that while this works, test is not a function

Manipulate[content,Evaluate[test[]]]

This works on my mac, but not my PC at work...

I think the issue is something to do with Manipulate being HoldAll, but don't understand why Dynamic[] should fix this. Also, Evaluate[] will only work some of the time.

So, why is the Dynamic[] or Evaluate[] necessary? Looking under the custom controllers section of the advanced manipulate tutorial, I see no references to this issue, and could not find any elsewhere.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深者入戏 2025-01-02 07:23:04

您可以内联 Button,而不是使用单独的 test[] 函数。否则,您上一个示例,Manipulate[content,Evaluate[test[]]]确实在 Mathematica 8 中的我的机器上显示按钮。平台之间应该没有区别( Windows 或 Mac)。

如果您正在做的事情与 Manipulate 默认提供的内容完全不同,您可能会发现使用 Dynamic 从头开始​​构建它更方便(这是我通常所做的) 。


以下是如何将一些按钮作为控制器包含在内的示例。

首先,设置要在 Manipulate 中显示的内容:

rotate90[{x_, y_}] := {-y, x}

koch[p1_, p2_, n_] := {koch[p1, p1 + (p2 - p1)/3, n - 1], 
  koch[p1 + (p2 - p1)/3, (p1 + p2)/2 + Sqrt[3]/6 rotate90[p2 - p1], 
   n - 1], koch[(p1 + p2)/2 + Sqrt[3]/6 rotate90[p2 - p1], 
   p2 - (p2 - p1)/3, n - 1], koch[p2 - (p2 - p1)/3, p2, n - 1]}

koch[p1_, p2_, 0] := Line[{p1, p2}]

snowflake[n_] := 
 Graphics[{koch[{0, 0}, {1, 0}, n], 
   koch[{1, 0}, {1/2, -Sqrt[3]/2}, n], 
   koch[{1/2, -Sqrt[3]/2}, {0, 0}, n]}]

然后设置 Manipulate 本身:

Manipulate[snowflake[n], {{n, 2}, ControlType -> None}, 
 Style["A Koch snowflake", Bold], Delimiter, 
 Row[{Button["+", n++], Button["-", n = Max[n - 1, 0]]}]]

Mathematicagraphics


这是一个示例,表明即使 Button 是在单独的函数中定义的,这也可以工作:

SetAttributes[paletteButton, HoldRest]
paletteButton[name_, func_] := 
 Button[name, func, Appearance -> "Palette"]

Manipulate[snowflake[n], {{n, 2}, ControlType -> None}, 
 Style["A Koch snowflake", Bold], Delimiter, 
 Evaluate@paletteButton["+", n++]]

正如您在问题中提到的,这里有必要将该函数包装在 <代码>评估获取内联Button。否则,Manipulate 将无法注意到我们这里是一个控件,而不是变量

You can inline the Button instead of using a separate test[] function. Otherwise you last example, Manipulate[content,Evaluate[test[]]], does show the button on my machine in Mathematica 8. There should be no difference between platforms (Windows or Mac).

If you're doing something sufficiently different from what Manipulate provides by default, you may find it more convenient to build it from scratch using Dynamic (this is what I usually do).


Here's an example of how to include some buttons as controllers.

First, set up something to show inside the Manipulate:

rotate90[{x_, y_}] := {-y, x}

koch[p1_, p2_, n_] := {koch[p1, p1 + (p2 - p1)/3, n - 1], 
  koch[p1 + (p2 - p1)/3, (p1 + p2)/2 + Sqrt[3]/6 rotate90[p2 - p1], 
   n - 1], koch[(p1 + p2)/2 + Sqrt[3]/6 rotate90[p2 - p1], 
   p2 - (p2 - p1)/3, n - 1], koch[p2 - (p2 - p1)/3, p2, n - 1]}

koch[p1_, p2_, 0] := Line[{p1, p2}]

snowflake[n_] := 
 Graphics[{koch[{0, 0}, {1, 0}, n], 
   koch[{1, 0}, {1/2, -Sqrt[3]/2}, n], 
   koch[{1/2, -Sqrt[3]/2}, {0, 0}, n]}]

Then set up the Manipulate itself:

Manipulate[snowflake[n], {{n, 2}, ControlType -> None}, 
 Style["A Koch snowflake", Bold], Delimiter, 
 Row[{Button["+", n++], Button["-", n = Max[n - 1, 0]]}]]

Mathematica graphics


Here's an example showing that this works even if the Button is defined in a separate function:

SetAttributes[paletteButton, HoldRest]
paletteButton[name_, func_] := 
 Button[name, func, Appearance -> "Palette"]

Manipulate[snowflake[n], {{n, 2}, ControlType -> None}, 
 Style["A Koch snowflake", Bold], Delimiter, 
 Evaluate@paletteButton["+", n++]]

As you mentioned in your question, here it is necessary to wrap the function in Evaluate to obtain an inlined Button. Otherwise Manipulate will not be able to notice that what we have here is a control and not a variable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文