将2个Item []表达式组合到一个表达式以便在宏中使用的任何技巧?

时间:2011-12-27 01:35:49

标签: wolfram-mathematica

V 8.04。这是在Manipulate仅使用的情况下。

这是一个使用Item将控件放在UI中使用Manipulate

的不同位置的简单示例
Manipulate[Plot[Sin[z], {z, -Pi, Pi}, ImageSize -> 100],
 Item[Control[{{x, 0, "x="}, 0, 10, 1,ImageSize->Tiny}],ControlPlacement->Left],
 Item[Control[{{y, 0, "y="}, 0, 10, 1,ImageSize->Tiny}],ControlPlacement->Right]
 ]

enter image description here

但是,我使用Leonid的宏方法(链接here)来帮助我构建我的UI控件,所以我想做类似的事情

 Manipulate[Plot[Sin[z], {z, -Pi, Pi}],

 Evaluate@With[{im = ImageSize -> Tiny},

   Item[Control[{{x, 0, "x="}, 0, 10, 1, im}],ControlPlacement -> Left],
   Item[Control[{{y, 0, "y="}, 0, 10, 1, im}], ControlPlacement -> Right]

   ]    
 ]

以上不起作用,因为我们不再有一个表达式使With满意,其语法为

 With[{x=x0}, expression ]

在上面,2 Item s现在不是一个表达式,而是2。

仅当我想使用Item来控制展示位置时,才会显示此问题。否则,我会使用Grid[]并在Grid内合并我的不同内容,然后问题就解决了。

但我当然不能在网格内部使用Item,以便使每个Item位于不同的位置。整个Grid必须在一个地方。

我认为在Sequence[]中包装2个项目可能会有效,但事实并非如此。

问题是:将上述2个项目合并为一个表达式以使其快乐的任何技巧

目前我在我的用户界面中解决了这个问题,只需将内容分成两个单独的With,如下所示:

Manipulate[Plot[Sin[z], {z, -Pi, Pi}],

 Evaluate@With[{im = ImageSize -> Tiny},
   Item[Control[{{x, 0, "x="}, 0, 10, 1, im}], 
    ControlPlacement -> Left]
   ],

 Evaluate@With[{im = ImageSize -> Tiny},
   Item[Control[{{y, 0, "y="}, 0, 10, 1, im}], 
    ControlPlacement -> Right]
   ]

 ]

它工作正常。

但是,当然,在上面,我失去了使用宏名称在许多控制构造代码之间共享的一些的好处。

更新12/26/11 8:37 PM

这是一个例子,在另一个宏中使用一个宏。我认为这是一个Hold问题。下面显示的技巧不适用于此。将尝试解决这个问题:(在实践中,我使用2级宏,因为我在一个级别定义了一些宏,并使用它们在第二级构建更高级别的宏。这里我只展示了我的非常简单的例子平均值)

Manipulate[Plot[Sin[z], {z, -Pi, Pi}],

 Evaluate@With[{im = ImageSize -> Tiny},

   Evaluate@With[{},

     ## &[
      Item[Control[{{x, 0, "x="}, 0, 10, 1, im}], ControlPlacement -> Left],
      Item[Control[{{y, 0, "y="}, 0, 10, 1, im}], ControlPlacement -> Right]
      ]

     ]
   ]
 ]

我几乎可以肯定,我需要在正确的位置插入HoldAll来对此进行排序。将尝试弄清楚并在此报告。咖啡差不多完成了;)

更新晚上9点

好的,MrWizard向我展示了上面的问题。我应该对内部宏进行评估。我忘了这件事。现在,它现在可以正常工作:

Manipulate[Plot[Sin[z], {z, -Pi, Pi}],

 Evaluate@With[{},

   With[{},
    ## &[
     Item[Control[{{x, 0, "x="}, 0, 10, 1}], ControlPlacement -> Left], 
     Item[Control[{{y, 0, "y="}, 0, 10, 1}], ControlPlacement -> Right]
     ]

    ](*close second With*)
   ](*close first With*)

 ](*close Manipulate*)

感谢您的回答,两者都非常有用。

2 个答案:

答案 0 :(得分:7)

使用Sequence,或许像:

Manipulate[
   Plot[Sin[z], {z, -Pi, Pi}], 
   Evaluate@With[{im = ImageSize -> Tiny}, 
      Sequence @@ {
         Item[Control[{{x, 0, "x="}, 0, 10, 1, im}], ControlPlacement -> Left], 
         Item[Control[{{y, 0, "y="}, 0, 10, 1, im}], ControlPlacement -> Right]
         }
      ]
   ]

修改

相同的方法,但使用不同的宏(警告,这种方式会导致疯狂......)

Manipulate[
   Plot[Sin[z], {z, -Pi, Pi}], 
   Evaluate @ With[{
      control = Function[{var, name, place}, 
         Item[Control[{{var, 0, name <> "="}, 0, 10, 1, ImageSize -> Tiny}],  ControlPlacement -> place], 
         HoldAll
         ]}, 
   Sequence @@ {control[x, "x", Left], control[y, "y", Right]}
   ]]

答案 1 :(得分:6)

不要忘记SequenceApply

Manipulate[Plot[Sin[z], {z, -Pi, Pi}],
 Evaluate[
  Sequence @@ With[{im = ImageSize -> Tiny},
    Hold[
     Item[Control[{{x, 0, "x="}, 0, 10, 1, im}], ControlPlacement -> Left],
     Item[Control[{{y, 0, "y="}, 0, 10, 1, im}], ControlPlacement -> Right]
    ]
   ]
]]

Mathematica graphics

布雷特的回答让我意识到同样的事情可以更加简洁地完成:

Manipulate[
 Plot[Sin[z], {z, -Pi, Pi}],
 Evaluate @ With[{im = ImageSize -> Tiny},
   ## &[
    Item[Control[{{x, 0, "x="}, 0, 10, 1, im}], ControlPlacement -> Left], 
    Item[Control[{{y, 0, "y="}, 0, 10, 1, im}], ControlPlacement -> Right]
   ]
  ]
] 

由于With没有SequenceHold属性,我们无法简单地按顺序[项目,项目],但我们可以使用## &[Item, Item],因为&会延迟评估。