Qt Utility Methods.
This class provides some basic methods for accessing the Qt controls which underlie Maya's UI.
The safest way to use the Qt API from within Maya is to create your own Qt window and populate it with your own controls.
While it is possible to use the Qt API to modify existing Maya UI elements, such as those created using Maya commands from MEL or Python, such modifications are not supported by Autodesk and could lead to Maya becoming unstable or inoperable.
In practice, you will likely find a number of modifications which appear safe, such as changing a control's text or reorganizing the items on a menu. However, Autodesk provides no guarantees that the underlying implementations of those UI elements won't change from one release of Maya to another, potentially in ways that may make formerly safe usage become unsafe. So if you choose to incorporate such actions into your plug-in be aware that you may have to modify your code in future versions of Maya.
Layouts In Maya Vs. Qt
In Qt a layout (i.e. a QLayout or something derived from it) is not a widget. It is attached to a widget to control the positioning of that widget's children but is not itself a child of the widget and does not appear in the widget hierarchy.
In Maya, layouts are also widgets which are part of the hierarchy. For example, if you have a window named "myWin" which contains a layout named "myLayout" which in turn holds a button named "myButton", then the button's full hierarchical name would be "myWin|myLayout|myButton".
To bridge this difference, each Maya layout is given its own placeholder QWidget to which the corresponding QLayout is applied and bearing the same name as the layout. The children of the layout are then parented beneath the placeholder widget. When you call the findLayout() method, it is the placeholder widget which is returned.
The one exception to this use of placeholders is the top-level layout of a window. Rather than introduce a superfluous placeholder widget, the top-level QLayout is attached directly to the window. So a call to findLayout() for a top-level layout will return the window. Note, however, that the top-level layout's hierarchical name is still structured as if it had its own dedicated widget in the hierarchy. E.g. "myWin|myLayout". This can lead to the somewhat incongruous result that calling fullName() on the result of a findLayout() call for a top-level layout will return the name of the window rather than the layout. E.g:
QWidget* layoutWidget = MQtUtil::findLayout("myWin|myLayout"); MString layoutName = MQtUtil::fullName(layoutWidget);
In the example above, layoutName
will contain
"myWin" rather than the string we started out with,
"myWin|myLayout". To get around this problem pass the widget's
QLayout to fullName()
instead:
MString layoutName = MQtUtil::fullName(layoutWidget->layout());
Now layoutName
will contain "myWin|myLayout" as
expected.
Not all Maya layouts are implemented by a single QLayout attached to a single placeholder widget (or window). In some cases the layout is implemented by a small sub-tree of widgets and QLayouts. Despite this added complexity behind the scenes, Maya still treats the entire sub-tree as a single element in the hierarchy for which the findLayout() method will return the top-level widget of the sub-tree.
To simplify the traversal of these complex layouts, the
getLayoutChildren() and
getParent() methods treat complex layouts as if they are a
single layout widget with their children parented directly beneath,
skipping over any internal widgets which the layout's sub-tree may
contain. In this way,
getLayoutChildren() returns the same set of children as the
layout
command's -query -childArray
flags, while
getParent() returns the same layout as a control's -query
-parent
flags.
Order of Include Files
Some Qt header files redefine certain standard C++ library symbols. As such it is important that the Qt headers be included before any other header files which might reference those symbols.
To ensure proper compilation, your source files should always include any Qt header files they use (QWidget, QEvent, etc) before all other header files. If the source includes MQtUtil.h then it should come after the Qt headers but before any others.
Qt Licensing
Qt is made available under both open source and commercial licenses. The type of license required depends upon your intended use of Qt. For more information, see the Qt Licensing page at http://qt.nokia.com/about/licensing/frequently-asked-questions
#include <MQtUtil.h>
Public Types |
|
typedef QWidget *(* | UITypeCreatorFn )(QWidget *parent, const QString &name) |
Pointer to a widget creator function.
|
|
Static Public Member Functions |
|
static QWidget * | findControl (MString controlName, const QWidget *ancestor=NULL) |
Returns the QWidget for the named Maya
control. |
|
static QWidget * | findLayout (MString layoutName, const QWidget *ancestor=NULL) |
Returns the QWidget for the named Maya
layout. |
|
static QAction * | findMenuItem (MString itemName) |
Returns the QAction for the named Maya
menuItem. |
|
static QWidget * | findWindow (MString windowName) |
Returns the QWidget for the named Maya
window. |
|
static MString | fullName (const QObject *uiElement) |
Returns the full, hierarchical name of a UI
element. |
|
static QWidget * | getCurrentParent () |
Returns the placeholder widget for the
current layout if there is one. |
|
static QList< QObject * > | getLayoutChildren (const QWidget *layout) |
Returns a list of all the Maya UI elements
parented directly beneath the specified Maya layout. |
|
static QObject * | getParent (const QObject *uiElement) |
Returns a pointer to a UI element's parent
element within Maya's UI hierarchy. |
|
static MString | addWidgetToMayaLayout (QWidget *control, QWidget *layout, const MString &uiType=MString()) |
Adds a QWidget to an existing Maya layout,
such as that returned by
getCurrentParent() or getLayout(). |
|
static bool | registerUIType (const MString &className, UITypeCreatorFn, const MString &command) |
Registers a class name (UI-type) with a
function to create the QWidget of that type, and a command to edit
it with. |
|
static bool | deregisterUIType (const MString &className) |
De-registers a widget class (UI-type) which
has been previously registered with
registerUIType(). |
|
static QWidget * | mainWindow () |
Returns Maya's main window. |
|
static MNativeWindowHdl | nativeWindow (const QWidget *control) |
Returns a platform-specific native window
handle for the specified control. |
|
static MString | toMString (const QString &qstr) |
Convenience utility to convert a QString to
an MString. |
|
static QString | toQString (const MString &mstr) |
Convenience utility to convert an MString to a QString. |
|
static const char * | className () |
Returns the name of this class. |
typedef QWidget*(* UITypeCreatorFn)(QWidget *parent, const QString &name) |
Pointer to a widget creator function.
[in] | parent | The function should use this parameter to set the parent of the created object. |
[in] | name | The function should use this parameter to set the objectName of the created object. |
QWidget * findControl | ( | MString | controlName, |
const QWidget * | ancestor =
NULL |
||
) | [static] |
Returns the QWidget for the named Maya control.
[in] | controlName | Name of the control within Maya. May be a plain name ("myButton") or a hierarchical name ("myWin|myLayout|myButton"). If a hierarchical name is supplied then the search will begin with the UI element at the start of the hierarchy and descend from there. |
[in] | ancestor | Pointer to an ancestor UI element which appears somewhere in the UI hierarchy above the control. If not NULL then the search will begin at the specified ancestor and descend from there. |
QWidget * findLayout | ( | MString | layoutName, |
const QWidget * | ancestor =
NULL |
||
) | [static] |
Returns the QWidget for the named Maya layout.
In Maya a layout is part of the widget tree and is represented by a QWidget to which the actual QLayout has been applied. This method returns a pointer to that QWidget.
There are some important exceptions to this rule. See the "Layouts In Maya Vs. Qt" discussion in the class documentation for further details.
[in] | layoutName | Name of the layout within Maya. May be a plain name ("myLayout") or a hierarchical name ("myWin|myLayout"). If a hierarchical name is supplied then the search will begin with the UI element at the start of the hierarchy and then descend from there. |
[in] | ancestor | Pointer to an ancestor UI element which appears somewhere in the UI hierarchy above the layout. If not NULL then the search will begin at the specified ancestor and descend from there. |
QAction * findMenuItem | ( | MString | itemName | ) | [static] |
Returns the QAction for the named Maya menuItem.
[in] | itemName | Name of the menuItem within Maya. May be a plain name ("myItem") or a hierarchical name ("myMenu|myItem"). If a hierarchical name is supplied then the search will begin with the UI element at the start of the hierarchy and then descend from there. |
QWidget * findWindow | ( | MString | windowName | ) | [static] |
Returns the QWidget for the named Maya window.
[in] | windowName | Name of the window within Maya. |
MString fullName | ( | const QObject * | uiElement | ) | [static] |
Returns the full, hierarchical name of a UI element.
This is the name which uniquely identifies the element within Maya and can be passed to Maya's UI commands.
For example, if a window was created as follows using MEL:
window myWin; columnLayout myLayout; button -l "Press Me" myButton;
then passing a pointer to 'myButton's QObject would return the string "myWin|myLayout|myButton".
[in] | uiElement | pointer to a UI element's QObject |
QWidget * getCurrentParent | ( | ) | [static] |
Returns the placeholder widget for the current layout if there is one.
The current layout is set when a layout is created using a Maya
layout command. In MEL, this layout can be queried using
"setParent -q"
. When adding a QWidget to a Maya
layout, the new QWidget should be parented to this widget. For
example, in the following MEL code the plug-in command 'myControl'
should create a custom QWidget-derived control and parent it to the
columnLayout's placeholder QWidget, and then add it using
addWidgetToMayaLayout().
window myWin; columnLayout; myControl; showWindow;
QList< QObject * > getLayoutChildren | ( | const QWidget * | layout | ) | [static] |
Returns a list of all the Maya UI elements parented directly beneath the specified Maya layout.
There may not always be a one-to-one correspondence between a Maya layout and a QLayout. For example, some of Maya's layouts are implemented by a small sub-tree of widgets which handle different aspects of the layout.
This method will treat that entire sub-tree as a single layout element and return all of the Maya controls and sub-layouts which it handles as a flattened list, with all of Maya's internal objects removed.
This method can be used in conjunction with getParent() to navigate up and down through such complex layouts as if they were single UI elements.
[in] | layout | Pointer to a Maya layout's QWidget. See findLayout() for a description of the relationship between Maya layouts and QWidgets. |
QObject * getParent | ( | const QObject * | uiElement | ) | [static] |
Returns a pointer to a UI element's parent element within Maya's UI hierarchy.
There may not always be a one-to-one correspondence between an element in Maya's UI hierarchy and a Qt object. For example, some of Maya's layouts are implemented by a small sub-tree of widgets. This method will treat that entire sub-tree as a single element by stepping to its head object.
This method can be used in conjunction with getLayoutChildren() to navigate up and down through such complex layouts as if they were single UI elements.
[in] | uiElement | A pointer to a UI element's QObject |
MString addWidgetToMayaLayout | ( | QWidget * | control, |
QWidget * | layout, | ||
const MString & | uiType = MString() |
||
) | [static] |
Adds a QWidget to an existing Maya layout, such as that returned by getCurrentParent() or getLayout().
Once the QWidget has been added, it can be used in MEL or Python scripts like native Maya controls. In order to integrate the control into Maya's UI, several modifications are made:
popupMenu
interaction.objectName
may be modified to ensure
uniqueness.isControl
and
objectTypeUI
are added.[in] | control | The QWidget to be added. If the control is named (with QObject::setObjectName), the name may be modified to make it unique, this will be done by adding a numeric suffix. Otherwise a default name, based on the class name will be used. |
[in] | layout | The placeholder widget for the Maya layout |
[in] | uiType | A Maya ui-type name for the QWidget being added. Defaults to
the name of its class. This name can be used by the Maya commands
lsUI and objectTypeUI . |
bool registerUIType | ( | const MString & | className, |
UITypeCreatorFn | fn, | ||
const MString & | command | ||
) | [static] |
Registers a class name (UI-type) with a function to create the QWidget of that type, and a command to edit it with.
The loadUI
command looks at each widget element of
the Qt Designer XML document, and if the class attribute
matches a registered class name, it calls the associated function
to create the object.
If there are any dynamic string properties with a '-' (MEL) or '+' (Python) prefix, the associated command is called in edit mode with the property name as the flag and the value as the flag value.
For example, with the following registration:
MQtUil::registerUIType("QCustom", createCustom, "custom")
The following XML fragment will delegate creation of the object
to createCustom
and then call custom -edit
-setValue 33 "custom1"
.
<widget class="QCustom" name="custom1"> <property
name="-setValue"> <string>33</string>
</property> </widget>
Some Qt types are associated by default with internal Maya
commands, such as QPushButton -> button etc. This can be queried
with loadUI -listTypes
.
[in] | className | The name of the QWidget-derived class created by the function. |
[in] | fn | The creator function. |
[in] | command | The command to be used to edit the created QWidget. |
bool deregisterUIType | ( | const MString & | className | ) | [static] |
De-registers a widget class (UI-type) which has been previously registered with registerUIType().
[in] | className | The name of the class to be de-registered. |
QWidget * mainWindow | ( | ) | [static] |
Returns Maya's main window.
MNativeWindowHdl nativeWindow | ( | const QWidget * | control | ) | [static] |
Returns a platform-specific native window handle for the specified control.
If the control is native then its native handle will be returned, otherwise a native window will be created for it. This may reduce performance so native should only be requested when necessary.
[in] | control | Control whose native window handle is to be returned. |
MString toMString | ( | const QString & | qstr | ) | [static] |
QString toQString | ( | const MString & | mstr | ) | [static] |
const char * className | ( | ) | [static] |