如何在 Mathematica 中制作选择性下拉菜单?

发布于 2024-12-20 03:25:53 字数 2365 浏览 2 评论 0原文

我的 Manipulate 界面空间不足。因此,我想看看是否可以重载 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 等。但我不知道如何做到这一点,也不知道这是否可能。

附:这是我目前尝试的解决方案

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"};
   )
 ]

,但效果还不是很好。会坚持下去......

谢谢

更新:

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

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"}]
       )
      ]
     ]
    }
   }
  ]
 ]

在此处输入图像描述

I am running out of space on the Manipulate interface. So, I am looking to see if I can overload a PopupMenu to serve more than one purpose.

Here is the problem:

I have a PopupMenu where I use to select an entry from it. But depending on another choice I make somewhere else, some of these entries in the menu will no longer make sense to select.

So, I was wondering, if I can make some of the entries in the PopupMenu 'selectable' based on a setting of a Dynamic? (may be disabled, or grayed out, or what would be best, have the whole list itself by dynamic, i.e. the whole popUp menu be dyanmic, so I can select different menus based on value of another dynamic. But I do not think this is possible)

Currently, the WHOLE PopupMenu can be enabled or disabled based on a dynamic setting. But I want to do this at the entry level inside the Popupmenu.

Here is an example to illustrate:

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

enter image description here

In the above, when X=1, the whole menu is enabled.

But what I want, if X=1, is to be able to select only say "NONE" (or the list just show "NONE"), and when X=2, then be able to select only "SOR" and "SSOR" (or the list just show these 2 choices).

i.e. the system will not let "SOR" be selected if x=2. Trying to select it will cause no change and the menu will remain on its previous setting and not change.

Again, I know I can break things into 2 popuMenus, and control each one based on X setting like this below, but I do not have more space to add more menus:

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
    }
   }]
 ]

enter image description here

My question is: Is there a way to do the above in Mathematica? I am using 8.04.

Best solution would be to have the list of items for the menu itself by Dynamic (or the whole menu be dynamic), so I can tell it to use listA when X=1 or use listB when X=2, etc.. But I do not know how to do this and do not know if it is even possible.

ps. This is my current attempt at a solution

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"};
   )
 ]

But it is not working too well yet. Will keep at it....

thanks

Update:

Looking at Simon solution below inspired me a little more, so this is what I have so far:

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"}]
       )
      ]
     ]
    }
   }
  ]
 ]

enter image description here

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

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

发布评论

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

评论(2

葬心 2024-12-27 03:25:53

这是您正在寻找的类型吗?

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}]

请注意顶部的开关,当x更改时,它控制选择的默认值。


编辑:

按照您将菜单逻辑本地化到控件 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}]

a Boring Screenshot

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

Is this the type of thing you're looking for?

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}]

Note the Switch at the top that controls the defaults for selection when x is changed.


Edit:

Following your request to have the menu logic localised to the control Grid and stealing Heike's default mechanism, here's a new version:

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}]

a boring screenshot

Note that the menu list does not need to be localized with a With statement - it can be set elsewhere in the code.

作妖 2024-12-27 03:25:53

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

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}]

This solution is similar to Simon's answer, but it doesn't explicitly use the number of lists so it should work for an arbitrary number of lists

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