[SOLVED] Monitoring/watching QSettings changes. Or how do you watch for external settings changes?
Context: some settings are coming from network to file at the random moments
We are doing a network-connected hardware device and part of the settings come from network and once in a while get updated by the daemon whenever server wants to push the updates (think updating username/password for email client).
Would be goot to reuse QSettings parsing mechanism
Daemon is under our control and it is of no problem to ask daemon to use standard INI format and then QSettings for parsing values, but how do you monitor for the settings changes? Our device can be up and running for weeks and we need to notice the change in the the network originated settings. Certainly we could just QSettings::sync() every few seconds, but that would be useless CPU use and memory access and still be slower when e.g. debugging and changing settings often.
Howto: monitor AND QSettings?
I was thinking about using QFileSystemWatcher, yet then we should implement our own settings file parsing shouldn't we? Or will it be ok if I force QSettings to use exactly the file QFileSystemWatcher monitors and force QSettings::sync() whenever change is detected.
How would you do it?
And a followup:
Even if it's ok to monitor for changes via QFileSystemWatcher, how do I know which files are actually read by QSettings? To my understanding QSettings::fileName() tells only one of the files used, when where app would write the changes.
I actually implemented a similar routine a while back. What I did was like you are suggesting. I used a QFileSystemWatcher to notify my application when a change of the configuration file occured. However I did not use QSettings but used a self-written XML based interpreted due to the XML based structure of our config.
I would follow up on your approach and suggest to implement a "QFileSystemWatcher":http://qt-project.org/doc/qt-4.8/qfilesystemwatcher.html to look for changes in the settings and reload them by using "QSettings::sync() ":http://qt-project.org/doc/qt-4.8/qsettings.html#sync as necessary. If possible I would keep those settings that are likely to change during the lifetime of your application inside a separate file so you can react specifically on alterations in these settings.
That's pretty much what I am doing now. Seems to work, yet certainly I'd prefer more built-in flexibility.
One limitation for manual monitoring is that QSettings::fileName reports only one of the locations it is actually listening to. For our case it's ok, but I can easily imagine apps that would like to monitor all the settings changes regardless of where they come from.
I don't see a great problem there. AFAIK "QFileSystemWatcher::fileChanged(...)":http://qt-project.org/doc/qt-4.8/qfilesystemwatcher.html#fileChanged is emitted for every file that changed - so it shouldn't be a very challenging to map the path that is handed by fileChanged to the actual file.
In the worst case you could also install multiple watcher, but I don't think that should be necessary.
Listening to any file is not a problem as long as you know the name of a file to watch.
If I understand it correctly by default QSettings can fetch values from up to 4 different sources. E.g. from QSettings docs:
On Mac OS X versions 10.2 and 10.3, these files are used by default:
Only the first of the above file names is reported by QSettings::fileName(). If you want to listen to changes coming from the other ones you just have to know the file names. That is, of course, error-prone and not very cross-platform.
It's not an issue in my particular case (we use one file only), yet in general it would be cool to be able to watch for settings changes originating from any of the supported sources.