qt获取qt.conf 中内容过程

qt获取qt.conf 中内容过程,第1张

class="superseo">qt.conf 用于手动配置 qt程序的环境路径,比如qt依赖的库、依赖的头文件、依赖的插件的路径、translations文件等等。其必须依赖QlibraryInfo类来使用。下面是QlibraryInfo中预先编译的可能会依赖的路径的名称,这些名称都对应一个默认的字符串值。这些路径在程序开发、安装和部署时可能会造成混乱,所以引入qt.conf来允许手动配置,来修改这些名称对应的默认的字符串值。
qt.conf 详细介绍的帮助文档路径为:Qt 5.12->Using qt.conf  。
具体文档为:qthelp://org.qt-project.qmake.5120/qtdoc/qt-conf.html
qt.conf所在位置要求如下:

1、:/qt/etc/qt.conf using the resource system
2、on macOS, in the Resource directory inside the application bundle, for example assistant.app/Contents/Resources/qt.conf
3、in the directory containing the application executable, i.e. QCoreApplication::applicationDirPath() + QDir::separator() + "qt.conf" 

//QtInstallDir\Qt5.12.0.12.0\Src\qtbase\src\corelib\global\qlibraryinfo.h
enum LibraryLocation
    {
        PrefixPath = 0,
        DocumentationPath,
        HeadersPath,
        LibrariesPath,
        LibraryExecutablesPath,
        BinariesPath,
        PluginsPath,
        ImportsPath,
        Qml2ImportsPath,
        ArchDataPath,
        DataPath,
        TranslationsPath,
        ExamplesPath,
        TestsPath,
        // Insert new values above this line
        // Please read the comments in qlibraryinfo.cpp before adding
#ifdef QT_BUILD_QMAKE
        // These are not subject to binary compatibility constraints
        SysrootPath,
        SysrootifyPrefixPath,
        HostBinariesPath,
        HostLibrariesPath,
        HostDataPath,
        TargetSpecPath,
        HostSpecPath,
        HostPrefixPath,
        LastHostPath = HostPrefixPath,
#endif
        SettingsPath = 100
    };

//QtInstallDir\Qt5.12.0.12.0\Src\qtbase\src\corelib\global\qlibraryinfo.cpp
QString QLibraryInfo::location(LibraryLocation loc)
{
.........
}
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow window;
    window.show();
    return app.exec();
}

而QLibraryInfo调用获取qt.conf的内容的调用栈如下。

 下面是QlibraryInfo获取qt.conf中内容的代码入口。可以看到windows下要获取到qt.conf中的内容需要先让QCoreApplication对象初始化,否则QLibraryInfo会使用默认值。

//QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\src\corelib\global\qlibraryinfo.cpp

QSettings *QLibraryInfoPrivate::findConfiguration()
{
#ifdef QT_BUILD_QMAKE
    QString qtconfig = qmake_libraryInfoFile();
    if (QFile::exists(qtconfig))
        return new QSettings(qtconfig, QSettings::IniFormat);
#else
    QString qtconfig = QStringLiteral(":/qt/etc/qt.conf");
    if (QFile::exists(qtconfig))
        return new QSettings(qtconfig, QSettings::IniFormat);
#ifdef Q_OS_DARWIN
    CFBundleRef bundleRef = CFBundleGetMainBundle();
    if (bundleRef) {
        QCFType urlRef = CFBundleCopyResourceURL(bundleRef,
                                                           QCFString(QLatin1String("qt.conf")),
                                                           0,
                                                           0);
        if (urlRef) {
            QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
            qtconfig = QDir::cleanPath(path);
            if (QFile::exists(qtconfig))
                return new QSettings(qtconfig, QSettings::IniFormat);
        }
    }
#endif
    if (QCoreApplication::instance()) {
        QDir pwd(QCoreApplication::applicationDirPath());
        qtconfig = pwd.filePath(QLatin1String("qt.conf"));  //发现 qt.conf
        if (QFile::exists(qtconfig))
            return new QSettings(qtconfig, QSettings::IniFormat);
    }
#endif
    return 0;     //no luck
}
//QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\src\gui\kernel\qplatformintegrationfactory.cpp
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
    (QPlatformIntegrationFactoryInterface_iid, QLatin1String("/platforms"), Qt::CaseInsensitive)) //(QPlatformIntegrationFactoryInterface_iid, QLatin1String("/platforms"), Qt::CaseInsensitive)整体作为QFactoryLoader对象初始化参数,Q_GLOBAL_STATIC_WITH_ARGS作用是通过loader对QFactoryLoader对象进行包装,并加入原子计数功能。


//QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\src\corelib\plugin\qfactoryloader.cpp
void QFactoryLoader::update()
{
#ifdef QT_SHARED
    Q_D(QFactoryLoader);
    QStringList paths = QCoreApplication::libraryPaths();
    for (int i = 0; i < paths.count(); ++i) {//update遍历librarypaths
        const QString &pluginDir = paths.at(i);
        // Already loaded, skip it...
        if (d->loadedPaths.contains(pluginDir))
            continue;
        d->loadedPaths << pluginDir;

        QString path = pluginDir + d->suffix; 

.....
}

QFactoryLoader::QFactoryLoader(const char *iid,
                               const QString &suffix,
                               Qt::CaseSensitivity cs)
    : QObject(*new QFactoryLoaderPrivate)
{
    moveToThread(QCoreApplicationPrivate::mainThread());
    Q_D(QFactoryLoader);
    d->iid = iid;
#if QT_CONFIG(library)
    d->cs = cs;
    d->suffix = suffix;  //suffix初始化

    QMutexLocker locker(qt_factoryloader_mutex());
    update();  //QFactoryLoader初始化调用update
.....
}

qt.conf 内容格式为INI文件格式,就是QSetting保存文件的内容的格式。

[Paths] //注释
Prefix=.  //prefix是相对于QCoreApplication::applicationDirPath(),其他路径都是相对于Prefix的
Binaries=bin
Libraries=lib
Plugins=plugins
Doc=deg\doc  //"\"在INI文件中是特殊字符
Imports=ggt/imports
Qml2Imports=qml
WindowsArguments = fontengine=freetype  //为windows platform设置参数。为qwindows.dll提供参数。

为了保证下面程序运行,需要在该执行程序路径下(我用于调试,所以放在build-plugandpaint-Desktop_Qt_5_12_0_MSVC2015_64bit-Debug下)建立platforms子目录并放入qwindows.dll 或qwindowsd.dll;或者在build-plugandpaint-Desktop_Qt_5_12_0_MSVC2015_64bit-Debug/plugins下建立子目录platforms,并将qwindows.dll或者qwindowsd.dll放入其中。

int main(int argc, char *argv[])
{
    qDebug()<<“QLibraryInfo默认值:”;
    qDebug()<

QString QLibraryInfo::location(LibraryLocation loc)获取path的过程可以参考下面文章:

qconfig.h qconfig.cpp_丘上人的博客-CSDN博客

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/2990262.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-23
下一篇 2022-09-23

发表评论

登录后才能评论

评论列表(0条)