定义:

QSettings 类提供与平台无关的持久应用程序设置。

官方例子:

QSettings settings("MySoft", "Star Runner");settings.setValue("editor/wrapMargin", 68);int margin = settings.value("editor/wrapMargin").toInt();

1.构造函数

QSettings::QSettings(const QString &organization, const QString &application, QObject *parent): QObject(*QSettingsPrivate::create(NativeFormat, UserScope, organization, application),parent)
{
}QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope,const QString &organization, const QString &application)
{return new QConfFileSettingsPrivate(format, scope, organization, application);
}
QConfFileSettingsPrivate::QConfFileSettingsPrivate(QSettings::Format format,QSettings::Scope scope,const QString &organization,const QString &application): QSettingsPrivate(format, scope, organization, application),nextPosition(0x40000000) // big positive number
{initFormat();QString org = organization;if (org.isEmpty()) {setStatus(QSettings::AccessError);org = QLatin1String("Unknown Organization");}QString appFile = org + QDir::separator() + application + extension;QString orgFile = org + extension;if (scope == QSettings::UserScope) {Path userPath = getPath(format, QSettings::UserScope);if (!application.isEmpty())confFiles.append(QConfFile::fromName(userPath.path + appFile, true));confFiles.append(QConfFile::fromName(userPath.path + orgFile, true));}Path systemPath = getPath(format, QSettings::SystemScope);
#if defined(Q_XDG_PLATFORM) && !defined(QT_NO_STANDARDPATHS)// check if the systemPath wasn't overridden by QSettings::setPath()if (!systemPath.userDefined) {// Note: We can't use QStandardPaths::locateAll() as we need all the// possible files (not just the existing ones) and there is no way// to exclude user specific (XDG_CONFIG_HOME) directory from the search.QStringList dirs = QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation);// remove the QStandardLocation::writableLocation() (XDG_CONFIG_HOME)if (!dirs.isEmpty())dirs.takeFirst();QStringList paths;if (!application.isEmpty()) {paths.reserve(dirs.size() * 2);for (const auto &dir : qAsConst(dirs))paths.append(dir + QLatin1Char('/') + appFile);} else {paths.reserve(dirs.size());}for (const auto &dir : qAsConst(dirs))paths.append(dir + QLatin1Char('/') + orgFile);// Note: No check for existence of files is done intentionaly.for (const auto &path : qAsConst(paths))confFiles.append(QConfFile::fromName(path, false));} else
#endif // Q_XDG_PLATFORM && !QT_NO_STANDARDPATHS{if (!application.isEmpty())confFiles.append(QConfFile::fromName(systemPath.path + appFile, false));confFiles.append(QConfFile::fromName(systemPath.path + orgFile, false));}initAccess();
}

根据参数进行初始化操作,然后调用initAccess();

void QConfFileSettingsPrivate::initAccess()
{if (!confFiles.isEmpty()) {if (format > QSettings::IniFormat) {if (!readFunc)setStatus(QSettings::AccessError);}}sync();       // loads the files the first time
}void QConfFileSettingsPrivate::sync()
{// people probably won't be checking the status a whole lot, so in case of// error we just try to go on and make the best of itfor (auto confFile : qAsConst(confFiles)) {QMutexLocker locker(&confFile->mutex);syncConfFile(confFile);}
}void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile)
{bool readOnly = confFile->addedKeys.isEmpty() && confFile->removedKeys.isEmpty();/*We can often optimize the read-only case, if the file on diskhasn't changed.*/if (readOnly && confFile->size > 0) {QFileInfo fileInfo(confFile->name);if (confFile->size == fileInfo.size() && confFile->timeStamp == fileInfo.lastModified())return;}if (!readOnly && !confFile->isWritable()) {setStatus(QSettings::AccessError);return;}
#ifndef QT_BOOTSTRAPPED/*Use a lockfile in order to protect us against other QSettings instancestrying to write the same settings at the same time.We only need to lock if we are actually writing as only concurrent writes are a problem.Concurrent read and write are not a problem because the writing operation is atomic.*/QLockFile lockFile(confFile->name + QLatin1String(".lock"));if (!readOnly && !lockFile.lock() && atomicSyncOnly) {setStatus(QSettings::AccessError);return;}
#endif/*We hold the lock. Let's reread the file if it has changedsince last time we read it.*/QFileInfo fileInfo(confFile->name);bool mustReadFile = true;bool createFile = !fileInfo.exists();if (!readOnly)mustReadFile = (confFile->size != fileInfo.size()|| (confFile->size != 0 && confFile->timeStamp != fileInfo.lastModified()));if (mustReadFile) {confFile->unparsedIniSections.clear();confFile->originalKeys.clear();QFile file(confFile->name);if (!createFile && !file.open(QFile::ReadOnly)) {setStatus(QSettings::AccessError);return;}/*Files that we can't read (because of permissions orbecause they don't exist) are treated as empty files.*/if (file.isReadable() && file.size() != 0) {bool ok = false;
#ifdef Q_OS_MACif (format == QSettings::NativeFormat) {QByteArray data = file.readAll();ok = readPlistFile(data, &confFile->originalKeys);} else
#endifif (format <= QSettings::IniFormat) {QByteArray data = file.readAll();ok = readIniFile(data, &confFile->unparsedIniSections);} else if (readFunc) {QSettings::SettingsMap tempNewKeys;ok = readFunc(file, tempNewKeys);if (ok) {QSettings::SettingsMap::const_iterator i = tempNewKeys.constBegin();while (i != tempNewKeys.constEnd()) {confFile->originalKeys.insert(QSettingsKey(i.key(), caseSensitivity),i.value());++i;}}}if (!ok)setStatus(QSettings::FormatError);}confFile->size = fileInfo.size();confFile->timeStamp = fileInfo.lastModified();}/*We also need to save the file. We still hold the file lock,so everything is under control.*/if (!readOnly) {bool ok = false;ensureAllSectionsParsed(confFile);ParsedSettingsMap mergedKeys = confFile->mergedKeyMap();
#if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(temporaryfile)QSaveFile sf(confFile->name);sf.setDirectWriteFallback(!atomicSyncOnly);
#elseQFile sf(confFile->name);
#endifif (!sf.open(QIODevice::WriteOnly)) {setStatus(QSettings::AccessError);return;}
#ifdef Q_OS_MACif (format == QSettings::NativeFormat) {ok = writePlistFile(sf, mergedKeys);} else
#endifif (format <= QSettings::IniFormat) {ok = writeIniFile(sf, mergedKeys);} else if (writeFunc) {QSettings::SettingsMap tempOriginalKeys;ParsedSettingsMap::const_iterator i = mergedKeys.constBegin();while (i != mergedKeys.constEnd()) {tempOriginalKeys.insert(i.key(), i.value());++i;}ok = writeFunc(sf, tempOriginalKeys);}
#if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(temporaryfile)if (ok)ok = sf.commit();
#endifif (ok) {confFile->unparsedIniSections.clear();confFile->originalKeys = mergedKeys;confFile->addedKeys.clear();confFile->removedKeys.clear();QFileInfo fileInfo(confFile->name);confFile->size = fileInfo.size();confFile->timeStamp = fileInfo.lastModified();// If we have created the file, apply the file permsif (createFile) {QFile::Permissions perms = fileInfo.permissions() | QFile::ReadOwner | QFile::WriteOwner;if (!confFile->userPerms)perms |= QFile::ReadGroup | QFile::ReadOther;QFile(confFile->name).setPermissions(perms);}
#ifdef Q_OS_WASMEM_ASM(// Sync sandbox filesystem to persistent database filesystem. See QTBUG-70002FS.syncfs(false, function(err) {}););
#endif} else {setStatus(QSettings::AccessError);}}
}

先锁住文件,如果文件格式是ini, 调用readIniFile()函数读取文件。

2.setValue()

void QSettings::setValue(const QString &key, const QVariant &value)
{Q_D(QSettings);if (key.isEmpty()) {qWarning("QSettings::setValue: Empty key passed");return;}QString k = d->actualKey(key);d->set(k, value);d->requestUpdate();
}void QConfFileSettingsPrivate::set(const QString &key, const QVariant &value)
{if (confFiles.isEmpty())return;// Note: First config file is always the most specific.QConfFile *confFile = confFiles.at(0);QSettingsKey theKey(key, caseSensitivity, nextPosition++);QMutexLocker locker(&confFile->mutex);confFile->removedKeys.remove(theKey);confFile->addedKeys.insert(theKey, value);
}

先删除原有的项,然后添加新项。

3.value()

QVariant QSettings::value(const QString &key, const QVariant &defaultValue) const
{Q_D(const QSettings);if (key.isEmpty()) {qWarning("QSettings::value: Empty key passed");return QVariant();}QVariant result = defaultValue;QString k = d->actualKey(key);d->get(k, &result);return result;
}
bool QConfFileSettingsPrivate::get(const QString &key, QVariant *value) const
{QSettingsKey theKey(key, caseSensitivity);ParsedSettingsMap::const_iterator j;bool found = false;for (auto confFile : qAsConst(confFiles)) {QMutexLocker locker(&confFile->mutex);if (!confFile->addedKeys.isEmpty()) {j = confFile->addedKeys.constFind(theKey);found = (j != confFile->addedKeys.constEnd());}if (!found) {ensureSectionParsed(confFile, theKey);j = confFile->originalKeys.constFind(theKey);found = (j != confFile->originalKeys.constEnd()&& !confFile->removedKeys.contains(theKey));}if (found && value)*value = *j;if (found)return true;if (!fallbacks)break;}return false;
}

代码写的很清楚了。

Qt源码分析--QSettings相关推荐

  1. Qt源码分析之QObject

    Qt的QObject 1.试验代码: #include <QApplication> #include <QtCore> #include <QtGui> int ...

  2. Qt源码分析之信号和槽机制

    Qt的信号和槽机制是Qt的一大特点,实际上这是和MFC中的消息映射机制相似的东西,要完成的事情也差不多,就是发送一个消息然后让其它窗口响应,当然,这里的消息是广义的 说法,简单点说就是如何在一个类的一 ...

  3. Qt源码分析--QImage(1)

    QImage 类提供独立于硬件的图像表示 (允许直接访问像素数据,且可以用作描绘设备). QImage 是为 I/O 和直接像素访问和操作而设计和优化的. 因为 QImage 是 QPaintDevi ...

  4. Qt源码分析--QImage(8)

    1.void setDotsPerMeterX(int); 设置每米有多少个像素 /*!Sets the number of pixels that fit horizontally in a phy ...

  5. 【Qt】Log4Qt(三)源码分析

    Log4Qt(三)源码分析 1.分层架构 1.1 核心对象 1.2 支持对象 2.源码分析 2.1 宏 2.1.1 LOG4QT_DECLARE_QCLASS_LOGGER 2.1.2 LOG4QT_ ...

  6. Qt 事件机制源码分析 QApplication exec 源码分析 多图超级详细

    前言: 不熟悉qt 源码结构的 可以先看这一篇 点我点我点我 写qt 的都知道 以下代码, 这段代码究竟的运行机制是怎么样的 咱们一步一步的看 QApplication a(argc, argv);Q ...

  7. Solr初始化源码分析-Solr初始化与启动

    用solr做项目已经有一年有余,但都是使用层面,只是利用solr现有机制,修改参数,然后监控调优,从没有对solr进行源码级别的研究.但是,最近手头的一个项目,让我感觉必须把solrn内部原理和扩展机 ...

  8. 14.QueuedConnection和BlockingQueuedConnection连接方式源码分析

    QT信号槽直连时的时序和信号槽的连接方式已经在前面的文章中分析过了,见https://blog.csdn.net/Master_Cui/article/details/109011425和https: ...

  9. sigslot库源码分析

    言归正传,sigslot是一个用标准C++语法实现的信号与槽机制的函数库,类型和线程安全.提到信号与槽机制,恐怕最容易想到的就是大名鼎鼎的Qt所支持的对象之间通信的模式吧.不过这里的信号与槽虽然在概念 ...

最新文章

  1. SAP 解决长时间不操作掉线问题
  2. T-SQL Recipes之Customized Database Objects
  3. python2 unicode编码_如何优雅解决python2.x的unicode编码优雅输出?
  4. PyCharm配置QTDesigner和ui2py工具
  5. CentOS 7安装mysql
  6. 远程580解锁bl工具_一年让你多挣4万的工具丨又增VIVO新款保资料解锁!
  7. 使用WinSCP上传下载IPAD的文件
  8. 课后习题讲解(免费)高数下册
  9. HTML | 分享几个HTML邮件样式模板
  10. 《黑客帝国》说的是什么?
  11. Redirected Walking
  12. miui11升级鸿蒙,这就是MIUI 11的升级机型名单?还挺给力!
  13. 移动端自动轮播可滑动轮播图
  14. 码农+码农=码农 ?
  15. 人工智能-OpenCV+Python实现人脸识别(视频人脸检测)
  16. Linux 性能分析工具汇总
  17. 新探索:包含坐标信息的tif格式文件直接覆盖到地图上
  18. 什么是swift闭包?
  19. vue3+ts 使用 vue-seamless-scroll
  20. 2.1.太极平台框架—表单介绍与使用

热门文章

  1. 苹果官网php,苹果官方购买产品服务器端验证代码PHP版
  2. 机器学习-9.逻辑回归
  3. phoenix安装及使用详细步骤
  4. Eclipse版本号的区别
  5. 描述 Web 服务:WSDL
  6. 使用Insignia SSPS做手机配置管理
  7. 安装Ubuntu后必须要做的几件事(一)
  8. URAL 1982. Electrification Plan(并查集)
  9. 江苏省计算机三级网络题库,计算机三级网络上机题库
  10. TP Non-static method app\index\controller\Class::method () should not be called statically