QSetting详解

2014年3月18日 由 Creater 留言 »

QSetting是一个平台无关的可以设置和读取应用程序设置的类,用户可能希望应用程序记住自己应用程序的设置,windows记录在注册表中,mac中记录在xml中,在unix中,缺乏标准,所以很多都记录在.ini文本文件中,QSetting的API都是基于QVariant的,允许保存很多类型的数据,例如QString,QRect,和QImage。

基本用法:

当创建一个QSetting对象时候,应该把公司或组织,还有应用程序的名字传递给构造函数,例如,如果应用程序叫做Star Runner,公司叫做MySoft,那么应该像下面这样构造对象

QSetting settings(“MySoft”,”Star Runner”);

QSetting的对象可以再堆或者栈上创建,构造和析构都非常快,如果在应用程序你在很多地方用QSetting,可以使用QCoreApplication::setOrganizationName()和QCoreApplication::setApplicationName()设置组织名和应用程序,然后使用QSetting的默认构造函数。

QCoreApplication::setOrganizationName("MySoft");

QCoreApplication::setOrganizationDomain("unix8.net");

 QCoreApplication::setApplicationName("softname");

     //...

QSettings settings;

这里我们也指定了组织的网络域名,使用QCoreApplication::setOrganizationDomain()。

QSetting由和值组成,使用QString指定键key的名字,使用QVariant来存储和key相关联的值,设定key,使用setValue(),例如

Setting.setValue(“editor/warpMargin”,68);

如果已经存在了同名的key,那么新的值会覆盖原来的值,获取setting的值使用value()函数

int margin=setting.value(“editor/warpMargin”).toInt();

如果没有指定的key,那么value()会返回一个Null QVariant,也可以为value()指定一个缺省的值,如下面

int margin=setting.value(“editor/warpMargin,80).toInt();

缺省值就是80,value()返回的值是一个QVariant,把他转换成int类型。

QVariant和GUI类型

因为QVariant是QtCore库的一部分,不能提供一个方便的函数转换成QColor,QImage和QPixmap,因为这些是QtGui的一部分,换句话说,没有toColor(),toImage(),toPixmap()等方法,但是我们可以使用qVariantValue()模板函数或者QVariant::value<templateT>来转换,他们是等价的,例如

QSettings settings("MySoft", "Star Runner");
QColor color = settings.value("DataPump/bgcolor").value<QColor>();

相反的转换过程是QVariant自动支持的,包括GUI相关类型,例如

QSettings settings("MySoft", "Star Runner");
QColor color = palette().background().color();
settings.setValue("DataPump/bgcolor", color);

QSetting语法

无论windows还是unix,使用“/”作为分隔符,而不是“\”,如果在一个地方指定了“text fonts”,就不要再其他地方指定“Text Fonts”,例如

     settings.setValue("mainwindow/size", win->size());
     settings.setValue("mainwindow/fullScreen", win->isFullScreen());
     settings.setValue("outputpanel/visible", panel->isVisible());

如果想设置子目录,也可以使用beginGroup()和endGroup()配合使用,如下

   settings.beginGroup("mainwindow");
     settings.setValue("size", win->size());
     settings.setValue("fullScreen", win->isFullScreen());
     settings.endGroup();

     settings.beginGroup("outputpanel");
     settings.setValue("visible", panel->isVisible());
     settings.endGroup();

效果和上面的一样,除了group之外,QSetting也支持array概念,详见beginReadArray()和beginWriteArray。如果有很多东西需要记录在setting中,可以使用arrays更简单一些,例如,你想保存一个变长的list,list中保存用户的name和password,可以用下面的代码

struct Login {
     QString userName;
     QString password;
 };
 QList<Login> logins;
 ...

 QSettings settings;
 settings.beginWriteArray("logins");
 for (int i = 0; i < logins.size(); ++i) {
     settings.setArrayIndex(i);
     settings.setValue("userName", list.at(i).userName);
     settings.setValue("password", list.at(i).password);
 }
 settings.endArray();

得到的键如下

  • logins/size
  • logins/1/userName
  • logins/1/password
  • logins/2/userName
  • logins/2/password
  • logins/3/userName
  • logins/3/password

其中size是自动侦测到的长度,要想把他们读取出来,可以使用如下的方法

struct Login {
     QString userName;
     QString password;
 };
 QList<Login> logins;
 ...

 QSettings settings;
 int size = settings.beginReadArray("logins");
 for (int i = 0; i < size; ++i) {
     settings.setArrayIndex(i);
     Login login;
     login.userName = settings.value("userName").toString();
     login.password = settings.value("password").toString();
     logins.append(login);
 }
 settings.endArray();

例子,  保存GUI应用程序的状态,在关闭应用程序时候保存应用程序窗口的大小和位置,在再次打开应用程序时候,读取出来

void MainWindow::writeSettings()
 {
     QSettings settings("Moose Soft", "Clipper");

     settings.beginGroup("MainWindow");
     settings.setValue("size", size());
     settings.setValue("pos", pos());
     settings.endGroup();
 }

 void MainWindow::readSettings()
 {
     QSettings settings("Moose Soft", "Clipper");

     settings.beginGroup("MainWindow");
     resize(settings.value("size", QSize(400, 400)).toSize());
     move(settings.value("pos", QPoint(200, 200)).toPoint());
     settings.endGroup();
 }

使用QWidget::resize()和QWidget::move()比QWidget::setGeometry()要更好,在构造函数中调用readSetting(),在关闭窗口事件中调用writeSettings()。

MainWindow::MainWindow()
 {
     ...
     readSettings();
 }

 void MainWindow::closeEvent(QCloseEvent *event)
 {
     if (userReallyWantsToQuit()) {
         writeSettings();
         event->accept();
     } else {
         event->ignore();
     }
 }

 

广告位

评论已关闭.