Menu

Home

borisbn

1 Main concept

If your program has some parameters, that you want to be editable from the GUI, you should just write xml-file in proper format, create an instance of class Config, call slot Config::show() and finally ask for necessary parameter via Config::get()

2 Usage of class Config

You can create it everywhere you wish. You can give an xml-file name/path either in c-tor or in Config::load() method. You can obtain any parameter in any place of your program by calling Config::get() method. Example of class Config's usage:

Config config( "full/path/to/settings.xml" );
connect( settingsAction, SIGNAL( trigger() ), &config, SLOT( show() ) );
... 
if ( config.get( "section_name", "param_name" ).toBool() ) {
    ...
}
QFile file( config.get( "section_name", "directory_for_log" ).toString() +
    "/prog.log" );

3 Restrictions

Config need QtCore, QtGui and QtXml. It uses C++11's features.

4 Xml-file format

Sorry, but I'm too lazy to write full description, so I'll write a full example with all features. I think, that you'll understand them all :)

<?xml version="1.0" encoding="System"?>
<config>
    <section visible="true" display_name="First section name" name="common">
        <group visible="true" checkable="true" display_name="First group" checked="true" name="group1">
            <value visible="true" display_name="Ip address:port" type="text" value="192.168.2.1:1235" regexp="ip-addr:port" name="Ip"/>
            <value visible="true" display_name="Some bool value" type="bool" value="true" name="Some bool value"/>
            <value visible="true" display_name="Choose 1" type="combo" value="The two" items="The one;The two;Just three" name="Choose 1"/>
            <value visible="true" display_name="Picture or sound" type="file" value="../../to_so/gui_settings.zip" name="Picture or sound" relative="true" filters="Images (*.png *.jpg);;Sounds (*.mp3 *.wav)"/>
            <value visible="true" display_name="Choose 2" type="radio" value="First" items="First;Second;Third;Fourth" name="Choose 2"/>
            <value visible="true" display_name="Dir for log" type="dir" value="D:/" name="Dir for log"/>
            <value visible="true" display_name="Dir for log 2" type="dir" value="D:/" name="Dir for log 2" relative="true"/>
        </group>
        <group visible="true" checkable="false" display_name="Second group" checked="true" name="group2">
            <value unit=" cm" visible="true" display_name="Length" type="int" value="18" min="1" name="Length" max="33"/>
            <value unit=" kg" visible="true" display_name="Weight" type="int" value="42" min="0" name="Weight" max="100"/>
            <value unit=" MHz" precision="1" visible="true" display_name="Freq" type="double" value="100.6" min="100" step="0.1" name="Freq" max="200"/>
        </group>
        <value visible="true" display_name="Just bool" type="bool" value="false" name="Just bool"/>
        <group visible="true" checkable="false" checked="true" name="colors" display_name="Color scheme">
            <value visible="true" display_name="textColor" type="color" value="#ffffff" name="textColor"/>
            <value visible="true" display_name="outlineColor" type="color" value="#363636" name="outlineColor"/>
        </group>
    </section>
    <section visible="true" display_name="Second sect" name="Second sect">
        <value visible="true" display_name="Greet me" type="text" value="hellohello" regexp="(hello)+" name="Greet me"/>
        <value visible="false" display_name="Invisible bool" type="bool" value="true" name="Invisible bool"/>
    </section>
    <found_style>{ font: bold; color: blue; }</found_style>
</config>

and here is a usage of Config with this file

std::ostream & operator<< ( std::ostream & os, const QVariant & var ) {
    if ( var.type() == QVariant::Bool ) {
        os << var.toBool();
    }
    else if ( var.type() == QVariant::Int ) {
        os << var.toInt();
    }
    else if ( var.type() == QVariant::String ) {
        os << qPrintable( var.toString() );
    }
    return os;
}

cfg.beginSection( "common" );
cout << "First group checked : " << cfg.get( "group1" ) << endl;
cout << "Ip address:port : " << cfg.get( "First section name", "ip" ) << endl;
cout << "Some bool value : " << cfg.get( "Some bool value" ) << endl;
cout << "Choose 1 : " << cfg.get( "Choose 1" ) << endl;
cout << "Picture or sound : " << cfg.get( "Picture or sound" ) << endl;
cout << "Choose 2 : " << cfg.get( "Choose 2" ) << endl;
cout << "Dir for log : " << cfg.get( "Dir for log" ) << endl;
cout << "Length : " << cfg.get( "Length" ) << endl;
cout << "Weight : " << cfg.get( "First section name", "Weight" ) << endl;
cout << "Just bool : " << cfg.get( "First section name", "Just bool" ) << endl;
cfg.beginGroup( "Second sect" );
cout << "Greet me : " << cfg.get( "Greet me" ) << endl;
cout << "Invisible bool : " << cfg.get( "Invisible bool" ) << endl;

QColor textColor = cfg.get( "colors", "textColor" ).value< QColor >()
QColor outlineColor = cfg.get( "colors", "outlineColor" ).value< QColor >()

UPD: Added searching parameters by name from GUI

UPD2:

  1. There are to names now: 'display_name' for show on widget and to search and 'name' for querying from code
  2. Querying from code is easy now. You can start to read a section with beginSection( section name ); and then just query a value by get( value name );
  3. File nad Directory chooser can be relative

UPD3: Added type Color and Color Picker

UPD4: Added type Double with precicion and step. (step also added to int type)

Project Admins:


MongoDB Logo MongoDB