Есть ли способ установить фактический путь по умолчанию для 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
для сохранения настроек в определенном месте.Пользовательский код не должен знать об изменении места хранения.В идеале установите QSettings
в main и используйте объекты, созданные в дальнейшем с помощью конструктора по умолчанию.
Я обнаружил, что только конструктор 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
в качестве пути по умолчанию, если он не был установлен, тоже нельзя сделать, потому что нет способа получить стандартный путь хранения QSettings
(есть setPath
, но нет getPath
; есть getFileName
и нет setFileName
; получение «пути» из fileName подвержено ошибкам, потому что Qt добавляет некоторую «магию», такую как имя организации, к «путь к производному fileName, и это «волшебство» на самом деле не задокументировано).
Итак, единственное решение, которое я придумал, это:
- Создание фабрики, которая знаетпереносимость приложения, создает объект
QSettings
в куче с соответствующим конструктором и возвращает указатель на него.У этого есть обратная сторона необходимости управлять памятью этого динамически сконструированного объекта, следовательно, необоснованно добавленная сложность.Кроме того, он добавляет еще одну сущность, которая зависит от переносимости приложения. - Делаем, как указано выше, но с одиночным.Это также добавляет лишнюю сложность при решении очень простой проблемы.Также в этом случае объект
QSettings
будет существовать в течение всего времени жизни приложения.
Так что у меня есть ощущение, что я определенно что-то здесь упускаю, и мне интересно, есть ли более простое решение для этогопроблема.
Примечание: в настоящее время я решил эту проблему, установив название своей организации на «настройки», если приложение переносное, поэтому настройки приложения хранятся в файле APP_FOLDER / settings / APP_NAME.ini.Грязный хак, но спасает много сложности.Во всяком случае, я нигде не использую название организации.