QSettings setDefaultFormat(QSettings::IniFormat) does not work on the first created object
-
Hi All,
I am making a program on windows, that uses QSettings objects to read and write settings.
In main, I write the following:QCoreApplication::setOrganizationName("me"); QCoreApplication::setOrganizationDomain("me.nl"); QCoreApplication::setApplicationName("myProgram");
in other files I have the following:
QSettings * settings = new QSettings; settings->setValue("Start",((QDateTimeEdit*)(myTableWidget->cellWidget(i,IDXSTART)))->dateTime());
This works fine, but I would like to use .ini files. Therefore I do the following:
QSettings * settings = new QSettings; settings->setDefaultFormat(QSettings::IniFormat); qDebug()<<"Reading settings from:"<< settings->fileName();
The first created QSettings object, reads from the registry, all the QSettings objects that are created after it, correctly read and write from the .ini file.
I can solve this by using the following constructor, but then I also need to specify the filename: I would not like to do this, as I then have to feed the same filename throughout my entire program, and I don't like the idea of using hardcoded paths
QSettings(const QString &fileName, Format format, QObject *parent = Q_NULLPTR)
I can also use this constructor, but then I have to specify my organisation, and application name in multiple places in my program.
QSettings(Scope scope, const QString &organization, const QString &application = QString(), QObject *parent = Q_NULLPTR)
After a search in this forum, I found somebody who has created a global QSettings object:
https://forum.qt.io/post/328451// in .h-File class MainWindow : public QMainWidnow { Q_OBJECT public: static QSettings Settings; }; // beginning of .cpp-File QSettings MainWindow::Settings = QSettings("My Company Inc.", "My Application"); Then use MainWindow::Settings.setValue( ... ); MainWindow::Settings.value( ... );
This looks good, as I then enter the information in exactly one place in the application, but somebody else then made an argument against a global QSettings object:
https://forum.qt.io/post/306740You are using QSettings in a global variable. Move the initialisation inside the main(). Looks like you are using a statically linked Qt, right ? Your QSettings is a global variable, QSettings implementation itself rely on other global variables. The order of initialisation of global variables is undefined. What could work, from worst to best: shuffle the link order around to get QSettings globals initialised first (that would be a very fragile fix) link Qt as a shared library, shared lib would be loaded and initialised before your code. Don't build a QSettings as a global, replace it with a QSettings * and build it in main().
What is the correct way to use .ini files on Windows without having to enter the same information in multiple places in the application?
Is the global object method above correct, or fragile?Cheers,
Cedric -
Hi, I've also faced the same conundrum as you, and knowing from previous bad experiences that global Qt objects is something to avoid, I wrote a simple utility class to encapsulate a QSettings instance.
To avoid repeating the file information, I used one nifty C++ trick: delegating constructor, like this:class AppSettings { QSettings* pSettings; public: AppSettings() : AppSettings(qApp->applicationName() + ".ini") {} // use appname.ini as filename AppSettings(QString sIniFileName); // use the specified filename ~AppSettings(); bool readBool (QString sKeyName); bool readBoolWithFallback (QString sKeyName,bool bFallbackValue); int readInt (QString sKeyName); int readIntWithFallback (QString sKeyName,int nFallbackValue); QString readString (QString sKeyName); QString readStringWithFallback(QString sKeyName,QString sFallbackValue); void writeBool (QString sKeyName,bool bValue); void writeInt (QString sKeyName,int nValue); void writeString (QString sKeyName,QString sValue) };
Then i my app, I just declare an
AppSettings settings;
and voila I can read/write from an .ini file, e.g.settings.readString("SavedNumber");
. If you want to see the code in all its glory, its here