【Qt】QSettings讀寫注冊表、配置文件【轉】


簡述

一般情況下,我們在開發軟件過程中,都會緩存一些信息到本地,可以使用輕量級數據庫sqlite,也可以操作注冊表、讀寫配置文件。

關於QSettings的使用前面已經介紹過了,比較詳細,見“更多參考”,下面介紹下QSettings常用功能-讀寫注冊表、配置文件。

優點

無需指定注冊表路徑

一般情況下,我們需要定義一個宏,或者常量字符串來指定保存的注冊表位置。

  • #define HKEY_CURRENT_USER_QT "HKEY_CURRENT_USER\\SoftWare\\Digia\\Qt"
  • const QString HKEY_CURRENT_USER_QT = "HKEY_CURRENT_USER\\SoftWare\\Digia\\Qt";

無需指定配置文件路徑

一般情況下,我們需要定義一個宏,或者常量字符串來指定保存的配置文件位置及名稱。

  • #define INI_QT "C:\Users\WangLiang\AppData\Roaming\Digia"
  • const QString INI_QT = "C:\Users\WangLiang\AppData\Roaming\Digia";

采用下面方式,我們不需要做太多工作,Qt已經很好的替你實現了!

讀寫注冊表

一般存儲

下面我們以Qt為例,眾所周知現在Qt已經屬於Digia,也就是說:組織名為Digia,產品名為Qt。

在main()函數中,首先設置組織名、產品名。

QCoreApplication::setOrganizationName(QString("Digia"));
QCoreApplication::setApplicationName(QString("Qt"));

然后使用QSettings對注冊表進行操作:

QSettings settings(QSettings::NativeFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());

settings.setValue("Name", "Qt Creator");
settings.setValue("Version", 5);

這時,我們打開注冊表regedit,數據就生成了。

這里寫圖片描述

一般讀取

存儲完數據之后,默認的程序啟動時需要加載對應的數據。

QString strName = settings.value("Name").toString();
int nVersion = settings.value("Version").toInt();
//Name:Qt Creator Version:5

這時,我們可以通過查看應用程序輸出窗口得到輸出結果。

分目錄存儲

如果我們需要在同一路徑下建立多個子目錄該怎么辦,下面介紹兩種方式。

替換applicationName

如上,我們可以看出,organizationName對應的注冊表路徑為HKEY_CURRENT_USER\\SoftWare\\Digia,applicationName對應的為其下一級的目錄,那么分目錄就需要更改其對應的applicationName。

QSettings settings(QSettings::NativeFormat, QSettings::UserScope, QString("%1\\%2").arg(QCoreApplication::organizationName()).arg(QCoreApplication::applicationName()), "Qt5.5");

settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.5");

QSettings settings2(QString("%1\\%2").arg(QCoreApplication::organizationName()).arg(QCoreApplication::applicationName()), "Qt5.6");

settings2.setValue("Name", "Qt Creator");
settings2.setValue("Version", "5.6");

分組

替換applicationName的方式看起來有些繁瑣,相比之下,使用group分組則會更簡單!

QSettings settings;
settings.beginGroup("Qt5.5");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.5");
settings.endGroup();

settings.beginGroup("Qt5.6");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.6");
settings.endGroup();

這時,我們再次查看注冊表數據。

注:
新建目錄,則需要重新打開注冊表,如果新添加設置,則不需要重新打開注冊表,只需要來回切換對應的選項即可。

這里寫圖片描述

讀寫配置文件

一般存儲

如上,我們只需要將格式從NativeFormat變為IniFormat即可:

QSettings settings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());

settings.setValue("Name", "Qt Creator");
settings.setValue("Version", 5);

這時,我們打開對應的存儲目錄,數據就生成了。

我們可以進入文件夾:C:\Users\WangLiang\AppData\Roaming(AppData默認為隱藏文件,需要設置顯示才可查看),可以看到生成了文件夾”Digia”以及配置文件”Qt.ini”。

這里寫圖片描述

一般讀取

存儲完數據之后,默認的程序啟動時需要加載對應的數據。

QString strName = settings.value("Name").toString();
int nVersion = settings.value("Version").toInt();
//Name:Qt Creator Version:5

這時,我們可以通過查看應用程序輸出窗口得到輸出結果。

分組存儲

我們可以看到配置文件中包含默認的分組為:General。通常情況下,我們需要對配置進行歸類,例如:用戶名、密碼等信息屬於用戶組,產品名稱、版本號屬於設置組。

QSettings settings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());

settings.beginGroup("Setting");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", 5);
settings.endGroup();

settings.beginGroup("User");
settings.setValue("UserName", "WangL");
settings.setValue("Password", "123456");
settings.endGroup();

這時我們再次查看配置文件,里面已經生成了另外兩個分組。

這里寫圖片描述

分組讀取

settings.beginGroup("Setting");
QString strName = settings.value("Name").toString();
int nVersion = settings.value("Version").toInt();
settings.endGroup();
//Name:Qt Creator  Version:5

settings.beginGroup("User");
QString strUserName = settings.value("UserName").toString();
QString strPassword = settings.value("Password").toString();
settings.endGroup();
//UserName:WangL  Password:123456

分目錄存儲

什么時候需要分目錄存儲呢?QQ大家都用過吧,是不是每一個用戶都有一個對應QQ號的目錄呢,里面保存各個用戶對應的信息。

如上,我們可以看出,organizationName對應的本地路徑為C:\Users\WangLiang\AppData\Roaming\Digia,applicationName對應的為其下的配置文件,那么如果我們需要在同一路徑下建立多個目錄就需要更改對應的organizationName,配置文件名稱則需要更改其對應的applicationName了。

QSettings settings(QSettings::IniFormat, QSettings::UserScope, QString("%1\\%2\\%3").arg(QCoreApplication::organizationName()).arg(QCoreApplication::applicationName()).arg("Qt5.5"), "User");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.5");

QSettings settings2(QSettings::IniFormat, QSettings::UserScope, QString("%1\\%2\\%3").arg(QCoreApplication::organizationName()).arg(QCoreApplication::applicationName()).arg("Qt5.5"), "User");
settings2.setValue("Name", "Qt Creator");
settings2.setValue("Version", "5.6");

這時,我們再次查看本地文件,則會發現C:\Users\WangLiang\AppData\Roaming\Digia\Qt所在目錄下會生成兩個文件夾”Qt5.5”和”Qt5.6”,並且每一個目錄底下會生成對應的配置文件User.ini。

這里寫圖片描述

這里寫圖片描述

刪除內容

刪除一個指定的鍵

QSettings settings;
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", 5);

settings.remove("Name");

QStringList keys = settings.allKeys();
// keys: ["Version"]

清空所有鍵

settings.clear(); 
QStringList keys = settings.allKeys();
// keys: []

刪除設置鍵以及子設置鍵

QSettings settings;
settings.setValue("Qt5.6", "5.6");

settings.beginGroup("Qt5.5");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.5");
settings.endGroup();

settings.beginGroup("Qt5.6");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.6");
settings.endGroup();

settings.remove("Qt5.6");

QStringList strList = settings.allKeys();
// keys: ["Qt5.5/Name", "Qt5.5/Version"]

如果key為空字符串,在當前group()的所有鍵將被刪除。

QSettings settings;
settings.setValue("Qt5.6", "5.6");

settings.beginGroup("Qt5.5");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.5");
settings.endGroup();

settings.beginGroup("Qt5.6");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.6");
settings.endGroup();

settings.beginGroup("Qt5.6");
settings.remove("");
settings.endGroup();

QStringList keys = settings.allKeys();
// keys: ["Qt5.5/Name", "Qt5.5/Version"]

疑問解釋

如上文代碼,我們可以知道未刪除之前keys: ["Qt5.6", "Qt5.5/Name", "Qt5.5/Version", "Qt5.6/Name", "Qt5.6/Version"],其中Qt5.6所在分組為默認的General。

這里寫圖片描述

那么調用下面代碼:

settings.beginGroup("Qt5.6");
settings.remove("");
settings.endGroup();

應該只刪除對應組中的所有鍵才對,也就是說剩余的keys應該為 ["Qt5.6", "Qt5.5/Name", "Qt5.5/Version"],General下的鍵為什么會被刪除呢?好,這里先跳過,繼續。

General下的鍵既然可以被刪除,那么在Qt5.5分組下建立對應的Qt5.6鍵值,應該也會被刪除。

刪除前:

這里寫圖片描述

刪除后:

這里寫圖片描述

什么鬼,為嘛Qt5.5分組下的Qt5.6對應的鍵還在呢?

我們繼續分析:

刪除前:keys: ["Qt5.6", "Qt5.5/Qt5.6", "Qt5.5/Name", "Qt5.5/Version", "Qt5.6/Name", "Qt5.6/Version"]

助手中關於remove()的說明為:Removes the setting key and any sub-settings of key.

也就是說:Qt5.5/Qt5.6鍵中即使存在Qt5.6,但是所屬的setting key為Qt5.5而非Qt5.6,所以不會被刪掉。

既然這樣,那么我們的疑問也就不復存在了。

更多參考


原文作者:一去丶二三里
作者博客:去作者博客空間


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM