目錄
1.引言
2.QSettings
2.1.功能特點
2.2.基本用法
3.讀取ini文件配置通用類設計
3.1.設計要點
3.2.完整實現
3.3.調用方法
4.總結
1.引言
? ? ? ? 在編寫應用程序的時,有些參數需要用戶配置,那么這些參數就涉及到存儲了,單從存儲來講,就有很多實現的方案,比如ini格式文件保存、xml格式文件保存、json格式文件保存,數據庫保存等,其中ini格式文件保存比較簡單,也是平時項目用的比較多的一種,下面就詳細講講Qt中讀取ini格式配置文件的方法和通用類設計。
2.QSettings
????????QSettings 是 Qt 框架中用于讀取和寫入應用程序配置信息的類。它提供了一個跨平臺的解決方案,可輕松地保存和獲取應用程序的設置和狀態。
2.1.功能特點
1)跨平臺支持:QSettings能夠自動適配不同的操作系統,確保配置數據能在不同平臺間無縫遷移。無論是Windows的注冊表、macOS的plist文件,還是INI文件或JSON格式的文件,QSettings都能輕松處理。
2)鍵值對存儲:使用鍵值對的方式來存儲和讀取應用程序的設置信息,使得配置數據的管理變得簡單直觀。
3)多種存儲格式:支持多種存儲格式,包括NativeFormat(使用操作系統推薦的存儲方式)、IniFormat(將數據保存為INI格式的文本文件)和CustomFormat(允許指定自定義的存儲格式,但需配合自定義的QSettings backend實現)。
4)默認值支持:在讀取設置值時,如果找不到指定的鍵,QSettings可以返回預設的默認值。
5)輔助方法:提供了一些輔助方法來處理組織和應用程序范圍的設置,以及檢查設置是否存在、刪除設置項等功能。
2.2.基本用法
創建QSettings對象
在使用 QSettings 之前,首先需要創建一個 QSettings 對象。可以通過以下兩種方式進行初始化:
使用應用程序的組織名稱和應用程序名稱進行初始化:
QSettings settings("組織名稱", "應用程序名稱");
使用配置文件路徑進行初始化:
QSettings settings("ConfigFile/config.ini", QSettings::IniFormat);
注意:如果沒有指定配置文件路徑,QSettings 將使用平臺特定的位置存儲配置信息。
存儲設置值
使用 setValue() 函數可以將鍵值對存儲到配置文件中:
settings.setValue("key", "value");
讀取設置值:
使用 value() 函數可以讀取配置文件中的鍵對應的值:
QVariant value = settings.value("鍵");
// 如果需要特定類型的值,可以使用如下方式:
QString stringValue = settings.value("鍵").toString();
int intValue = settings.value("鍵").toInt();
如果要指定默認值,可以在讀取時提供:
QString username = settings.value("username", "DefaultUser").toString();
設置系統編碼
當ini文件的內容中可能有中文,如果不設置編碼,就可能出現亂碼。
QSettings iniRead(file, QSettings::IniFormat);
iniRead.setIniCodec("utf-8"); //解決中文亂碼的情況
檢查設置是否存在:
bool exists = settings.contains("鍵");
刪除設置項:
使用 remove() 函數可以刪除配置文件中的指定鍵:
settings.remove("key");
持久化設置:
在多線程環境中,如果需要確保數據立即寫入持久存儲,可以使用sync()
方法:
settings.setValue("Setting1", "Value1");
settings.sync(); // 強制立即寫入
訪問子組:
settings.beginGroup("Window");
settings.setValue("Width", 800);
settings.endGroup(); // 可選,用于提高代碼可讀性
綜合示例:
以下是一個使用QSettings保存和恢復窗口位置、大小等設置的示例:
#include <QApplication>
#include <QMainWindow>
#include <QSettings> int main(int argc, char *argv[]) { QApplication app(argc, argv); QMainWindow window; window.setWindowTitle("QSettings Example"); // Load settings QSettings settings("YourCompany", "YourApp"); window.resize(settings.value("WindowSize", QSize(640, 480)).toSize()); window.move(settings.value("WindowPosition", QPoint(100, 100)).toPoint()); // Connect signals to save settings when necessary QObject::connect(&window, &QMainWindow::windowStateChanged, [&settings](Qt::WindowState state) { if (state == Qt::WindowMaximized) settings.setValue("WindowState", "maximized"); else settings.setValue("WindowState", "normal"); }); QObject::connect(&window, &QMainWindow::moveEvent, [&](QMoveEvent *event) { settings.setValue("WindowPosition", event->pos()); }); QObject::connect(&window, &QMainWindow::resizeEvent, [&](QResizeEvent *event) { settings.setValue("WindowSize", event->size()); }); window.show(); return app.exec();
}
在這個示例中,我們創建了一個QSettings實例,并在窗口初始化時從其中加載先前保存的尺寸和位置。同時,連接了窗口狀態變化、移動和調整大小的信號,以便在這些事件發生時自動更新存儲的設置。
3.讀取ini文件配置通用類設計
3.1.設計要點
1)應用程序用ini保存系統的配置,一般來說整個程序就一份,可以用單實例模式來實現整個類:
設計模式之單例模式-CSDN博客
class CShortWaveConfig
{
protected:CShortWaveConfig();~CShortWaveConfig();...public:static CShortWaveConfig& instance();....
};
2)普通的編程思路是一行一行得讀取ini文件,然后分別保存到變量中,這樣做不具有批量操性;轉變一下思路,可以一次性把整個文件讀取出來,保存到QMap中,關鍵代碼如下:
class CShortWaveConfig
{
protected:bool loadConfig();。。。
private:QMap<QString, QVariant> m_value;
};bool CShortWaveConfig::loadConfig()
{。。。QStringList allKeys = iniRead.allKeys();for (auto& it : allKeys) {m_value[it] = iniRead.value(it);}return true;
}
3)元素的訪問,每個元素的類型不知道,可利用C++中的模板把元素的類型T傳入,判斷是否可以從QVariant中的類型轉換成T,關鍵代碼如下:
template<typename T>
T value(const QString& key) {auto item = m_value.find(key);if (item != m_value.end()) {const QVariant& value1 = item.value();if (value1.canConvert<T>()) {return value1.value<T>();}assert(false);}。。。
}
4)元素的訪問時,如果傳入的路徑找不到元素,可以返回默認參數,關鍵代碼如下:
template<typename T>
T value(const QString& key, const T& defalutValue) {auto item = m_value.find(key);if (item != m_value.end()) {。。。}return defalutValue;
}
3.2.完整實現
ShortWaveConfig.h
#ifndef _SHORT_WAVE_CONFIG_H_
#define _SHORT_WAVE_CONFIG_H_
#include <QString>
#include <QMap>
#include <QVariant>
#include <assert.h>
using namespace std;class CShortWaveConfig
{
protected:CShortWaveConfig();~CShortWaveConfig();bool loadConfig();public:static CShortWaveConfig& instance();template<typename T>T value(const QString& key, const T& defalutValue) {auto item = m_value.find(key);if (item != m_value.end()) {const QVariant& value1 = item.value();if (value1.canConvert<T>()) {return value1.value<T>();}assert(false);}return defalutValue;}private:QMap<QString, QVariant> m_value;
};#endif
ShortWaveConfig.cpp
#include "ShortWaveConfig.h"
#include <QFile>
#include <QApplication>
#include <QSettings>CShortWaveConfig::CShortWaveConfig()
{bool result = loadConfig();assert(result);
}CShortWaveConfig::~CShortWaveConfig()
{}bool CShortWaveConfig::loadConfig()
{QString file = QCoreApplication::applicationDirPath() + "/systemConfig.ini";if (!QFile::exists(file)) {return false;}QSettings iniRead(file, QSettings::IniFormat);iniRead.setIniCodec("utf-8"); //解決中文亂碼的情況QStringList allKeys = iniRead.allKeys();for (auto& it : allKeys) {m_value[it] = iniRead.value(it);}return true;
}CShortWaveConfig& CShortWaveConfig::instance()
{static CShortWaveConfig config;return config;
}
3.3.調用方法
//姓名
QString name = CShortWaveConfig::instance().value<QString>("Attr/name", "xiaoming");//年齡
int age = CShortWaveConfig::instance().value<int>("Attr/age", 20);
4.總結
????????本文詳細介紹了 Qt 中的 QSettings 類,包括初始化、讀取、寫入和刪除配置信息的操作。還講解了在整個系統中怎么去設計系統配置文件讀取類CShortWaveConfig。通過合理使用類CShortWaveConfig,您可以輕松管理和存儲應用程序的配置信息,提高應用程序的靈活性和可維護性。