一、代码之路
日常中,我们会使用QSettings来读取配置文件中的数据信息或者是注册表中的键值对信息,如下方代码:
QString strFilePath = "D:/my.ini";
QSettings sysSettings(strFilePath, QSettings::IniFormat);
sysSettings.setIniCodec("UTF-8");
sysSettings.beginGroup("MyInfo");
strHost = sysSettings.value("Name").toString();
strPort = sysSettings.value("Age").toString();
sysSettings.endGroup();
但是如果我们只是QSettings对象来存储数据,如下方代码中getMyInfo方法将自己的数据信息存储在QSettings对象中,但是我们发现在test方法中我们使用qDebug打印出来的名字和年龄都是空值。
Name: “” Age: 0
QSettings* getMyInfo(QString name, int age)
{QSettings* settings = new QSettings();settings->setValue("Name", name);settings->setValue("Age", age);return settings;
}void testSettings()
{QSettings* mySettings = getMyInfo("小明", 18);QString name = mySettings->value("Name").toString();int age = mySettings->value("Age").toInt();qDebug() << "Name:" << name << " Age:" << age;
}
那么原因出在哪里呢?
简单看下Qt助手中这段解释说明:
QSettings objects can be created either on the stack or on the heap (i.e. using new). Constructing and destroying a QSettings object is very fast.
If you use QSettings from many places in your application, you might want to specify the organization name and the application name using QCoreApplication::setOrganizationName() and QCoreApplication::setApplicationName(), and then use the default QSettings constructor:
QCoreApplication::setOrganizationName("MySoft");
QCoreApplication::setOrganizationDomain("mysoft.com");
QCoreApplication::setApplicationName("Star Runner");
...
QSettings settings;
如果我们需要使用QSettings的默认构造函数,需要调用下面的代码,设置全局的OrganizationName:
QCoreApplication::setOrganizationName("MySoft");
QSettings* settings = new QSettings("MySoft");
注意点:
如果没有全局设置OrganizationName,我们可以在QSettings构造方法中传入OrganizationName,下面代码中我们稍加修改,在getMyInfo方法中我们直接在栈上创建QSettings对象(即局部变量,会在函数结束后销毁),然后我们在testSettings方法中直接在QSettings对象中传入相同的OrganizationName,然后依旧可以输出我们传入的值,说明可以直接通过指定OrganizationName来创建一个全局的QSettings数据对象。
void getMyInfo(QString name, int age)
{QSettings settings("MySoft");settings.setValue("Name", name);settings.setValue("Age", age);
}void testSettings()
{// 这里直接调用;getMyInfo("小明", 18);// 这里也是在构造中指定getMyInfo方法中同样的OrganizationName;QSettings mySettings("MySoft");QString name = mySettings.value("Name").toString();int age = mySettings.value("Age").toInt();qDebug() << "Name:" << name << " Age:" << age;
}
那我们是不是可以通过指定不同的OrganizationName,来创建多个全局的QSettings数据对象呢,来看下方测试代码:
void testSettings()
{// 测试数据{QSettings settings("MySoft1");settings.setValue("Name", "小明");settings.setValue("Age", 18);QSettings settings1("MySoft2");settings1.setValue("Name", "小李");settings1.setValue("Age", 20); }{QSettings mySettings1("MySoft1");QString name = mySettings1.value("Name").toString();int age = mySettings1.value("Age").toInt();qDebug() << "Name:" << name << " Age:" << age;}{QSettings mySettings2("MySoft2");QString name = mySettings2.value("Name").toString();int age = mySettings2.value("Age").toInt();qDebug() << "Name:" << name << " Age:" << age;}
}
输出结果:
Name: “小明” Age: 18
Name: “小李” Age: 20
通过测试,证明了我们的猜想。
其实这里除了OrganizationName之外,还有另外一个参数ApplicationName可以设置,请看下方测试代码:
void testSettings()
{{QSettings settings("MySoft", "Test1");settings.setValue("Name", "小明");settings.setValue("Age", 18);QSettings settings1("MySoft", "Test2");settings1.setValue("Name", "小李");settings1.setValue("Age", 20);}{QSettings mySettings1("MySoft", "Test1");QString name = mySettings1.value("Name").toString();int age = mySettings1.value("Age").toInt();qDebug() << "Name:" << name << " Age:" << age;}{QSettings mySettings2("MySoft", "Test2");QString name = mySettings2.value("Name").toString();int age = mySettings2.value("Age").toInt();qDebug() << "Name:" << name << " Age:" << age;}{// 这里特意增加了ApplicationName为Test3,实际未设置过ApplicationName为Test3QSettings mySettings3("MySoft", "Test3");QString name = mySettings3.value("Name").toString();int age = mySettings3.value("Age").toInt();qDebug() << "Name:" << name << " Age:" << age;}
}
实际输出:
Name: “小明” Age: 18
Name: “小李” Age: 20
Name: “小明” Age: 18
从测试结果中看到,可以通过OrganizationName和ApplicationName组合进行使用,获取到不同的QSettings配置信息;
同时我特意增加了一组QSettings mySettings3(“MySoft”, “Test3”);测试数据,这里并未设置ApplicationName为Test3对应的数据,这里可以从源码中来寻找更加准确的答案,这里我们通过测试数据来得出的信息,源码的逻辑才是更加正确的。