Using Multi-Res Icons in Max and Qt
Beginning with 3ds Max 2017, the 3ds Max user interface supports multi-resolution icons that can be used to
display crisp and appealing icons on High-DPI displays. 3ds Max
picks the best fitting icon resource based on the available sizes for an optimal
user experience. For details on the naming conventions of these icon files,
see MaxSDK::LoadMaxMultiResIcon()
in the SDK Reference.
As of 3ds Max 2023.1 Update Scalable Vector Graphics (SVG) files are also supported.
There are three options for accessing icons for use in Qt-based user interfaces:
- Use standard 3ds Max icons
- Use custom icons compiled with the Qt Resource System
- Use custom icons loaded from the file system at run time.
Using Standard 3ds Max Icons
3ds Max uses a large library of icons, and these can be accessed by plug-ins by using LoadMaxMultiResIcon()
and passing in a path and icon name. Be aware that these icons may be altered in upcoming versions of 3ds Max.
MaxSDK::LoadMaxMultiResIcon( "Common/Delete" );
You can view the path and name of icons in the 3ds Max UI in the Icon Guide.
You can also set CustomControlsOptions.PrintIconPaths=true
in the Scripting Listener, and then hover the mouse over an icon.
Custom Icons Compiled by Qt
You can use the Qt Resource System with your plug-in. Qt provides a method to compile resources into resource-bundles, which can be linked into the application / dll or loaded dynamically at run-time. The sample plug-in in maxsdk\howto\ui\qtIconsDemo illustrates how to load icons dynamically using this approach.
The benefit of using a dynamically-loaded resource-bundle is that you have the ability to change the resources at run-time, as shown in the qtIconsDemo example to support the Dark and Light theme switching, without having to change anything on the UI code side.
The 3ds Max internal multi-res icon system takes care of reloading the icons after a theme change, so exchanging the resource-bundle right before that is all that needs to be done on a plug-in side.
The resources are defined by a .qrc file, with a format that looks like this:
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/qtIconsDemo/Icons">
<file>Array_24.png</file>
<file>Array_30.png</file>
<file>Array_36.png</file>
<file>Array_48.png</file>
<file>Array.svg</file>
<file>Snapshot_24.png</file>
<file>Snapshot_30.png</file>
<file>Snapshot_36.png</file>
<file>Snapshot_48.png</file>
<file>Snapshot.svg</file>
</qresource>
</RCC>
Note the prefix attribute in the .qrc file, which specifies the path where this resource can be found:
MaxSDK::LoadMaxMultiResIcon( ":/qtIconsDemo/Icons/Array" );
Also note the colon : at the beginning of the path. That is the Qt convention for indicating a resource and not a file-system path.
In the example above we supply pixel perfect PNG images for specific sizes, and an SVG version that is used at other sizes. You can supply only SVG images (which is similar) but may want to provide a PNG for the smallest size to ensure it is scaled correctly.
The .qrc file is then compiled using Qt's RCC compiler. See the custom build-step in the qtIconsDemo project. In that sample, the icon set for the light and dark themes are each copied to a temporary directory, the .qrc file is copied to the same location, and RCC is called to compile the icons. The usage looks like this:
rcc.exe qtIconsDemo.qrc -binary -o qtIconsDemo.rcc
This .rcc file then has to be registered as a resource-bundle at run-time using this call:
QResource::registerResource( path_to_my_bundle.rcc )
and can be unregistered using
QResource::unregisterResource( path_to_my_bundle.rcc );
Note that registering the resource-bundle does not load anything into
memory, as the resources are loaded later on demand. If dynamic change of the
resources in a bundle is not needed (for example, if you do not need to support light and dark theming), the qrc can also be simply compiled into a .cpp
file that can be compiled into a dll.
For more detailed information see the Qt Resource System documenation.
To make the qtIconsDemo sample work, make sure to copy the qtIconsDemo_Dark.rcc and qtIconsDemo_Light.rcc files into the UI_ln folder inside the 3dsmax installation.
Load Icons from the File System at Run-time
Your plug-in can load icons in PNG in SVG format from the file system as required. This is the easiest way to quickly do some testing, but probably not the optimal solution for production code used by customers.
LoadMaxMultiResIcon()
can load icons under UI_ln/Icons in the 3ds Max install location. Pass the sub-path to the function such as:
MaxSDK::LoadMaxMultiResIcon( "qtIconsDemo/Cut" );
This will look into that folders and load one of those files:
UI_ln/Icons/Dark/qtIconsDemo/Cut_24.png UI_ln/Icons/Dark/qtIconsDemo/Cut_30.png UI_ln/Icons/Dark/qtIconsDemo/Cut_36.png UI_ln/Icons/Dark/qtIconsDemo/Cut_48.png
UI_ln/Icons/Light/qtIconsDemo/Cut_24.png UI_ln/Icons/Light/qtIconsDemo/Cut_30.png UI_ln/Icons/Light/qtIconsDemo/Cut_36.png UI_ln/Icons/Light/qtIconsDemo/Cut_48.png
Depending on the current theme of 3dsmax and the display resolution.