如何将menuItems安全地添加到Maya MEL中的现有菜单中

时间:2013-10-07 23:41:28

标签: menu maya mel

我尝试使用MEL

将菜单项添加到Maya中的现有菜单中

示例:

menuItem -label "Mylabel" -insertAfter "someEntry" -parent $gMainFileMenu;
menuItem -label "Mylabel2" -insertAfter "someEntry" -parent $gMainFileMenu;

问题是菜单不会像普通条目一样填充,只能通过我用这两行代码添加的条目来填充。

例如,文件菜单通常包含“新场景”,“打开场景”,“保存场景”等,但是当我执行这两行时,它只包含“Mylabel”和“Mylabel2”。

是否有修复或解决方法以确保菜单完全填充?有没有办法迫使Maya在没有用户实际点击的情况下构建它?

1 个答案:

答案 0 :(得分:6)

实际上问题是Maya首次在用户打开菜单时填充菜单。它检查菜单长度是否大于0,它不会填充它。由于您添加了2个条目,因此菜单长度大于0,并且不会填充标准条目。

要解决这个问题,有两种方法可以解决。您可以通过强制构建菜单项或注册构建menuItem来实现。 Bot方式可用于不同的情况。

强制建立菜单:

您需要做的是找到Maya调用的功能来构建您需要的菜单。您可以在文件夹<MayaInstall>/scripts/startup/*中找到这些功能。查找过程名称的一种好方法是打开Maya控制台,启用“回显所有命令”,然后单击要查看构建它的函数的菜单。

在您的情况下,该函数名为buildFileMenu(),可以在脚本FileMenu.mel中找到。

现在您拥有该功能名称,您必须检查它的参数。有时它需要一个菜单​​名称作为参数。如果需要,请参阅底部有关如何查找菜单名称的内容。

现在让我们构建它。

global string $gMainFileMenu; // Retrieve the menu name
buildFileMenu(); //  Build it

// Now build your menu
menuItem -divider true -parent $gMainFileMenu SuperMenuDivider;
menuItem -label "MyLabel1" -parent $gMainFileMenu SuperMenuLab1;
menuItem -label "MyLabel2" -parent $gMainFileMenu SuperMenuLab2;

// Create a proc to remove your menu items
global proc RemoveMyMenuItems()
{
    if(`menuItem -ex SuperMenuDivider`) deleteUI -mi SuperMenuDivider;
    if(`menuItem -ex SuperMenuLab1`) deleteUI -mi SuperMenuLab1;
    if(`menuItem -ex SuperMenuLab2`) deleteUI -mi SuperMenuLab2;
}
// You can then call that function when in the unload function of your plugin.

通过注册构建menuItem调用

你需要做的是使用一个名为addMenuItemSafe的函数,该函数有3个参数,你想要填充的菜单,填充菜单的函数的名称,以及用于保存回调的全局变量名。

首先,你要做的是创建将填充菜单的函数,然后是删除它的函数,然后调用AddMenuItemSafe方法。请注意,在该功能中,您必须检查您的菜单是否已经创建,因为Maya会在每次显示菜单时调用该功能。

首先,添加和删除菜单条目的两个功能是:

global proc string AddMyMenuItems()
{
    // Global variable to hold the test to see if the menu is populated.
    global int $gMyMenuItemsTest;

    // Menu var needed in our case because we are inserting in the middle of the menu
    global string $gMainFileMenu;

    if( $gMyMenuItemsTest == 0 ) 
    {
        // Actually build your menu.
        // Note that if you don't need to insert it after a specific entry,
        // You can just do `menuItem -label "blep"`. No need of -ia and -p
        // Also, for inserting in the middle you have to put stuff in reverse order.
        // If you are just appending, put it in the normal order.
        menuItem -label "Mylabel2" -insertAfter "someEntry" -parent $gMainFileMenu MyMenuLab2;
        menuItem -label "Mylabel" -insertAfter "someEntry" -parent $gMainFileMenu MyMenuLab;
        menuItem -divider true -parent $gMainFileMenu MyMenuDiv;

        $gMyMenuItemsTest = 1;
    }
    return "RemoveMyMenuItems()"; // Returns the callback
}

global proc RemoveMyMenuItems()
{
    global int $gMyMenuItemsTest;

    if( $gMyMenuItemsTest == 1 ) 
    {
        // Delete your items if they exist (yes we are kind of 
        // doing the check twice, but I find it safe. 
        // The user could have deleted it from Maya in the command
        // line for whatever reason, more robustness is always good.
        if(`menu -ex MyMenuDiv`) deleteUI -mi MyMenuDiv;
        if(`menu -ex MyMenuLab`) deleteUI -mi MyMenuLab;
        if(`menu -ex MyMenuLab2`) deleteUI -mi MyMenuLab2;
    }
}

然后实际调用AddMenuItemSafe:

// The menu we want to use ... here it is the File Menu.
global string $gMainFileMenu;

// Our variables needed for the addSafe call
global int $gMyMenuItemsTest;
global string $gMyMenuVariable;
$gMyMenuItemsTest = 0;
$gMyMenuVariable = "";

// The menu creation
addMenuItemSafe($gMainFileMenu, "AddMyMenuItems", "gMyMenuVariable");

您可以自由地将该函数调用放在插件实例化中,或者让您满意。

有关函数AddMenuItemSafe的更多信息,您可以进入Maya脚本目录,它应该位于“AddMenuItemSafe.mel”。


如何查找菜单名称

注意菜单变量名称,您可以使用以下约定“构建”它们

  

“g”+查看+姓名+“菜单”

其中:

  • 查看是可以找到该菜单的视图。例如:主要,多边形,动画等

  • 名称是菜单的名称。例如:文件,编辑,网格等

注意Autodesk有时会重命名菜单并使用旧的globalVariable名称,因此使用此方法可能并不总是有效