Re: QSettings - how to use?
Speed isn't really much of an issue for most cases; settings tend to be small, and in many cases the results of the first read will hang around in the I/O buffer anyway, making subsequent reads that much faster. However, if you're using QSettings as an adjunct to a general purpose preferences-style framework, you'll want an in-memory copy in most cases so the user can modify settings in a one-shot manner without overwriting the file-based set unless explicitly requesting such an overwrite. Here, your program will always read from the in-memory copy, which gets initialized during startup and might be modified at runtime through an options panel having both "Save" and "Use" (and "Cancel") choices.
Re: QSettings - how to use?
SixDegrees, thank you for your opinion! I got the idea.
Re: QSettings - how to use?
my 2 cents:
I try to avoid callings to qsettings...
in my QMainWindow (or in other dialog)
i read settings related to that dialog at the beggining into variables...
and in the close event i write to qsettings. (or in accept() )
if my main window open a dialog who need read a setting of main window... i'll pass as a parameter.
only I read settings directly when the setting is not specific for any dialog..
Re: QSettings - how to use?
I made my settings code with a bunch of variables. But now that I think about it, it probably makes more sense to access settings in the ini/reg file directly since you're reducing the amount of memory needed for the stack.
Comments?
Re: QSettings - how to use?
1 - Caching the settings into variables on startup and writing changes back out at exit will make your code run faster, at the expense of some small amount of extra memory. If you create MainWindow on the stack in main(), then these variables will also live on the stack.
2 - Accessing QSettings as needed from within your code is slower, but you don't need to find ways of passing all those variable values around. I wrote a little wrapper class that has static readValue() and writeValue() methods. Inside the static methods, it creates a QSettings instance on the stack that is initialized with the organization and application name (obtained from qApp()), sets it to User mode and Ini format and reads or writes the values through that. The qApp settings are set in main() at program startup. So in one line I can write something like this with all of the QSettings construction stuff hidden away:
Code:
MySettings::writeValue( "Foo/Bar", "Baz" );
3 - Caching the settings means that if your program crashes, you lose any changes because you never get to the MainWindow's writeSettings() call.
4 - Reading and writing settings on demand means that changes are immediately committed. QSettings is thread- and process-safe.
In most of my applications, I use method (2) because the overhead is negligible and I never do it from within process-critical code. It is also way more convenient with the wrapper class. You could even get fancy and provide multiple readValue() methods that do the QVariant conversion for you:
Code:
// static
int MySettings
::readValue( const QString & key,
int defaultVal
) {
bool bOk;
int testVal = var.toInt( &bOk );
if ( bOk )
return testVal;
else
return defaultVal;
}
Re: QSettings - how to use?
Thanks for that, very helpful, I'm leaning in the direction of on demand access to ini/reg files as well. I'm already creating LoadSettings() and SaveSettings() functions in 3 different classes and the associated member variables and I'm only starting out.
Ah you're one step ahead of me. After starting to write a class for managing settings as you suggested I immediately ran into the problem of dealing with different data types. Reading about QVariant, seems like it's basically a placeholder for different datatypes?
Re: QSettings - how to use?
EDIT: Something to do with unions. No idea what they are just learned about them, need to do some reading.
Re: QSettings - how to use?
Quote:
Something to do with unions.
Don't worry about how QVariant is implemented internally, you'll just wind up leading yourself astray and your sheep dog will have to round you up with a lot of barking and nipping at heels. Yes, it *acts* like a union in that you can store as one type and retrieve as another, but just know (and appreciate) that you can store any fundamental type (int, float, double, etc.), nearly any Qt type (QString, etc.), and any custom type (with the right wrapper) in one and retrieve it afterwards exactly as it was stored. In this way it goes well beyond the C++ definition of union. It is more like a general purpose container that can hold one thing of any type.
The main use for QVariant is to allow you to write one method (like QSettings::setValue()) that allows you to store a value of any type (wrapped in a QVariant) as opposed to writing a zillion different setValue() methods, one for int, one for float, one for long, etc. as you usually have to do for the ">>" and "<<" operators.
Re: QSettings - how to use?
Oh I wasn't looking into the implementation of QVariant, I was just reading about unions since I had not heard of them before, now I know what they are and as you described, what QVariant is. The only question that I have about your code is why the return type is int if you're creating a function that can store any value? And why are you only accepting int as a parameter? Seems like QVariant is not necessary for your snippet? Could have gotten away with just an int?
I'm thinking code like this might be a bit more universal?
PS I haven't compiled it, so might be synatx errors, but for reading, you only need one variable and that's the name of the settings.
For writing, you simply put in whatever variable you want and reading will output the variable in the same format.
Re: QSettings - how to use?
Quote:
And why are you only accepting int as a parameter?
Well, in actual fact I am doing it that way:
Code:
// static
{
settings.beginGroup( group );
QVariant value
= settings.
value( key, defValue
);
settings.endGroup();
return value;
}
// static
{
settings.beginGroup( group );
settings.setValue( key, value );
settings.endGroup();
}