Reading [General] section in ini-files
-
Hi,
I am currently porting some old Delphi-based software to Qt. One task is to read the contents of a large number of Windows ini-files. These files are pre-made, and are used by a number of different tools, so the format cannot be changed.
I use the QSettings class to read these ini-files. My problem is, that the QSettings functions cannot access the [General] section. For a reason that I don't quite understand, Qt uses the section name [%General] instead of [General]. Ususally, this wouldn't be a problem, because most softwares only read the ini-files they have written themselves.
However, I have to read the [General] section (without %). So my question is: Has anybody found a way for the QSettings functions to read the [General] section? (I only need to read the contents – not write anything.)
My work-around would be to make my own ini-file reader, but it seems a bit "overkill" for just a percent sign.
I have tried the following approaches:
settings.beginGroup("General"); ModuleName=settings.value("ModuleName").toString();
settings.beginGroup("General/"); ModuleName=settings.value("ModuleName").toString();
ModuleName=settings.value("General/ModuleName").toString();
None of these accessed the actual [General] section.
-
We let our QSettings write to the default location. So, I don't really know how Windows handles this (the default location on Windows is the registry). But I had a look what Linux does. What I found there is that if I don't specify any group values are put under the section
[General]
. Maybe the only thing you have to do to read the[General]
section is to not use a group. It might be that just for your own groupGeneral
Qt will put a%
in front of the name to distinguish it from the non-group stuff. -
Copy the ini-file, replace
[General]
with something different and read this. -
Copy the ini-file, replace
[General]
with something different and read this.@Christian-Ehrlicher
Unfortunately, this is not possible, as this is a large collection of ini-files that a number of different software tools are already using. Modifying the ini-files is not an option. -
@Christian-Ehrlicher
Unfortunately, this is not possible, as this is a large collection of ini-files that a number of different software tools are already using. Modifying the ini-files is not an option.@ErikThomsen Why can't you copy the ini file before trying to read it with Qt?
-
or, if copying is not possible, why not read it in memory change
General
there and read it than with QSettingssurely the file is not Gbytes big ?
-
@ErikThomsen Why can't you copy the ini file before trying to read it with Qt?
@Christian-Ehrlicher
It is not one file. It is a large number of files, full of configuration data, used by numerous different software tool.
These files gradualy increase in number, and occationally the contents change. Therefore, we need a common pool of these files, so only one set of files is maintained. -
I still don't understand why you can't copy the file to a temp dir, modify it and read it with Qt...
-
or, if copying is not possible, why not read it in memory change
General
there and read it than with QSettingssurely the file is not Gbytes big ?
@J-Hilk
No, the files are not huge. And your solution would probably work.
My own solution will probaby be something similar, such as parsing the [General] section as a text file. All the other sections work as they should.I just hoped that someone had found a way to tweak QSettings directly.
@Christian-Ehrlicher
In that case, it will be necessary for the software to do this everytime it is used. I find that impratical. -
@ErikThomsen said in Reading [General] section in ini-files:
In that case, it will be necessary for the software to do this everytime it is used. I find that impratical.
And what's different from your / @J-Hilk's idea? It's a simple class derived from QSettings...
ok, deriving does not work due to QSettings constraints, ~12 lines of code without error checking...
class MySettings { public: MySettings(const QString &fn) { QFile f(fn); f.open(QIODevice::ReadOnly); QByteArray ba = f.readAll(); f.close(); temp.open(); temp.write(ba.replace("[General]", "[Blub]")); temp.close(); m_settings = new QSettings(temp.fileName(), QSettings::IniFormat); } ~MySettings() { delete m_settings; } QSettings *settings() { return m_settings; } private: QSettings *m_settings = nullptr; QTemporaryFile temp; }
-
We let our QSettings write to the default location. So, I don't really know how Windows handles this (the default location on Windows is the registry). But I had a look what Linux does. What I found there is that if I don't specify any group values are put under the section
[General]
. Maybe the only thing you have to do to read the[General]
section is to not use a group. It might be that just for your own groupGeneral
Qt will put a%
in front of the name to distinguish it from the non-group stuff. -
@ErikThomsen said in Reading [General] section in ini-files:
In that case, it will be necessary for the software to do this everytime it is used. I find that impratical.
And what's different from your / @J-Hilk's idea? It's a simple class derived from QSettings...
ok, deriving does not work due to QSettings constraints, ~12 lines of code without error checking...
class MySettings { public: MySettings(const QString &fn) { QFile f(fn); f.open(QIODevice::ReadOnly); QByteArray ba = f.readAll(); f.close(); temp.open(); temp.write(ba.replace("[General]", "[Blub]")); temp.close(); m_settings = new QSettings(temp.fileName(), QSettings::IniFormat); } ~MySettings() { delete m_settings; } QSettings *settings() { return m_settings; } private: QSettings *m_settings = nullptr; QTemporaryFile temp; }
@Christian-Ehrlicher
I just need to read some pre-made ini-files. Not modify them.
But I have solved the issue by reading the ini-file as a text file, and parsing the lines in the [General] section manually. -
@ErikThomsen said in Reading [General] section in ini-files:
I just need to read some pre-made ini-files. Not modify them.
I never said that you should modify them... read my osts and suggestion properly!
-
We let our QSettings write to the default location. So, I don't really know how Windows handles this (the default location on Windows is the registry). But I had a look what Linux does. What I found there is that if I don't specify any group values are put under the section
[General]
. Maybe the only thing you have to do to read the[General]
section is to not use a group. It might be that just for your own groupGeneral
Qt will put a%
in front of the name to distinguish it from the non-group stuff.@SimonSchroeder
Aaaah! That's interesting!
Will try it. Thanks!Due to the posting frequency limit for newbies, I had plenty om time to try it out.
It works nicely.Instead of
settings.beginGroup("General");
which accesses [%General], I use
settings.beginGroup("");
which accesses [General]. The compiler gives me a warning, but that can be ignored.
-
@ErikThomsen said in Reading [General] section in ini-files:
I just need to read some pre-made ini-files. Not modify them.
I never said that you should modify them... read my osts and suggestion properly!
@Christian-Ehrlicher
I apologize for being stupid. If you didn't mean to copy and modify the files, then I simply don't understand your suggestion.In any case, the hint from @SimonSchroeder solved the issue.
-
I use the file, generate a modified temoprary file and use this for QSettings. The temporary file is deleted right after the class gets destructed. So it's the same as @J-Hilk suggested. I never modified the original one so I don't see what's your problem with my suggestion...
-
@SimonSchroeder
Aaaah! That's interesting!
Will try it. Thanks!Due to the posting frequency limit for newbies, I had plenty om time to try it out.
It works nicely.Instead of
settings.beginGroup("General");
which accesses [%General], I use
settings.beginGroup("");
which accesses [General]. The compiler gives me a warning, but that can be ignored.
@ErikThomsen said in Reading [General] section in ini-files:
I use
settings.beginGroup("");which accesses [General]. The compiler gives me a warning, but that can be ignored.
I am not sure what the compiler warns about. But, you don't have to start any group. Just drop the
beginGroup(...)
altogether (and also the correspondingendGroup()
).