Qt: Ошибка получения ini-файла настроек из каталога application / исполняемый файл

Я использую 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 Файл всегда находится в той же папке, что и само приложение.

0

Решение

Кажется немного странным видеть объект со всеми нестатическими функциями-членами и со всеми статическими членами-данными. Вы используете это как 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");
3

Другие решения

Вы можете установить путь установки с помощью QSettings::setPath

Так

QSettings::setPath(QSettings::IniFormat,QSettings::SystemScope,
QCoreApplication::applicationDirPath());

Должен сделать свое дело.

Кажется, потому что у вас есть один INI-файл, а не на пользователя SystemScope уместно здесь

Замечания: Это установит это местоположение, которое ищет Qt все INI-файлы в вашей программе для SystemScope так что не используйте это, если вы хотите, чтобы расположение нескольких файлов INI для SystemScope

2

Вы не должны отправлять INI-файлы с вашей заявкой. Когда пользователь запускает приложение в первый раз, приложение создает INI-файл. Когда вы читаете ваши настройки, вы всегда должны установить значение по умолчанию. Для дальнейшего использования пользователь переопределит значения по умолчанию и будет использовать сохраненные настройки.

Измените вашу функцию чтения с помощью:

QVariant SettingsManager::read(const QString & key, const QVariant &defaultValue) const
{
return settings.value(key,defaultValue);
}

и где бы вы ни вызывали функцию, всегда указывайте значение по умолчанию

1
По вопросам рекламы [email protected]