[Interest] Write QSettings to a QString in INI format
Henry Skoglund
henry at tungware.se
Sat Oct 26 12:15:24 CEST 2019
On 2019-10-26 11:43, Konrad Rosenbaum wrote:
> Hi,
>
> On 10/24/19 5:53 PM, Murphy, Sean wrote:
>> I'd like to be able to have QSettings write out my settings to an INI
>> file format, but I'd like to avoid writing it to an actual file,
>> instead just writing it to "something" in memory (for example, a
>> QString, QByteArray, QBuffer, etc.).
>>
> That's because QSettings is rather complex underneath - it handles
> stuff like multiple instances accessing the same file at the same
> time, hierarchies of settings-files (e.g. system level and user
> level), etc. If you handed in a QIODevice then QSettings could not be
> sure what the state of the underlying IO-Object is and whether it is
> safe to access it.
>> So I if all the above is correct, and there is no way to write an INI
>> formatted string to memory, and given the fact that I really don't
>> want a file in the first place, I decided to look at writing the
>> settings out to a QTemporaryFile, then just reading that data back in
>> as a string, and then let the QTemporaryFile go out of scope and
>> clean itself up. But according to the following test code, QSettings
>> does not seem to play nicely with QTemporaryFile:
> This is basically the way to go.
>>
>> void MainWindow::writeSettings()
>> {
>> // comment/uncomment the *define* below to switch implementations
>> #define USE_QTEMPORARY_FILE
>>
>> #ifdef USE_QTEMPORARY_FILE
>> // using a QTemporaryFile doesn't seem to work
>> QTemporaryFile tempFile;
>> bool ok = tempFile.open();
>> #else
>> // if instead you use a regular QFile, it works
>> QFile tempFile("tempFile.ini");
>> bool ok = tempFile.open(QIODevice::ReadWrite);
>> #endif
>>
>> if(ok)
>> {
>> qDebug() << "Opened" << tempFile.fileName();
>> } else {
>> qDebug() << "Unable to open" << tempFile.fileName();
>> }
> Call tempFile.fileName() before you call close()! (But close() before
> you instantiate QSettings.)
>> tempFile.close();
>>
>> QSettings settings(tempFile.fileName(), QSettings::IniFormat);
>> settings.setValue("string", "hello");
>> settings.setValue("int", 2);
>>
>> settings.sync();
>> // using QTemporaryFile always produces an AccessError here,
> 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.
Rgrds Henry
More information about the Interest
mailing list