如何在 Mathematica 中制作选择性下拉菜单?
我的 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
}
}]
]
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
}
}]
]
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"}]
)
]
]
}
}
]
]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是您正在寻找的类型吗?
请注意顶部的
开关
,当x
更改时,它控制选择
的默认值。编辑:
按照您将菜单逻辑本地化到控件
Grid
的请求并窃取 Heike 的默认机制,这里有一个新版本:请注意,
menu
列表不需要使用With
语句进行本地化 - 它可以在代码中的其他位置进行设置。Is this the type of thing you're looking for?
Note the
Switch
at the top that controls the defaults forselection
whenx
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:Note that the
menu
list does not need to be localized with aWith
statement - it can be set elsewhere in the code.该解决方案类似于西蒙的答案,但它没有明确使用列表的数量,因此它应该适用于任意数量的列表
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