QSetting 类使用
QSetting是一個(gè)平臺(tái)無關(guān)的可以設(shè)置和讀取應(yīng)用程序設(shè)置的類
用戶可能希望應(yīng)用程序記住自己應(yīng)用程序的設(shè)置,windows記錄在注冊表中,mac中記錄在xml中,在unix中,缺乏標(biāo)準(zhǔn),所以很多都記錄在.ini文本文件中
QSetting的API都是基于QVariant的,允許保存很多類型的數(shù)據(jù),例如QString,QRect,和QImage
?
基本用法:
當(dāng)創(chuàng)建一個(gè)QSetting對象時(shí)候,應(yīng)該把公司或組織,還有應(yīng)用程序的名字傳遞給構(gòu)造函數(shù),例如,如果應(yīng)用程序叫做Star Runner,公司叫做MySoft,那么應(yīng)該像下面這樣構(gòu)造對象
QSetting settings(“MySoft”,”Star Runner”);
QSetting的對象可以再堆或者棧上創(chuàng)建,構(gòu)造和析構(gòu)都非常快
如果在應(yīng)用程序你在很多地方用QSetting,可以使用QCoreApplication::setOrganizationName()和QCoreApplication::setApplicationName()設(shè)置組織名和應(yīng)用程序,然后使用QSetting的默認(rèn)構(gòu)造函數(shù)
QCoreApplication::setOrganizationName("MySoft");
???? QCoreApplication::setOrganizationDomain("mysoft.com");
????QCoreApplication::setApplicationName("Star Runner");
???? ...
???? QSettings settings;
這里我們也指定了組織的網(wǎng)絡(luò)域名,使用QCoreApplication::setOrganizationDomain()
?
QSetting有鍵和值組成,使用QString指定鍵key的名字,使用QVariant來存儲(chǔ)和key相關(guān)聯(lián)的值,設(shè)定key,使用setValue(),例如
Setting.setValue(“editor/warpMargin”,68);
如果已經(jīng)存在了同名的key,那么新的值會(huì)覆蓋原來的值
獲取setting的值使用value()函數(shù)
Intmargin=setting.value(“editor/warpMargin”).toInt();
如果沒有指定的key,那么value()會(huì)返回一個(gè)Null QVariant,也可以為value()指定一個(gè)缺省的值,如下面
Intmargin=setting.value(“editor/warpMargin,80).toInt();
缺省值就是80,value()返回的值是一個(gè)QVariant,把他轉(zhuǎn)換成int類型
?
QVariant和GUI類型
因?yàn)镼Variant是QtCore庫的一部分,不能提供一個(gè)方便的函數(shù)轉(zhuǎn)換成QColor,QImage和QPixmap,因?yàn)檫@些是QtGui的一部分,換句話說,沒有toColor(),toImage(),toPixmap()等方法,但是我們可以使用qVariantValue()模板函數(shù)或者QVariant::value<templateT>來轉(zhuǎn)換,他們是等價(jià)的,例如
QSettings settings("MySoft", "Star Runner"); QColor color = settings.value("DataPump/bgcolor").value<QColor>();相反的轉(zhuǎn)換過程是QVariant自動(dòng)支持的,包括GUI相關(guān)類型,例如
QSettings settings("MySoft", "Star Runner"); QColor color = palette().background().color(); settings.setValue("DataPump/bgcolor", color);?
QSetting語法
無論windows還是unix,使用“/”作為分隔符,而不是“\”,如果在一個(gè)地方指定了“text fonts”,就不要再其他地方指定“Text Fonts”,例如
???? settings.setValue("mainwindow/size", win->size()); ???? settings.setValue("mainwindow/fullScreen", win->isFullScreen()); ???? settings.setValue("outputpanel/visible", panel->isVisible());如果想設(shè)置子目錄,也可以使用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更簡單一些,例如,你想保存一個(gè)變長的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是自動(dòng)偵測到的長度
要想把他們讀取出來,可以使用如下的方法
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應(yīng)用程序的狀態(tài)
在關(guān)閉應(yīng)用程序時(shí)候保存應(yīng)用程序窗口的大小和位置,在再次打開應(yīng)用程序時(shí)候,讀取出來
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()要更好
在構(gòu)造函數(shù)中調(diào)用readSetting(),在關(guān)閉窗口事件中調(diào)用writeSettings()
MainWindow::MainWindow() { ???? ... ???? readSettings(); } ? void MainWindow::closeEvent(QCloseEvent *event) { ???? if (userReallyWantsToQuit()) { ???????? writeSettings(); ???????? event->accept(); ???? } else { ???????? event->ignore(); ???? } }?
在多線程和多進(jìn)程中使用QSetting
QSetting是可重入的,意味著可以在不同的線程中使用不同的QSetting對象,這保證即便多個(gè)QSetting對象同時(shí)操作同一個(gè)文件或者磁盤,如果其中一個(gè)對象修改了文件或者注冊表,同一個(gè)進(jìn)程中其他操作同一個(gè)位置的QSetting對象能夠檢測到,并且不會(huì)讀取到臟數(shù)據(jù)。
在不同的進(jìn)程中使用QSetting來讀寫同一個(gè)setting文件是安全的,它使用文件鎖和智能合并算法來保證數(shù)據(jù)的完整,在sync()調(diào)用之前,這個(gè)進(jìn)程中的修改在另一個(gè)進(jìn)程中是不可見的, QSetting::sync()的作用是將那些未保存的修改永久寫進(jìn)存儲(chǔ)中,并且在其他進(jìn)程中重新載入這些修改的設(shè)置,這個(gè)函數(shù)被QSetting的析構(gòu)函數(shù)自動(dòng)調(diào)用,也被事件循環(huán)定期調(diào)用,一般情況下不需要手動(dòng)調(diào)用。
?
應(yīng)用程序settings保存的位置
這里使用MySoft作為組織名,使用Star Runner作為應(yīng)用程序名
在unix系統(tǒng)上,如果文件格式是NativeFormat,默認(rèn)使用下面的文件
1 、$HOME/.config/MySoft/StarRunner.conf (Qt for Embedded Linux: $HOME/Settings/MySoft/Star Runner.conf)
2、$HOME/.config/MySoft.conf(Qt for Embedded Linux: $HOME/Settings/MySoft.conf)
3、/etc/xdg/MySoft/StarRunner.conf
4、/etc/xdg/MySoft.conf
?
Mac os x上,默認(rèn)使用下面的文件
Windows上,NativeFormat設(shè)置被存儲(chǔ)在下面路徑的注冊表中
在windows上,32位程序運(yùn)行在WOW64模式下,setting被存儲(chǔ)在?HKEY_LOCAL_MACHINE\Software\WOW6432node.上
如果是使用IniFormat,存儲(chǔ)位置如下
Mac OS X上
Windows上
%APPDATA%通常是?C:\Documents and Settings\User Name\ApplicationData;
%COMMON_APPDATA%?通常是C:\Documents and Settings\All Users\Application Data
.ini和.conf文件的路徑可以使用setPath()來修改,在Mac OS X上,可以使用環(huán)境變量XDG_CONFIG_HOME
直接讀取INI和.plist文件
在所有平臺(tái)上,如果想直接讀取ini文件,可以在QSetting的構(gòu)造函數(shù)中,將ini文件的名和QSetting::IniFormat作為參數(shù),如下
QSettings settings("/home/petra/misc/myapp.ini", ??????????????????? QSettings::IniFormat);然后可以使用settings對象來讀寫這些設(shè)置
在Mac OS X上,讀取XML基礎(chǔ)文件.plist通過傳遞參數(shù)QSetting::NativaFormat作為第二個(gè)參數(shù),例如
QSettings settings("/Users/petra/misc/myapp.plist", ??????????????????? QSettings::NativeFormat);直接讀取Windows注冊表
通過傳遞給構(gòu)造函數(shù)第二個(gè)參數(shù)QSetting::NativaFormat,第一個(gè)參數(shù)是注冊表的鍵值位置,如下
QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Office", ??????????????????? QSettings::NativeFormat);指定的路徑下的所有注冊表入口都可以通過QSetting像平常一樣讀寫,例如
settings.setValue("11.0/Outlook/Security/DontTrustInstalledFiles", 0);在windows上,一個(gè)鍵可能有一個(gè)值和一個(gè)子鍵,他默認(rèn)的值可以通過“Dafault”和“.”獲取
settings.setValue("HKEY_CURRENT_USER\\MySoft\\Star Runner\\Galaxy", "Milkyway"); settings.setValue("HKEY_CURRENT_USER\\MySoft\\Star Runner\\Galaxy\\Sun", "OurStar"); settings.value("HKEY_CURRENT_USER\\MySoft\\Star Runner\\Galaxy\\Default"); // returns "Milkyway"在其他非windows平臺(tái)上,“Default”和“.”將會(huì)被當(dāng)做一般子鍵看待處理。
總結(jié)
以上是生活随笔為你收集整理的QSetting 类使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: webshell检测方式深度剖析 ---
- 下一篇: Vista优化大师更新历史: