首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >防止QSettings向QSettings设置的路径添加组织名称::setPath()

防止QSettings向QSettings设置的路径添加组织名称::setPath()
EN

Stack Overflow用户
提问于 2019-03-02 08:43:01
回答 1查看 681关注 0票数 1

是否有一种方法可以设置QSettings存储的实际默认路径(有或没有文件名),并防止QSettings向该路径追加组织名称之类的内容?这是因为要求QSettings的进一步使用保持不变,并且不了解设置存储路径。

考虑用例。在我的主目录中,我有以下代码:

代码语言:javascript
复制
QApplication a(argc, argv);

...

QCoreApplication::setApplicationName(APP_NAME);
QCoreApplication::setOrganizationDomain(MY_DOMAIN);
QCoreApplication::setOrganizationName(MY_ORGANIZATION);
QCoreApplication::setApplicationVersion(APP_VERSION);

...

a.exec();

在我的整个项目中,我都是这样使用QSettings的:

代码语言:javascript
复制
QSettings settings;

settings.setValue(somePath, someValue);

someOtherValue = settings.value(someOtherPath, someDefault);

现在,我有了一个使应用程序可移植的要求。因此,我主要将代码更改为:

代码语言:javascript
复制
QApplication a(argc, argv);

...

QCoreApplication::setApplicationName(APP_NAME);
QCoreApplication::setOrganizationDomain(MY_DOMAIN);
QCoreApplication::setOrganizationName(MY_ORGANIZATION);
QCoreApplication::setApplicationVersion(APP_VERSION);

if (PORTABLE) {
    QSettings::setDefaultFormat(QSettings::IniFormat);
    QString settingsPath = a.applicationDirPath() + "/settings";
    QSettings::setPath(QSettings::defaultFormat(), QSettings::UserScope, settingsPath);
    QSettings::setPath(QSettings::defaultFormat(), QSettings::SystemScope, settingsPath);
}

...

a.exec();

但是,实际的位置不是写到APP_PATH/settings/上的,而是APP_PATH/settings/ORGANIZATION_NAME/,在我看来,这有点太难看了。

我想设置QSettings来将设置存储在特定的位置。用户代码必须不知道存储位置的更改。理想情况下,在main中设置QSettings,并进一步使用用默认构造函数构造的对象。

我发现只有QSettings(const QString &fileName, QSettings::Format format, QObject *parent = nullptr)构造函数才能真正地设置存储位置。所有其他构造函数都在路径中添加内容。而且,由于我不希望用户代码知道应用程序的可移植性,所以每次使用不同的构造函数都不是一个选项。

我想像这样子类QSettings来修复setPath()

代码语言:javascript
复制
class Settings : public QSettings {
private:
    static QString mPath = "";

public:
    Settings(QObject *parent = nullptr) :
        QSettings(
            mPath.isEmpty() ? 
            QSettings() : 
            QSettings(mPath, Settings::defaultFormat, parent)
        )
    {}

    static void setPath(QSettings::Format format, QSettings::Scope scope, const QString &path)
    {
        mPath = path;
        QSettings::setPath(format, scope, path);
    }
} 

但这是不可能的,因为QSettings没有副本构造函数。在每一种情况下都可以使用QSettings(mPath, Settings::defaultFormat, parent)构造基础,但如果没有设置mPath,则不能将其设置为默认路径,因为没有获得默认QSettings存储路径的方法(有setPath,但没有getPath;有getFileName,没有setFileName;从fileName派生“路径”很容易出错,因为Qt在派生fileName的" path“中添加了一些”魔术“,比如组织名称,而这种”魔力“并没有得到真正的记录)。

所以我想出的唯一解决办法是:

  1. 创建一个工厂,该工厂意识到应用程序的可移植性,使用适当的构造函数在堆上构造QSettings对象,并返回指向它的指针。这样做的缺点是必须管理动态构造的对象的内存,因此增加了不合理的复杂性。此外,它还添加了另一个依赖于应用程序可移植性的实体。
  2. 就像上面一样但是和单身的孩子。这也增加了额外的复杂性,同时解决了死亡的简单问题。同样,在这种情况下,QSettings对象将在整个应用程序生存期内存在。

所以我有一种感觉,我肯定在这里遗漏了一些东西,我想知道是否有一个更简单的解决这个问题的方法。

附带注意:目前我解决了这个问题,如果应用程序是可移植的,则将我的组织名称设置为“设置”,因此应用程序设置存储在app _文件夹/ so /APP_NAME.ini中。一次肮脏的黑客攻击,但节省了大量的复杂性。我在任何地方都不使用这个组织的名字。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-02 11:37:16

我的理解是,您本质上希望根据是否设置了特定路径,以两种方式之一构造QSettings

与从QSettings继承不同,您可以创建一个类,该类具有指向成员->操作符的重载指针,返回指向QSettings实例的指针。这样,QSettings的初始化就可以推迟到需要时,并使用设置好的任何信息。

代码语言:javascript
复制
class settings {
public:
  static void set_path (QSettings::Format format, QSettings::Scope scope, const QString &path)
    {
      s_path = path;
      QSettings::setPath(format, scope, path);
    }
  QSettings *operator-> ()
    {
      return get_settings();
    }
private:
  QSettings *get_settings ()
    {
      if (!m_settings) {
        if (s_path.isEmpty()) {
          m_settings = std::make_unique<QSettings>();
        } else {
          m_settings = std::make_unique<QSettings>(s_path, QSettings::defaultFormat());
        }
      }
      return m_settings.get();
    }
  static QString             s_path;
  std::unique_ptr<QSettings> m_settings;
};

QString settings::s_path = "";

当与默认设置/值一起使用时.

代码语言:javascript
复制
settings settings;
std::cout << "\nsettings file path is [" << settings->fileName() << "]";

上面提到的东西就像..。

代码语言:javascript
复制
settings file path is [/home/<user>/.config/Unknown Organization/appname.conf]

使用.显式设置所需路径

代码语言:javascript
复制
settings::set_path(QSettings::defaultFormat(), QSettings::SystemScope, app.applicationDirPath() + "/settings.ini");
settings settings;
std::cout << "\nsettings file path is [" << settings->fileName() << "]";

给..。

代码语言:javascript
复制
settings file path is [/home/<user>/scratch/settings.ini]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54956708

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档