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
from fxpt3.fx_prefsaver import Serializers
mySerializer = Serializers.SerializerFileJson('path/to/pref/file/prefs.cfg')2. Create a PrefSaver instance
from fxpt3.fx_prefsaver import PrefSaver
myPrefSaver = PrefSaver(mySerializer)3. Add controls to PrefSaver with their types and OPTIONAL default value
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:
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:
myPrefSaver.savePrefs()To load control states:
myPrefSaver.savePrefs()To reset controls to defaults (global defaults are used if none were supplied):
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.
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:
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:
SerializerFilePickle('path/to/pref/file/prefs.cfg')SerializerFileJson serializes data to a text JSON file
SerializerFileJson('path/to/pref/file/prefs.cfg')SerializerOptVar serializes data to Maya optionVar (available only within Maya)
SerializerOptVar('mayaOptionVarName')Getting Help
Just import PrefSaver and run help()
from fxpt3.fx_prefsaver import PrefSaver
help(PrefSaver)Supported Controls and Default Values
PyQt Types
Note: only supported for Python 2 (fxpt package)
PYQTCheckAction boolPYQTCheckBox QtCore.Qt.CheckStatePYQTCheckButton boolPYQTComboBox int → current item index (0-based)PYQTComboBoxEditable int → current item index (0-based)PYQTDateEdit str → string in format ‘yyyy.MM.dd’ or QDate objectPYQTDateTimeEdit str → string in format ‘yyyy.MM.dd HH:mm:ss.zzz’ (24 hours) or QDateTime objectPYQTDial int, floatPYQTDoubleSpinBox int, floatPYQTLineEdit strPYQTListView None → no default value, ignoredPYQTListWidget None → no default value, ignoredPYQTPlainTextEdit strPYQTRadioButton boolPYQTScrollArea [int, int] → tuple or list with horizontal and vertical scroll valuesPYQTScrollBar intPYQTSlider int, floatPYQTSpinBox int, floatPYQTSplitter [int, int, ...] → tuple or list with section sizesPYQTStackedWidget int → current widget index (0-based)PYQTTabWidget int → current tab index (0-based)PYQTTableView None → no default value, ignoredPYQTTableWidget None → no default value, ignoredPYQTTextEdit strPYQTTimeEdit str → string in format ‘HH:mm:ss.zzz’ (24 hours) or QTime objectPYQTToolBox int → current tab index (0-based)PYQTTreeView None → no default value, ignoredPYQTTreeWidget None → no default value, ignoredPYQTWindow [int, int, int, int] → tuple or list with top and left corner coordinates, width and height
PySide Types
PYSIDECheckAction boolPYSIDECheckBox QtCore.Qt.CheckStatePYSIDECheckButton boolPYSIDEComboBox int → current item index (0-based)PYSIDEComboBoxEditable int → current item index (0-based)PYSIDEDateEdit str → string in format ‘yyyy.MM.dd’ or QDate objectPYSIDEDateTimeEdit str → string in format ‘yyyy.MM.dd HH:mm:ss.zzz’ (24 hours) or QDateTime objectPYSIDEDial int, floatPYSIDEDoubleSpinBox int, floatPYSIDELineEdit strPYSIDEListView None → no default value, ignoredPYSIDEListWidget None → no default value, ignoredPYSIDEPlainTextEdit strPYSIDERadioButton boolPYSIDEScrollArea [int, int] → tuple or list with horizontal and vertical scroll valuesPYSIDEScrollBar intPYSIDESlider int, floatPYSIDESpinBox int, floatPYSIDESplitter [int, int, …] → tuple or list with section sizesPYSIDEStackedWidget int → current widget index (0-based)PYSIDETabWidget int → current tab index (0-based)PYSIDETableView None → no default value, ignoredPYSIDETableWidget None → no default value, ignoredPYSIDETextEdit strPYSIDETimeEdit str → string in format ‘HH:mm:ss.zzz’ (24 hours) or QTime objectPYSIDEToolBox int → current tab index (0-based)PYSIDETreeView None → no default value, ignoredPYSIDETreeWidget → no default value, ignoredPYSIDEWindow [int, int, int, int] → tuple or list with top and left corner coordinates, width and height
Maya Types
MCheckBox boolMCheckBoxGrp1 [bool] → tuple or listMCheckBoxGrp2 [bool, bool] → tuple or listMCheckBoxGrp3 [bool, bool, bool] → tuple or listMCheckBoxGrp4 [bool, bool, bool, bool] → tuple or listMColorSliderGrp [float, float, float] → tuple or list with Red, Green and Blue values (0-1 range)MFloatField floatMFloatFieldGrp1 [float] → tuple or listMFloatFieldGrp2 [float, float] → tuple or listMFloatFieldGrp3 [float, float, float] → tuple or listMFloatFieldGrp4 [float, float, float, float] → tuple or listMFloatScrollBar floatMFloatSlider floatMFloatSliderGrp floatMFrameLayout bool → collapse stateMIconTextCheckBox boolMIconTextRadioButton boolMIconTextScrollList [int, int, …] → tuple or list with selected indexesMIntField intMIntFieldGrp1 [int] → tuple or listMIntFieldGrp2 [int, int] → tuple or listMIntFieldGrp3 [int, int, int] → tuple or listMIntFieldGrp4 [int, int, int, int] → tuple or listMIntScrollBar intMIntSlider intMIntSliderGrp intMOptionMenu int → current item index (1-based)MOptionMenuGrp int → current item index (1-based)MRadioButton boolMRadioButtonGrp1 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, ignoredMScrollField strMScrollLayout [int, int] → tuple or list with horizontal and vertical scroll valuesMShelfTabLayout int → current tab index (1-based)MSymbolCheckBox boolMTabLayout int → current tab index (1-based)MTextField strMTextFieldButtonGrp strMTextFieldGrp strMTextScrollList [int, int, …] → tuple or list with selected indexes
PyMel Types
PMCheckBox boolPMCheckBoxGrp1 [bool] → tuple or listPMCheckBoxGrp2 [bool, bool] → tuple or listPMCheckBoxGrp3 [bool, bool, bool] → tuple or listPMCheckBoxGrp4 [bool, bool, bool, bool] → tuple or listPMColorSliderGrp [float, float, float] → tuple or list with Red, Green and Blue values (0-1 range)PMFloatField floatPMFloatFieldGrp1 [float] → tuple or listPMFloatFieldGrp2 [float, float] → tuple or listPMFloatFieldGrp3 [float, float, float] → tuple or listPMFloatFieldGrp4 [float, float, float, float] → tuple or listPMFloatScrollBar floatPMFloatSlider floatPMFloatSliderGrp floatPMFrameLayout bool → collapse statePMIconTextCheckBox boolPMIconTextRadioButton boolPMIconTextScrollList [int, int, …] → tuple or list with selected indexesPMIntField intPMIntFieldGrp1 [int] → tuple or listPMIntFieldGrp2 [int, int] → tuple or listPMIntFieldGrp3 [int, int, int] → tuple or listPMIntFieldGrp4 [int, int, int, int] → tuple or listPMIntScrollBar intPMIntSlider intPMIntSliderGrp intPMOptionMenu int → current item index (1-based)PMOptionMenuGrp int → current item index (1-based)PMRadioButton boolPMRadioButtonGrp1 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, ignoredPMScrollField strPMScrollLayout [int, int] → tuple or list with horizontal and vertical scroll valuesPMShelfTabLayout int → current tab index (1-based)PMSymbolCheckBox boolPMTabLayout int → current tab index (1-based)PMTextField strPMTextFieldButtonGrp strPMTextFieldGrp strPMTextScrollList [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:
from fxpt3.fx_prefsaver import PrefSaver
myPrefSaver = PrefSaver(mySerializer)For Python 2 use fxpt package:
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)