Я использую Qt5.7 на Windows7.
В моем текущем приложении у меня есть свой собственный класс диспетчера настроек, который выглядит следующим образом:
Заголовок:
class SettingsManager
{
public:
void write(const QString & key, const QVariant & variant);
QVariant read (const QString & key) const;
private:
static QSettings settings;
};
Источник cpp:
QSettings SettingsManager::settings("settings.ini", QSettings::IniFormat);
void SettingsManager::write(const QString & key, const QVariant & variant)
{
settings.setValue(key, variant);
}
QVariant SettingsManager::read(const QString & key) const
{
return settings.value(key);
}
Моя проблема в том, что я дал приложение нескольким друзьям, и, возможно, они запустили его с другим рабочим каталогом или чем-то еще, и приложение не нашло settings.ini
файл, следовательно, он не работал как надо …
Итак, вопрос: как я могу изменить приведенный выше код, чтобы иметь возможность получить settings.ini
файл из каталога приложения / исполняемого файла? Очевидно, что settings.ini
Файл всегда находится в той же папке, что и само приложение.
Кажется немного странным видеть объект со всеми нестатическими функциями-членами и со всеми статическими членами-данными. Вы используете это как SettingsManager()::read(...)
?
Может быть более уместным просто использовать функции в пространстве имен или в шаблоне синглтона.
В любом случае, вернемся к вопросу, вы можете использовать QApplication :: applicationDirPath () для этого. Он получает абсолютный путь к каталогу, содержащему двоичный файл приложения. Например.
QString absPath = QDir(QApplication::applicationDirPath()).filePath("settings.ini");
получает абсолютный путь туда, куда вы хотите.
похоже, у вас есть проблема с этим, так как вы используете его в глобальном статическом инициализаторе, который запускается перед вводом main (), поэтому QApplication еще не существует. Вы можете использовать статическую переменную функции, чтобы отложить инициализацию до вызова функции.
Вы можете выбрать либо создание одноэлементного SettingsManager, либо просто QSettings (я думаю, что QSettings, вероятно, более странный, как я уже говорил выше).
Пример синглтона QSettings: (должен быть определен в cpp)
QSettings& globalInstance() {
static QSettings settings(QDir(QApplication::applicationDirPath()).filePath("settings.ini"));
return settings;
}
если вы используете это в своих функциях, он не будет создавать QSettings до тех пор, пока вы не вызовете функцию, и к тому времени появится экземпляр QApplication. Но я бы предпочел сделать весь класс синглтоном:
settingsmanager.h:
#include <QApplication>
#include <QDir>
#include <QSettings>
class SettingsManager
{
public:
SettingsManager & instance();
void write(const QString & key, const QVariant & variant);
QVariant read (const QString & key) const;
private:
SettingsManager(const QString & path) :
settings(path, QSettings::IniFormat)
{}
QSettings settings;
};
settingsmanager.cpp:
#include "settingsmanager.h"
SettingsManager& SettingsManager::instance() {
static SettingsManager s(QDir(QApplication::applicationDirPath()).filePath("settings.ini"));
return s;
}
void SettingsManager::write(const QString & key, const QVariant & variant)
{
settings.setValue(key, variant);
}
QVariant SettingsManager::read(const QString & key) const
{
return settings.value(key);
}
использование:
auto val = SettingsManager::instance().read("key");
Вы можете установить путь установки с помощью QSettings::setPath
Так
QSettings::setPath(QSettings::IniFormat,QSettings::SystemScope,
QCoreApplication::applicationDirPath());
Должен сделать свое дело.
Кажется, потому что у вас есть один INI-файл, а не на пользователя SystemScope
уместно здесь
Замечания: Это установит это местоположение, которое ищет Qt все INI-файлы в вашей программе для SystemScope
так что не используйте это, если вы хотите, чтобы расположение нескольких файлов INI для SystemScope
Вы не должны отправлять INI-файлы с вашей заявкой. Когда пользователь запускает приложение в первый раз, приложение создает INI-файл. Когда вы читаете ваши настройки, вы всегда должны установить значение по умолчанию. Для дальнейшего использования пользователь переопределит значения по умолчанию и будет использовать сохраненные настройки.
Измените вашу функцию чтения с помощью:
QVariant SettingsManager::read(const QString & key, const QVariant &defaultValue) const
{
return settings.value(key,defaultValue);
}
и где бы вы ни вызывали функцию, всегда указывайте значение по умолчанию