【问题标题】:How to make selective drop down menu in Mathematica?如何在 Mathematica 中制作选择性下拉菜单?
【发布时间】:2011-12-07 12:50:48
【问题描述】:

我的 Manipulate 界面空间不足。所以,我想看看是否可以重载 PopupMenu 以服务于多个目的。

问题来了:

我有一个 PopupMenu 用于从中选择一个条目。但是根据我在其他地方所做的另一个选择,菜单中的某些条目将不再有意义。

所以,我想知道,是否可以根据动态设置使 PopupMenu 中的某些条目“可选择”? (可能被禁用,或变灰,或者最好的是,让整个列表本身通过动态,即整个弹出菜单是动态的,所以我可以根据另一个动态的值选择不同的菜单。但我不认为这个是可能的)

目前,可以根据动态设置启用或禁用整个 PopupMenu。但我想在 Popupmenu 内的入门级执行此操作。

这里有一个例子来说明:

Manipulate[selection,
 Grid[{
   {"x", SetterBar[Dynamic[x], {1, 2}]},
   {"selection", PopupMenu[Dynamic[selection],
     {
      "NONE", "SOR", "SSOR"
      }, Enabled -> Dynamic[x == 1]], SpanFromLeft
    }
   }]
 ]

在上面,当X=1时,整个菜单被启用。

但我想要的是,如果 X=1,只能选择说“NONE”(或列表只显示“NONE”),而当 X=2 时,只能选择“SOR”和“SSOR”(或列表仅显示这两个选项)。

即如果 x=2,系统将不允许选择“SOR”。尝试选择它不会导致任何更改,并且菜单将保持其先前的设置并且不会更改。

再一次,我知道我可以将事情分成 2 个 popuMenus,并根据下面的 X 设置控制每个,但我没有更多空间来添加更多菜单:

Manipulate[If[x == 1, selectionA, selectionB],
 Grid[{
   {"x", SetterBar[Dynamic[x], {1, 2}]},
   {"selection", PopupMenu[Dynamic[selectionA],
     {
      "NONE"
      }, Enabled -> Dynamic[x == 1]], SpanFromLeft
    },
   {"selection", PopupMenu[Dynamic[selectionB],
     {
      "SOR", "SSOR"
      }, Enabled -> Dynamic[x == 2]], SpanFromLeft
    }
   }]
 ]

我的问题是:有没有办法在 Mathematica 中执行上述操作?我正在使用 8.04。

最好的解决方案是让菜单本身的项目列表由动态(或整个菜单是动态的),所以我可以告诉它在 X=1 时使用 listA 或在 X=2 时使用 listB 等。 . 但我不知道如何做到这一点,甚至不知道它是否可能。

ps。这是我目前的解决方案尝试

Manipulate[selection,

 Grid[{
   {"x", SetterBar[Dynamic[x], {1, 2}]},
   {"selection", PopupMenu[Dynamic[selection],
     {
      Dynamic[If[x == 1, listA, listB]]
      }
     ]
    }
   }
  ],
 Initialization :>
  (
   listA = {"A", "B"};
   listB = {"C", "D"};
   )
 ]

但它还不是很好。会坚持下去的……

谢谢

更新:

看看下面的 Simon 解决方案给了我更多启发,所以这就是我目前所拥有的:

Manipulate[selection,

 Grid[{
   {"x", SetterBar[Dynamic[x], {1, 2}]},
   {"selection",

    Dynamic[If[x == 1,
      (
       selection = "A";
       PopupMenu[Dynamic[selection], {"A", "B"}]
       ),
      (
       selection = "C";
       PopupMenu[Dynamic[selection], {"C", "D"}]
       )
      ]
     ]
    }
   }
  ]
 ]

【问题讨论】:

    标签: wolfram-mathematica


    【解决方案1】:

    这是你要找的东西吗?

    Manipulate[
     Switch[x,
            1, If[selection =!= None, selection = None],
            2, If[selection === None, selection = "SOR"]];
     selection,
     {x, {1, 2}, ControlType -> SetterBar},
     {{selection, None}, Switch[x, 1, {None}, 2, {"SOR", "SSOR"}, _, {"huh"}], 
      ControlType -> PopupMenu}]
    

    请注意顶部的Switch,当x 更改时控制selection 的默认值。


    编辑:

    根据您的要求,将菜单逻辑本地化到控件 Grid 并窃取 Heike 的默认机制,这是一个新版本:

    Manipulate[selection,
     Grid[With[{menu = {{None}, {"A", "B"}, {"emu", "num"}}},
       {{"Which menu?", SetterBar[Dynamic[x], Range[Length[menu]]]},
        {"Menu selection:", Dynamic[
          If[MemberQ[menu[[x]], selection], selection = menu[[x, 1]]];
          PopupMenu[Dynamic[selection], menu[[x]]]]}}]],
     {{selection, None}, None}, {{x, 1}, None}]
    

    请注意,menu 列表不需要使用 With 语句进行本地化 - 它可以在代码的其他位置设置。

    【讨论】:

    • +1,谢谢!你有一个很好的解决方案。如果可能的话,我想将所有逻辑封装在 popemenu 中,以便于管理(我的程序变得非常大)。您的解决方案让我们看到了方向。请查看我的编辑,看看我现在是否根据您的见解修改了我之前的内容,看看它是否适合您。会接受您的回答,但让我们看看是否有人能想出更好的方法:)... Mathematica 非常灵活。很多时候,我认为在 Mathematica 中不可能做某事,但有一种方法可以做到。
    【解决方案2】:

    此解决方案类似于 Simon 的答案,但它没有明确使用列表的数量,因此它应该适用于任意数量的列表

    choices = {{"a", "b", "c"}, {None}, {"e", "f"}};
    
    Manipulate[
     If[Not[MemberQ[x, selection]], selection = x[[1]]];
     selection,
     {{x, choices[[1]]}, MapIndexed[# -> #2[[1]] &, choices], SetterBar}, 
     {selection, x, ControlType -> PopupMenu}]
    

    【讨论】:

      猜你喜欢
      • 2015-09-30
      • 1970-01-01
      • 1970-01-01
      • 2020-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-19
      相关资源
      最近更新 更多