在我的应用程序中访问 QSettings

Posted

技术标签:

【中文标题】在我的应用程序中访问 QSettings【英文标题】:Access QSettings in my app 【发布时间】:2017-10-31 09:03:28 【问题描述】:

我正在尝试为我的 Qt 应用程序实现应用程序设置。 我正在使用QSettings,像这样创建了我的类的一个实例

settings = new QSettings(qApp->organizationName(), qApp->applicationName());

并且想知道:通过我的应用访问我的设置的最佳方式是什么

我需要访问来自不同类的一些设置,但我不知道我是否必须声明和创建一个 QSettings 实例并使其在我需要的任何地方都可以访问,或者我是否可以创建 @987654323 的本地实例@ 我需要访问一些设置的地方。

【问题讨论】:

【参考方案1】:

没有必要使用单音,正如 Qt 的文档所说,QSettings:

如果您在应用程序的许多地方使用 QSettings,您可能希望使用 QCoreApplication::setOrganizationName() 和 QCoreApplication::setApplicationName() 指定组织名称和应用程序名称,然后使用默认的 QSettings 构造函数:

那么,在创建QApplication之后:

QApplication app(argc, argv);

设置,不同的默认参数:

QCoreApplication::setOrganizationName("MySoft");
QCoreApplication::setOrganizationDomain("mysoft.com");
QCoreApplication::setApplicationName("Star Runner");

当你想使用 QSettingsm 时,只需使用默认构造函数,它将从核心应用程序中获取默认参数:

QSettings settings;
settings.setValue("example", 68);

在QML下,替代方案是Settings,setps是一样的,配置你的gui应用:

QGuiApplication app(argc, argv);
app.setOrganizationName("Some Company");
app.setOrganizationDomain("somecompany.com");
app.setApplicationName("Amazing Application");

在 QML 中,设置不同的设置:

Settings 
   property alias x: window.x
   property alias y: window.y
   property alias width: window.width
   property alias height: window.height

【讨论】:

所以只要我使用指定组织名称和应用程序的构造函数创建本地实例就可以了吗? @nmud 一旦设置了 QCoreApplication(通常在你的 main 函数中),那么你只需要在需要设置的地方使用 QSettings 的无参数构造函数。 问题是如果 qsettings 使用自定义格式【参考方案2】:

在我看来,最好的方法是实现单例设计模式来分配 QSettings 对象,但请记住,如果您共享 QSettings,您必须处理原子持久性,我的意思是,您有时需要使用sync() 方法,以便在 C++ 类中保留一些数据。我了解您不需要在 QML 层中使用设置。如果是这种情况,您可以查看 qmlRegisterSingletonType 方法以便在 QML 中使用它。

【讨论】:

但是,如果我在主窗口的构造函数中创建 QSettings 的唯一实例,是否需要单例设计?我只需要在下次启动应用程序时考虑偏好,所以我可能也不需要调用 sync() 吗? @jgd 是的,这是使用单例类 +1 访问全局设置的最佳选择 @nmud sync() 在持久化之后被调用。您需要写入还是只读取设置? @jgd 我需要在我的代码中从一个位置写入设置并从多个位置读取设置 @nmud 很好,我的建议是在你写的时候使用 sync(),尽管 QSettings 有缓存的内存可供使用,所以当你在一个位置阅读时,设置将是一致的,但如果你的应用程序崩溃在执行过程中,下一次执行可能不一致。另外,正如我所说,对这个对象使用单例设计。【参考方案3】:

为了在您的整个应用程序中使用全局设置 singleton 可能是个好主意,我有一个设置类的模式,我在这里发布可能对您和其他人有用。

这里我有 GlobalSettings 类,它是一个单例,下面是头文件和 cpp 文件。

头文件:

#ifndef GLOBALSETTINGS_H
#define GLOBALSETTINGS_H

#include <QSettings>
#include <QObject>

class GlobalSettings

public:
    Q_DISABLE_COPY(GlobalSettings)

    static GlobalSettings* getSettings();

    // Settings getter and setters

    QString Setting1() const;
    void setSetting1(const QString &Setting1);

    QString Setting2() const;
    void setSetting2(const QString &Setting2);

private:

    // private constructor
    GlobalSettings();
    static GlobalSettings * m_Settings;

    QSettings * settings;

    // Settings memebers
    QString m_Setting1;
    QString m_Setting2;

;

#endif // GLOBALSETTINGS_H

以及 GlobalSettings 的 cpp 文件

#include "globalsettings.h"

#include <QCoreApplication>

GlobalSettings * GlobalSettings::m_Settings = NULL;

GlobalSettings::GlobalSettings()

    settings = new QSettings(qApp->organizationName(), qApp->applicationName());
    if (!settings->contains("Setting1"))
    
        settings->setValue("Setting1","Something"); //  default value
    
    else
    
        m_Setting1 = settings->value("Setting1").toString();
    

    if (!settings->contains("Setting2"))
    
        settings->setValue("Setting2","Something"); //  default value
    
    else
    
        m_Setting2 = settings->value("Setting2").toString();
    
    settings->sync();


GlobalSettings *GlobalSettings::getSettings()

    if (m_Settings == NULL)
    
        m_Settings =  new GlobalSettings();
    
    return m_Settings;


QString GlobalSettings::Setting1() const

    return m_Setting1;


void GlobalSettings::setSetting1(const QString &Setting1)

    m_Setting1 = Setting1;
    settings->setValue("Setting1",Setting1);


QString GlobalSettings::Setting2() const

    return m_Setting2;


void GlobalSettings::setSetting2(const QString &Setting2)

    m_Setting2 = Setting2;
    settings->setValue("Setting2",Setting2);

这里是如何在任何你想使用的地方使用它

#include "mainwindow.h"
#include <QApplication>

#include <QDebug>

#include <globalsettings.h>

int main(int argc, char *argv[])

    QApplication a(argc, argv);

    GlobalSettings * setting = GlobalSettings::getSettings();

    qDebug() <<  setting->Setting1();


    MainWindow w;
    w.show();

    return a.exec();

现在如果你想拥有线程安全设置类,你可以在 get 和 setter 函数中锁定一个互斥锁

【讨论】:

为此必须有一个全局变量吗?我对全局变量不太满意,如果使用本地实例有效,我宁愿这样做。 会的。另外,不是 QSettings 线程安全吗?如果是这种情况,为什么我需要互斥锁?

以上是关于在我的应用程序中访问 QSettings的主要内容,如果未能解决你的问题,请参考以下文章

如何在现有的 QSettings 文件中添加组

在 Qt 中,如何使用 QSettings 来创建/修改/删除 Windows 注册表项/值?

如何在“QSettings”中保存/更改“QLineEdit”的文本并进行“QPushButton”调用

在跨平台环境中是不是有必要的安全方式在 QSettings 中存储数据?

QSettings 简单任务不起作用

QSettings & unicode