Using QSettings with data stored in a QByteArray, or QIODevice?

864 views Asked by At

I have data in ini format that was originally written using QSettings (and so it contains some QSettings-specific syntax) that is stored in a QByteArray. I'd like to be able to read and write to it using QSettings. Unfortunately, out of the box QSettings only seems capable of working with files specifically, and can't be used with a QByteArray or an instance of a class that derives from QIODevice such as QBuffer.

So far, I've found two ways of dealing with this:

  1. Dump the data temporarily into a file, probably using QTemporaryFile, and read that using QSettings
  2. Create a custom implementation of QAbstractFileEngine that can read from the data in the byte array as though it were a file, as suggested in this ten year old thread. However QAbstractFileEngine is no longer public in Qt 5 and so this is a not a viable option.

I'd like to avoid writing this data to disk if at all possible. Ten years have gone by since that old thread was posted. Is there a better method available now?

edit: For the time being I settled on using QAbstractFileEngine even though it's private in Qt 5. At least it's still around as of Qt 5.15. If it's ever removed I'll update my code to use a different method. I'm going to keep this question open, though, in case someone can answer with another viable method that doesn't use QTemporaryFile.

edit 2: QAbstractFileEngine only works for reading settings. Writing settings using QSettings unfortunately always assumes the file is a native file.

1

There are 1 answers

1
JarMan On

I think you can achieve what you want by registering your own format. You provide your own read/write functions, so you can do anything you want inside them. The docs provide an example for using an XML format. You can easily modify this to write into a QByteArray.

// Buffer to store settings
QByteArray someBuffer;

bool readSettingsFromBuffer(QIODevice &device, QSettings::SettingsMap &map)
{
    // Ignore "device" and read from someBuffer instead.
}

bool writeSettingsToBuffer(QIODevice &device, const QSettings::SettingsMap &map)
{
    // Ignore "device" and write to someBuffer instead.
}

int main(int argc, char *argv[])
{
    const QSettings::Format BufferFormat =
            QSettings::registerFormat("buffer", readSettingsFromBuffer, writeSettingsToBuffer);

    QSettings settings(BufferFormat, QSettings::UserScope, "MyCompany",
                       "MyApplication");

    ...
}