[Interest] Write QSettings to a QString in INI format

Henry Skoglund henry at tungware.se
Sat Oct 26 18:25:05 CEST 2019


On 2019-10-26 17:31, Murphy, Sean wrote:
>>> Because QSettings has the file locked. Make sure settings goes out of
>>> scope before you re-open the file.
>>>
>> Granted, it's complex with the locking code, but underneath it all you have
>> this hidden gem writeIniFile(), which takes a QIODevice and the map (you
>> know, the function with those hardwired [General] and [General%] strings).
>>
>> Suggestion: you have this nice extension/plugin call
>> QSettings::registerFormat(), which takes a readFunc and a writeFunc ptr.
>> If that writeIniFile() could be exposed as a public writeFunc ptr (yes it has the
>> same function signature) then you could have users bypass the locking stuff,
>> by requiring them to register a new format (say with the extension "buffer"
>> for a QBuffer) but allowing them to reuse the existing writeIniFile() as their
>> own writeFunc (and say a QBuffer as the QIODevice).
>> That way you could access the streaming functionality of QSettings without
>> involving the file system.
> Is the suggestion to me, or to the Qt development team? Because even if I
> somehow expose the writeIniFile() function so that I can use it, the only
> applicable QSettings constructor that allows me to specify a registered format
> is this one:
>      QSettings(const QString &fileName, QSettings::Format format, QObject *parent = nullptr)
> And the behavior of that constructor is that it opens an actual file on the
> filesystem with "fileName" (use an existing file if the file already existed before
> this call, otherwise creating a file with that name if it didn't already exist), then
> sets the QIODevice to point at the file, and then uses your registered format's
> function pointers to handle the reading and writing of it. There does not appear
> to be any way for me to point the created QSettings object at my QBuffer, even
> if I got access to the writeIniFile(), correct? Or am I missing something?
>
A suggestion for development, to add these 2 static public members to 
QSettings:
QSettings::ReadFunc getReadFunc(QSettings::Format format);
QSettings::WriteFunc getWriteFunc(QSettings::Format format);

never mind about the ReadFunc functionality right now, let's look at the 
getWriteFunc, say you could use it to obtain a function pointer to that 
hidden gem I wrote about earlier, writeIniFile():

QSettings::ReadFunc myReadFunc; // only a dummy for now

QString s;
QBuffer b(&s);
bool myWriteFunc(QIODevice &device, const QSettings::SettingsMap &map)
{
// ignore the QIODevice QSettings gives us, instead replace it with our 
QBuffer;
     bool bOk = QSettings::getWriteFunc(QSettings::IniFormat)(b,map);
}

// register
QSettings::Format myFormat = 
QSettings::registerFormat("buffer",myReadFunc,myWriteFunc);

// and then start the party by:
{
     auto mySettings = QSettings("tempfile.buffer",myFormat);
     settings.setValue("string", "hello");
     settings.setValue("int", 2);
}
// with a bit of luck the b.buffer() should now contain 
"[General]\nstring=Hello\nint=2"

So you're right that there's no way to avoid dipping your toes into the 
file system, but by short-circuiting the writes the resulting file would 
always be empty and the QBuffer b would be the lucky winner.

Rgrds Henry



More information about the Interest mailing list