I have previously read several topics on this site and other platforms, but my code does still not work as desired. I seem not to be able to put all the puzzle pieces together and need someone to look over my code.
I'm writing a plugin for the program QtiPlot. Im using Python 2.7.6 and PyQt4. I created the Plugin GUI with QT Designer. I'm also new to Python. Im using these "old" resources because my predecessor has used them.
My current task is to develop the settings, i.e. being able to save and restore parameters. I found a template on this site for this purpose: Python PyQt4 functions to save and restore UI widget values?
I want to save parameters to an Ini-File. However I have problems with the QVariants. Instead of the strings I inserted in the plugin, the expression "PyQt4.QtCore.QVariant object at 0x08667FB0" is being saved. I already know that this is an issue due to the fact that the QVariants are not correcly converted back to Python objects.
So, in order to convert the QVariants back manually, I added the phrase "toString()" to the value assignment of QLineEdit-Objects in the restore function(the line commented out is the previous version). But then my QLineEdit-Blocks in the plugin are empty, which confuses me. I read in the documentation that an empty string is returned if the QVariant does not consist of one of the preset types, including string. But this happens although I entered a string before.
Does this mean that the strings are not correctly saved in the first place? Or else what does it mean, what do I miss or what am I doing wrong?
I also noticed that no values are stored in the Ini-File, so that part of the code is also still buggy. But I'm not sure if this due to the fact that the save-function doesn't work or because the Ini-construction is wrong itself.
Further, I tried to use the SIP-Module at the head of the configuration file to fix my problem(it is commented out, too, because it didn't work for me so far). But although I placed this at the head of the code, I then get the error "API 'QVariant' has already been set to version 1". I don't understand why or from what the SIP-instruction is overridden. Is there any way to fix this?
My Configuration program looks like this:
#import sip
#sip.setapi('QVariant', 2)
#sip.setapi('QString', 2)
import inspect
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
sys.path.append("C:\\Program Files (x86)\\QtiPlot\\app\\02 Python Packages")
import PyQt4_Save_Restore_UI_Widget_Values
class app_conf(QtGui.QWidget):
def __init__(self):
super(self.__class__, self).__init__()
self.version = 1.0
QtCore.QCoreApplication.setOrganizationName("Organization")
QtCore.QCoreApplication.setApplicationName("Application")
QtCore.QSettings.setPath(QSettings.IniFormat, QSettings.UserScope, "C:\\Program Files (x86)\\QtiPlot\\app\\02 Python Packages\\saved.ini")
self.settings = QtCore.QSettings("C:\\Program Files (x86)\\QtiPlot\\app\\02 Python Packages\\saved.ini", QSettings.IniFormat)
from PyQt4 import uic
self.ui = uic.loadUi(r"C:\Program Files (x86)/QtiPlot/app/03 UI Files/Config.ui")
PyQt4_Save_Restore_UI_Widget_Values.gui_restore_settings(self.ui, self.settings)
self.ui.closeEvent = self.closeEvent
self.ui.show()
def closeEvent(self, event):
PyQt4_Save_Restore_UI_Widget_Values.gui_save_settings(self.ui, self.settings)
window = app_conf()
And my settings module(PyQt4_Save_Restore_UI_Widget_Values.py) looks like this:
#===================================================================
# 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
def gui_save_settings(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)
def gui_restore_settings(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
value = settings.value(name).toString()
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.toBool()) # restore checkbox
################################################################
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()