[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