ShellRox
ShellRox

Reputation: 2602

PyQt4: Saving list to QSettings

I made an list (array) that would count number of game finish. But if someone restarted game, length of list would reset.

As I know QSettings is dedicated to save and store data. I have read documentation but didn't help me enough.

For example I have a global array:

global finishcount
finishcount = []

How can I apply this to QSettings? So then I can append data on it without data loss after restart.

Should it look something like this?

from PyQt4 import QtGui, QtCore
global finishcount
finishcount = []
settings = QtCore.QSettings(self)
settings.setValue(finishcount, self)

How can I achieve this? Or can I make list in QSettings itself where I can append something?

Upvotes: 3

Views: 7967

Answers (2)

ekhumoro
ekhumoro

Reputation: 120818

Below is a very simple demo that shows how to read and write a list of integers to QSettings. The demo automatically adds a new value every time the window is opened and closed.

If you're using PyQt, there is no need to use json at all. For lists, just provide a default, and specify the type of the contained values:

    settings.value('finishcount', [], int)

Demo:

from PyQt4 import QtCore, QtGui

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        settings = QtCore.QSettings('my_org', 'my_app')
        self._finishcount = settings.value('finishcount', [], int)
        print('read settings: %s' % self._finishcount)
        # add a new value for testing
        self._finishcount.append(len(self._finishcount))

    def closeEvent(self, event):
        settings = QtCore.QSettings('my_org', 'my_app')
        settings.setValue('finishcount', self._finishcount)
        print('save settings: %s' % self._finishcount)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(600, 100, 100, 100)
    window.show()
    sys.exit(app.exec_())

NB: for the special case of a list of strings, it's best to use this:

    settings.value('finishcount', [], 'QStringList')

rather than specifying the type with str. Otherwise, empty lists don't get treated properly.

Upvotes: 3

Brendan Abel
Brendan Abel

Reputation: 37599

Generally it looks something like this. This also assumes your using the v2 version of the QVariant api; otherwise, the results returned from QSettings.value is going to be a QVariant and you'll need to cast it to the appropriate python type. If you're using a recent version of PyQt then you should be on v2, but if not you can force it by sticking this at the top of your file

import sip
sip.setapi('QVariant', 2)
sip.setapi('QString', 2)

Also, even with the v2 version of the api, it often doesn't always work as expected with anything more complicated than strings or numbers. For more complex types like lists and dicts, I've found it's often better to serialize the values using json or pickle and save that to the QSettings instead, and then unserialize it myself when retrieving it.

import json

class MyWidget(QWidget):

    def __init__(self, parent):
        super(MyWidget, self).__init__(parent)
        self.myvalue = 10
        self.mylist = [1,2,3]
        self.restoreSettings()

    def closeEvent(self, event):
        self.saveSettings()
        super(MyWidget, self).closeEvent(event)

    def saveSettings(self):
        settings = QSettings('myorg', 'myapp')
        settings.setValue('myvalue', self.myvalue)
        settings.setValue('mylist', json.dumps(self.mylist))

    def restoreSettings(self):
        settings = QSettings('myorg', 'myapp')
        self.myvalue = settings.value('myvalue', self.myvalue)
        try:
            self.mylist = json.loads(settings.value('mylist', None))
        except (ValueError, TypeError):
            pass

Upvotes: 1

Related Questions