是否可以设置QSettings
存储的实际默认路径(带或不带文件名),并防止QSettings
向该路径附加组织名称之类的方法?前提是必须继续使用QSettings
,并且不了解设置存储路径。
考虑用例。在我的主目录中,我有以下代码:
QApplication a(argc, argv);
...
QCoreApplication::setApplicationName(APP_NAME);
QCoreApplication::setOrganizationDomain(MY_DOMAIN);
QCoreApplication::setOrganizationName(MY_ORGANIZATION);
QCoreApplication::setApplicationVersion(APP_VERSION);
...
a.exec();
在我的整个项目中,我都这样使用QSettings
:
QSettings settings;
settings.setValue(somePath, someValue);
someOtherValue = settings.value(someOtherPath, someDefault);
现在我有一个使应用程序可移植的要求。所以我将main中的代码更改为此:
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()
:
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
设置为默认路径(如果尚未设置)的情况,因为无法获得默认的{ {1}}存储路径(有QSettings
,但没有setPath
;有getPath
,没有getFileName
;从fileName派生“路径”很容易出错,因为Qt将一些“魔术”(如组织名称)添加到“路径”以派生fileName,而该“魔术”并未真正记录下来。)
所以我想出的唯一解决方案是:
setFileName
对象
构造函数,并返回指向它的指针。这有一个缺点
必须管理该动态构造对象的内存,
因此不合理地增加了复杂性。同时添加另一个实体
这取决于应用程序的可移植性。QSettings
对象将在整个应用程序生存期内存在。所以我有一种感觉,我肯定在这里缺少一些东西,我想知道是否有一个更简单的解决方案来解决这个问题。
旁注:当前,我通过将组织名称设置为“ settings”(如果应用程序是便携式的)来解决此问题,因此应用程序设置存储在APP_FOLDER / settings / APP_NAME.ini中。肮脏的hack,但可以节省很多复杂性。我真的没有在任何地方使用组织名称。
答案 0 :(得分:1)
我的理解是,您基本上希望根据是否设置了特定路径,以两种方式之一构造QSettings
。
您可以创建一个类,该类具有指向成员QSettings
运算符的重载指针,该成员返回指向->
实例的指针,而不是从QSettings
继承。这样,QSettings
的初始化可以推迟到需要时才进行,并利用已设置的任何信息。
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 = "";
与默认设置/值一起使用时...
settings settings;
std::cout << "\nsettings file path is [" << settings->fileName() << "]";
上面的内容类似...
settings file path is [/home/<user>/.config/Unknown Organization/appname.conf]
使用...明确设置所需的路径
settings::set_path(QSettings::defaultFormat(), QSettings::SystemScope, app.applicationDirPath() + "/settings.ini");
settings settings;
std::cout << "\nsettings file path is [" << settings->fileName() << "]";
给予...
settings file path is [/home/<user>/scratch/settings.ini]