Reputation: 51
I have a pretty standard Qt GUI application. It uses Qt's QSettings to store a number of settings, and it all works fine.
However, when multiple copies of the application are launched, and settings are changed in one or the other, the different copies can appear inconsistent (as one has the "old" copy of the data).
What are the preferred solutions to this problem? I guess this problem occurs, even outside of the Qt arena.
Upvotes: 4
Views: 1410
Reputation: 8067
I am facing the same problem. There is QSettings::sync()
function but it seems to take of the integrity of the settings file (INI, registry etc.) than to make the settings consistent with the state of the application. By this 'consistency' I mean for example that when as a user I change the font size value in the settings dialog, I expect the whole application to be re-layouted and repainted. This is easy to achieve within one instance of application (using signals-slots, events etc.). But when I have two or more applications running, the other instances get no information that the font size settings was changed, they are not re-layouted nor repainted and later when any widget gets drawn using the new font size initialized from the QSettings
, it becomes inconsistent with the rest of the application and the layout get potentially broken.
There is however a solution to this. It requires adding another 'caching' level for all settings, above QSettings
. All the settings will be loaded to some settings data class using QSettings::value(...)
only at the application start, and during the run of the application the application will not directly read from QSettings::value()
but only from the cache. This way you will have fully consistent behavior. When the user changes some setting in settings dialog, each item will be compared to the cached value (i.e. check whether the user changed it) and if it is not equal, it gets written to settings using QSettings::setValue()
.
// To be created at application startup, just after
// QApplication::setApplication(), setOrganizationName() etc. is called.
// When the application is running, you only obtain cached values
// from the instance of Settings instead of querying QSettings.
class Settings
{
Settings() {
m_x = QSettings().value("x", 0).toInt();
}
int x() const {
return m_x;
}
void setX(int x) {
if (x == m_x)
return;
m_x = x;
QSettings().setValue("x", x);
}
private:
int m_x;
}
Upvotes: 0
Reputation: 67836
The QSettings docs mention this in the Accessing Settings from Multiple Threads or Processes Simultaneously section:
Have you tried to call yoursettings.sync() from the writer app after writing values and from the reader app before reading them? If so, and if your logic is correct, this sounds like a Qt bug.
Upvotes: 2