Python PyQt4 functions to save and restore UI widget values?
Here's an updated snippet which originally shared by mr. Panofish. Those great functions are same, but now can be used on never versions of PyQt and Python with minor changes if needed. Thx mr. Panofish, long live OpenSource! :)
Changes:
- Updated for Python3 and PyQt5
- Added geometry save\restore
- Added QRadioButton save\restore
SetCheckState() replcaed with SetChecked() in order to avoid tristate
def guisave(self): # Save geometry self.settings.setValue('size', self.size()) self.settings.setValue('pos', self.pos()) for name, obj in inspect.getmembers(ui): # if type(obj) is QComboBox: # this works similar to isinstance, but missed some field... not sure why? if isinstance(obj, QComboBox): name = obj.objectName() # get combobox name index = obj.currentIndex() # get current index from combobox text = obj.itemText(index) # get the text for current index settings.setValue(name, text) # save combobox selection to registry if isinstance(obj, QLineEdit): name = obj.objectName() value = obj.text() settings.setValue(name, value) # save ui values, so they can be restored next time if isinstance(obj, QCheckBox): name = obj.objectName() state = obj.isChecked() settings.setValue(name, state) if isinstance(obj, QRadioButton): name = obj.objectName() value = obj.isChecked() # get stored value from registry settings.setValue(name, value) def guirestore(self): # Restore geometry self.resize(self.settings.value('size', QtCore.QSize(500, 500))) self.move(self.settings.value('pos', QtCore.QPoint(60, 60))) for name, obj in inspect.getmembers(ui): if isinstance(obj, QComboBox): index = obj.currentIndex() # get current region from combobox # text = obj.itemText(index) # get the text for new selected index name = obj.objectName() value = (settings.value(name)) if value == "": continue index = obj.findText(value) # get the corresponding index for specified string in combobox if index == -1: # add to list if not found obj.insertItems(0, [value]) index = obj.findText(value) obj.setCurrentIndex(index) else: obj.setCurrentIndex(index) # preselect a combobox value by index if isinstance(obj, QLineEdit): name = obj.objectName() value = (settings.value(name).decode('utf-8')) # get stored value from registry obj.setText(value) # restore lineEditFile if isinstance(obj, QCheckBox): name = obj.objectName() value = settings.value(name) # get stored value from registry if value != None: obj.setChecked(strtobool(value)) # restore checkbox if isinstance(obj, QRadioButton): name = obj.objectName() value = settings.value(name) # get stored value from registry if value != None: obj.setChecked(strtobool(value))
thank you Panofish and everyone i am adding some update for QSlider/QSpinBox. it's small and simple.
at guisave you can add :
if isinstance(obj, QSpinBox):
name = obj.objectName()
value = obj.value() # get stored value from registry
settings.setValue(name, value)
if isinstance(obj, QSlider):
name = obj.objectName()
value = obj.value() # get stored value from registry
settings.setValue(name, value)
at guirestore you can add :
if isinstance(obj, QSlider):
name = obj.objectName()
value = settings.value(name) # get stored value from registry
if value != None:
obj. setValue(int(value)) # restore value from registry
if isinstance(obj, QSpinBox):
name = obj.objectName()
value = settings.value(name) # get stored value from registry
if value != None:
obj. setValue(int(value)) # restore value from registry
I'm adding update for QListWidget.
In guisave:
if isinstance(obj, QListWidget):
name = obj.objectName()
settings.beginWriteArray(name)
for i in range(obj.count()):
settings.setArrayIndex(i)
settings.setValue(name, obj.item(i).text())
settings.endArray()
in guirestore:
if isinstance(obj, QListWidget):
name = obj.objectName()
size = settings.beginReadArray(name)
for i in range(size):
settings.setArrayIndex(i)
value = settings.value(name) # get stored value from registry
if value != None:
obj.addItem(value)
settings.endArray()
OK, I wrote a module with 2 functions to do what I was asking for. Not really that complicated, once I figured it out, but it sure does save a lot of time whenever you create new pyqt gui programs where you want to save widget field values between sessions. I currently only have lineEdit, checkBox and combobox fields coded. If anyone else wants to add or improve (e.g. radio buttons...etc) ... I'm sure others, including myself, will appreciate it.
#===================================================================
# Module with functions to save & restore qt widget values
# Written by: Alan Lilly
# Website: http://panofish.net
#===================================================================
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import inspect
#===================================================================
# save "ui" controls and values to registry "setting"
# currently only handles comboboxes editlines & checkboxes
# ui = qmainwindow object
# settings = qsettings object
#===================================================================
def guisave(ui, settings):
#for child in ui.children(): # works like getmembers, but because it traverses the hierarachy, you would have to call guisave recursively to traverse down the tree
for name, obj in inspect.getmembers(ui):
#if type(obj) is QComboBox: # this works similar to isinstance, but missed some field... not sure why?
if isinstance(obj, QComboBox):
name = obj.objectName() # get combobox name
index = obj.currentIndex() # get current index from combobox
text = obj.itemText(index) # get the text for current index
settings.setValue(name, text) # save combobox selection to registry
if isinstance(obj, QLineEdit):
name = obj.objectName()
value = obj.text()
settings.setValue(name, value) # save ui values, so they can be restored next time
if isinstance(obj, QCheckBox):
name = obj.objectName()
state = obj.checkState()
settings.setValue(name, state)
#===================================================================
# restore "ui" controls with values stored in registry "settings"
# currently only handles comboboxes, editlines &checkboxes
# ui = QMainWindow object
# settings = QSettings object
#===================================================================
def guirestore(ui, settings):
for name, obj in inspect.getmembers(ui):
if isinstance(obj, QComboBox):
index = obj.currentIndex() # get current region from combobox
#text = obj.itemText(index) # get the text for new selected index
name = obj.objectName()
value = unicode(settings.value(name))
if value == "":
continue
index = obj.findText(value) # get the corresponding index for specified string in combobox
if index == -1: # add to list if not found
obj.insertItems(0,[value])
index = obj.findText(value)
obj.setCurrentIndex(index)
else:
obj.setCurrentIndex(index) # preselect a combobox value by index
if isinstance(obj, QLineEdit):
name = obj.objectName()
value = unicode(settings.value(name)) # get stored value from registry
obj.setText(value) # restore lineEditFile
if isinstance(obj, QCheckBox):
name = obj.objectName()
value = settings.value(name) # get stored value from registry
if value != None:
obj.setCheckState(value) # restore checkbox
#if isinstance(obj, QRadioButton):
################################################################
if __name__ == "__main__":
# execute when run directly, but not when called as a module.
# therefore this section allows for testing this module!
#print "running directly, not as a module!"
sys.exit()