Code


PrefSaver

PrefSaver streamlines the process of preserving various UI component states – such as control values, selected items, tree collapse states, active tabs, etc. – by serializing them to different destinations. Designed for both standalone applications and Maya-integrated tools, it supports multiple serialization formats including binary, JSON, and Maya optionVars.


Features

Universal UI Support

Save and load states for PySide, PyQt (Python 2 only), Maya UI and Maya PyMEL UI controls.

Flexible Serialization

Store your data as Binary (via pickle), JSON, or Maya optionVars.

Environment Agnostic

Works seamlessly in both Standalone Python applications and inside Maya.

User Variable Serialization

Register your own Python variables for serialization.


Usage


1. Create Serializer

Python
from fxpt3.fx_prefsaver import Serializers
mySerializer = Serializers.SerializerFileJson('path/to/pref/file/prefs.cfg')

2. Create a PrefSaver instance

Python
from fxpt3.fx_prefsaver import PrefSaver
myPrefSaver = PrefSaver(mySerializer)

3. Add controls to PrefSaver with their types and OPTIONAL default value

Python
myPrefSaver.addControl(myPyQtLineEdit, PrefSaver.UIType.PYQTLineEdit)
myPrefSaver.addControl(myPySideChkBox, PrefSaver.UIType.PYSIDECheckBox, QtCore.Qt.Unchecked)
myPrefSaver.addControl(myPyMelFloatField, PrefSaver.UIType.PMFloatField, 4.568)
myPrefSaver.addControl(myMayaCheckBoxGroup2, PrefSaver.UIType.MCheckBoxGrp2, [False, False])

4. You can also save variables instead of UI controls.

You will need to provide a variable name, getter callable, setter callable and default value:

Python
def variableGetter():
    return myVariable
def variableSetter(arg):
    myVariable = arg
myPrefSaver.addVariable('myVariable', variableGetter, variableSetter, defaultVariableValue)

5. Call the PrefSaver instance to save, load, or reset states.

To save control states:

Python
myPrefSaver.savePrefs()

To load control states:

Python
myPrefSaver.savePrefs()

To reset controls to defaults (global defaults are used if none were supplied):

Python
myPrefSaver.savePrefs()

Important Note 1

When creating PyMEL or Maya UI controls, always provide a custom name. This ensures the control name remains constant between sessions.

Python
myPyMelCheckBox = pymel.core.checkBox('myPyMelCheckBox', label='My PyMel Check Box')
myMelCheckBox = maya.cmds.checkBox('myMelCheckBox', label='My Mel Check Box')

When creating Qt controls via code, you must also set the object name:

Python
myPySideCheckBox = PySide6.QtWidgets.QCheckBox()
myPySideCheckBox.setObjectName('myPySideCheckBox')

Important Note 2

Ensure all control names are unique.


Serializers

SerializerFilePickle serializes data to a binary file using pickle:

Python
SerializerFilePickle('path/to/pref/file/prefs.cfg')

SerializerFileJson serializes data to a text JSON file

Python
SerializerFileJson('path/to/pref/file/prefs.cfg')

SerializerOptVar serializes data to Maya optionVar (available only within Maya)

Python
SerializerOptVar('mayaOptionVarName')

Getting Help

Just import PrefSaver and run help()

Python
from fxpt3.fx_prefsaver import PrefSaver
help(PrefSaver)

Supported Controls and Default Values


PyQt Types

Note: only supported for Python 2 (fxpt package)

PYQTCheckAction bool
PYQTCheckBox QtCore.Qt.CheckState
PYQTCheckButton bool
PYQTComboBox int → current item index (0-based)
PYQTComboBoxEditable int → current item index (0-based)
PYQTDateEdit str → string in format ‘yyyy.MM.dd’ or QDate object
PYQTDateTimeEdit str → string in format ‘yyyy.MM.dd HH:mm:ss.zzz’ (24 hours) or QDateTime object
PYQTDial int, float
PYQTDoubleSpinBox int, float
PYQTLineEdit str
PYQTListView None → no default value, ignored
PYQTListWidget None → no default value, ignored
PYQTPlainTextEdit str
PYQTRadioButton bool
PYQTScrollArea [int, int] → tuple or list with horizontal and vertical scroll values
PYQTScrollBar int
PYQTSlider int, float
PYQTSpinBox int, float
PYQTSplitter [int, int, ...] → tuple or list with section sizes
PYQTStackedWidget int → current widget index (0-based)
PYQTTabWidget int → current tab index (0-based)
PYQTTableView None → no default value, ignored
PYQTTableWidget None → no default value, ignored
PYQTTextEdit str
PYQTTimeEdit str → string in format ‘HH:mm:ss.zzz’ (24 hours) or QTime object
PYQTToolBox int → current tab index (0-based)
PYQTTreeView None → no default value, ignored
PYQTTreeWidget None → no default value, ignored
PYQTWindow [int, int, int, int] → tuple or list with top and left corner coordinates, width and height


PySide Types

PYSIDECheckAction bool
PYSIDECheckBox QtCore.Qt.CheckState
PYSIDECheckButton bool
PYSIDEComboBox int → current item index (0-based)
PYSIDEComboBoxEditable int → current item index (0-based)
PYSIDEDateEdit str → string in format ‘yyyy.MM.dd’ or QDate object
PYSIDEDateTimeEdit str → string in format ‘yyyy.MM.dd HH:mm:ss.zzz’ (24 hours) or QDateTime object
PYSIDEDial int, float
PYSIDEDoubleSpinBox int, float
PYSIDELineEdit str
PYSIDEListView None → no default value, ignored
PYSIDEListWidget None → no default value, ignored
PYSIDEPlainTextEdit str
PYSIDERadioButton bool
PYSIDEScrollArea [int, int] → tuple or list with horizontal and vertical scroll values
PYSIDEScrollBar int
PYSIDESlider int, float
PYSIDESpinBox int, float
PYSIDESplitter [int, int, …] → tuple or list with section sizes
PYSIDEStackedWidget int → current widget index (0-based)
PYSIDETabWidget int → current tab index (0-based)
PYSIDETableView None → no default value, ignored
PYSIDETableWidget None → no default value, ignored
PYSIDETextEdit str
PYSIDETimeEdit str → string in format ‘HH:mm:ss.zzz’ (24 hours) or QTime object
PYSIDEToolBox int → current tab index (0-based)
PYSIDETreeView None → no default value, ignored
PYSIDETreeWidget → no default value, ignored
PYSIDEWindow [int, int, int, int] → tuple or list with top and left corner coordinates, width and height


Maya Types

MCheckBox bool
MCheckBoxGrp1 [bool] → tuple or list
MCheckBoxGrp2 [bool, bool] → tuple or list
MCheckBoxGrp3 [bool, bool, bool] → tuple or list
MCheckBoxGrp4 [bool, bool, bool, bool] → tuple or list
MColorSliderGrp [float, float, float] → tuple or list with Red, Green and Blue values (0-1 range)
MFloatField float
MFloatFieldGrp1 [float] → tuple or list
MFloatFieldGrp2 [float, float] → tuple or list
MFloatFieldGrp3 [float, float, float] → tuple or list
MFloatFieldGrp4 [float, float, float, float] → tuple or list
MFloatScrollBar float
MFloatSlider float
MFloatSliderGrp float
MFrameLayout bool → collapse state
MIconTextCheckBox bool
MIconTextRadioButton bool
MIconTextScrollList [int, int, …] → tuple or list with selected indexes
MIntField int
MIntFieldGrp1 [int] → tuple or list
MIntFieldGrp2 [int, int] → tuple or list
MIntFieldGrp3 [int, int, int] → tuple or list
MIntFieldGrp4 [int, int, int, int] → tuple or list
MIntScrollBar int
MIntSlider int
MIntSliderGrp int
MOptionMenu int → current item index (1-based)
MOptionMenuGrp int → current item index (1-based)
MRadioButton bool
MRadioButtonGrp1 int → current item index (1-based)
MRadioButtonGrp2 int → current item index (1-based)
MRadioButtonGrp3 int → current item index (1-based)
MRadioButtonGrp4 int → current item index (1-based)
MScriptTable anything → no default value, ignored
MScrollField str
MScrollLayout [int, int] → tuple or list with horizontal and vertical scroll values
MShelfTabLayout int → current tab index (1-based)
MSymbolCheckBox bool
MTabLayout int → current tab index (1-based)
MTextField str
MTextFieldButtonGrp str
MTextFieldGrp str
MTextScrollList [int, int, …] → tuple or list with selected indexes


PyMel Types

PMCheckBox bool
PMCheckBoxGrp1 [bool] → tuple or list
PMCheckBoxGrp2 [bool, bool] → tuple or list
PMCheckBoxGrp3 [bool, bool, bool] → tuple or list
PMCheckBoxGrp4 [bool, bool, bool, bool] → tuple or list
PMColorSliderGrp [float, float, float] → tuple or list with Red, Green and Blue values (0-1 range)
PMFloatField float
PMFloatFieldGrp1 [float] → tuple or list
PMFloatFieldGrp2 [float, float] → tuple or list
PMFloatFieldGrp3 [float, float, float] → tuple or list
PMFloatFieldGrp4 [float, float, float, float] → tuple or list
PMFloatScrollBar float
PMFloatSlider float
PMFloatSliderGrp float
PMFrameLayout bool → collapse state
PMIconTextCheckBox bool
PMIconTextRadioButton bool
PMIconTextScrollList [int, int, …] → tuple or list with selected indexes
PMIntField int
PMIntFieldGrp1 [int] → tuple or list
PMIntFieldGrp2 [int, int] → tuple or list
PMIntFieldGrp3 [int, int, int] → tuple or list
PMIntFieldGrp4 [int, int, int, int] → tuple or list
PMIntScrollBar int
PMIntSlider int
PMIntSliderGrp int
PMOptionMenu int → current item index (1-based)
PMOptionMenuGrp int → current item index (1-based)
PMRadioButton bool
PMRadioButtonGrp1 int → current item index (1-based)
PMRadioButtonGrp2 int → current item index (1-based)
PMRadioButtonGrp3 int → current item index (1-based)
PMRadioButtonGrp4 int → current item index (1-based)
PMScriptTable None → no default value, ignored
PMScrollField str
PMScrollLayout [int, int] → tuple or list with horizontal and vertical scroll values
PMShelfTabLayout int → current tab index (1-based)
PMSymbolCheckBox bool
PMTabLayout int → current tab index (1-based)
PMTextField str
PMTextFieldButtonGrp str
PMTextFieldGrp str
PMTextScrollList [int, int, …] → tuple or list with selected indexes


Setup


Installation

FX Outliner is part of the FX Python Tools library. Download fxpt from GitHub and add it to your PYTHONPATH directory.


Python 2 and 3

For Python 3 use fxpt3 package:

Python
from fxpt3.fx_prefsaver import PrefSaver
myPrefSaver = PrefSaver(mySerializer)

For Python 2 use fxpt package:

Python
from fxpt.fx_prefsaver import PrefSaver
myPrefSaver = PrefSaver(mySerializer)

Compatibility

Tested on

Maya 2016
Maya 2017
Maya 2022 (with “-pythonver 2” flag)
Maya 2024
Maya 2025
Standalone mode (Python 2.7 & 3.x)