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

Qt: Issue getting the settings ini file from application/executable directory

本文关键字:设置 获取 ini 文件 问题 应用程序 可执行 Qt      更新时间:2023-10-16

我在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文件总是在同一个文件夹作为应用程序本身。

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

无论如何,回到问题,您可以为此目的使用QApplication::applicationDirPath()。它获取包含应用程序二进制文件的目录的绝对路径。例如

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

得到你想要的位置的绝对路径。

编辑:-回应关于"QApplication不存在错误"的评论

似乎您对此有问题,因为您在全局静态初始化器中使用它,该初始化器在进入main()之前运行,因此还没有QApplication。您可以使用静态函数变量来延迟初始化,直到函数被调用。

你可以选择单独的setingsmanager,或者只是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程序中的位置,所以不要使用这个,如果你想为SystemScope多个ini文件的位置

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

修改你的read函数:

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

和无论你在哪里调用这个函数总是提供默认值