问题:从应用程序/可执行文件目录获取设置ini文件的问题

时间:2016-10-28 11:36:22

标签: c++ qt configuration application-settings qsettings

我在Windows7上使用Qt5.7 在我当前的应用程序中,我有自己的设置管理器类,如下所示:

标题

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文件始终与应用程序本身位于同一文件夹中。

3 个答案:

答案 0 :(得分:3)

看到具有所有非静态成员函数和所有静态数据成员的对象似乎有点奇怪。你是否像SettingsManager()::read(...)一样使用它? 在命名空间或单例模式中使用函数可能更合适。

无论如何,回到这个问题,你可以使用QApplication::applicationDirPath()来达到这个目的。它获取包含app二进制文件的目录的绝对路径。 E.g。

QString absPath = QDir(QApplication::applicationDirPath()).filePath("settings.ini");    

获得你想要的绝对路径。

编辑: - 对“QApplication不存在错误”

的评论作出回应

看起来你有这个问题,因为你在全局静态初始化器中使用它,它在进入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");

答案 1 :(得分:2)

您可以使用QSettings::setPath

设置设置路径

所以

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

应该做的伎俩。

因为你有一个ini文件似乎而不是每个用户群我认为SystemScope适合

注意:这会将此位置Qt设置为SystemScope程序中所有 ini文件的位置,所以请勿使用此项你想要SystemScope

的多个ini文件位置

答案 2 :(得分:1)

您不应该使用您的应用程序发送ini文件。当用户第一次启动应用程序时,应用程序将创建ini文件。阅读设置时,应始终设置默认值。为了将来使用,用户将覆盖默认值并使用保存的设置。

使用以下命令更改您的读取功能:

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

无论你在何处调用该函数,都始终提供默认值