• qt获取qt.conf 中内容过程


    qt.conf是与QlibraryInfo关联的。与qmake基本没有关系。

    qt.conf 用于手动配置 qt程序的环境路径,qt库、translations文件等等。引入qt.conf目的就是方便手动配置QlibraryInfo的各项值,所以必须依赖QlibraryInfo类来使用。下面是QlibraryInfo中预先编译的可能会依赖的路径的名称的枚举,这些名称都对应一个默认的字符串值。
    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" 

    1. //QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\src\corelib\global\qlibraryinfo.h
    2. enum LibraryLocation
    3. {
    4. PrefixPath = 0,
    5. DocumentationPath,
    6. HeadersPath,
    7. LibrariesPath,
    8. LibraryExecutablesPath,
    9. BinariesPath,
    10. PluginsPath,
    11. ImportsPath,
    12. Qml2ImportsPath,
    13. ArchDataPath,
    14. DataPath,
    15. TranslationsPath,
    16. ExamplesPath,
    17. TestsPath,
    18. // Insert new values above this line
    19. // Please read the comments in qlibraryinfo.cpp before adding
    20. #ifdef QT_BUILD_QMAKE
    21. // These are not subject to binary compatibility constraints
    22. SysrootPath,
    23. SysrootifyPrefixPath,
    24. HostBinariesPath,
    25. HostLibrariesPath,
    26. HostDataPath,
    27. TargetSpecPath,
    28. HostSpecPath,
    29. HostPrefixPath,
    30. LastHostPath = HostPrefixPath,
    31. #endif
    32. SettingsPath = 100
    33. };
    34. //QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\src\corelib\global\qlibraryinfo.cpp
    35. QString QLibraryInfo::location(LibraryLocation loc)
    36. {
    37. .........
    38. }
    1. int main(int argc, char *argv[])
    2. {
    3. QApplication app(argc, argv);
    4. MainWindow window;
    5. window.show();
    6. return app.exec();
    7. }

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

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

    1. //QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\src\corelib\global\qlibraryinfo.cpp
    2. QSettings *QLibraryInfoPrivate::findConfiguration()
    3. {
    4. #ifdef QT_BUILD_QMAKE
    5. QString qtconfig = qmake_libraryInfoFile();
    6. if (QFile::exists(qtconfig))
    7. return new QSettings(qtconfig, QSettings::IniFormat);
    8. #else
    9. QString qtconfig = QStringLiteral(":/qt/etc/qt.conf"); //应该是linux下的qt.conf的配置方式之一。linux中qt.conf可以配置在:/qt/etc/下,也可以配置在当前文件下。如果存在,程序会优先使用:/qt/etc/中的qt.conf
    10. if (QFile::exists(qtconfig))
    11. return new QSettings(qtconfig, QSettings::IniFormat);
    12. #ifdef Q_OS_DARWIN
    13. CFBundleRef bundleRef = CFBundleGetMainBundle();
    14. if (bundleRef) {
    15. QCFType<CFURLRef> urlRef = CFBundleCopyResourceURL(bundleRef,
    16. QCFString(QLatin1String("qt.conf")),
    17. 0,
    18. 0);
    19. if (urlRef) {
    20. QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
    21. qtconfig = QDir::cleanPath(path);
    22. if (QFile::exists(qtconfig))
    23. return new QSettings(qtconfig, QSettings::IniFormat);
    24. }
    25. }
    26. #endif
    27. if (QCoreApplication::instance()) {
    28. QDir pwd(QCoreApplication::applicationDirPath());
    29. qtconfig = pwd.filePath(QLatin1String("qt.conf")); //发现 qt.conf
    30. if (QFile::exists(qtconfig))
    31. return new QSettings(qtconfig, QSettings::IniFormat);
    32. }
    33. #endif
    34. return 0; //no luck
    35. }
    1. //QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\src\gui\kernel\qplatformintegrationfactory.cpp
    2. Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
    3. (QPlatformIntegrationFactoryInterface_iid, QLatin1String("/platforms"), Qt::CaseInsensitive)) //(QPlatformIntegrationFactoryInterface_iid, QLatin1String("/platforms"), Qt::CaseInsensitive)整体作为QFactoryLoader对象初始化参数,Q_GLOBAL_STATIC_WITH_ARGS作用是通过loader对QFactoryLoader对象进行包装,并加入原子计数功能。
    4. //QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\src\corelib\plugin\qfactoryloader.cpp
    5. void QFactoryLoader::update()
    6. {
    7. #ifdef QT_SHARED
    8. Q_D(QFactoryLoader);
    9. QStringList paths = QCoreApplication::libraryPaths();
    10. for (int i = 0; i < paths.count(); ++i) {//update遍历librarypaths
    11. const QString &pluginDir = paths.at(i);
    12. // Already loaded, skip it...
    13. if (d->loadedPaths.contains(pluginDir))
    14. continue;
    15. d->loadedPaths << pluginDir;
    16. QString path = pluginDir + d->suffix;
    17. .....
    18. }
    19. QFactoryLoader::QFactoryLoader(const char *iid,
    20. const QString &suffix,
    21. Qt::CaseSensitivity cs)
    22. : QObject(*new QFactoryLoaderPrivate)
    23. {
    24. moveToThread(QCoreApplicationPrivate::mainThread());
    25. Q_D(QFactoryLoader);
    26. d->iid = iid;
    27. #if QT_CONFIG(library)
    28. d->cs = cs;
    29. d->suffix = suffix; //suffix初始化
    30. QMutexLocker locker(qt_factoryloader_mutex());
    31. update(); //QFactoryLoader初始化调用update
    32. .....
    33. }

    qt.conf 内容格式为INI文件格式,就是QSetting保存文件的内容的格式。设置Prefix,就不需要拷贝qt的库文件(比如qt5core.dll)到exe的文件夹下了。

    1. [Paths] //注释
    2. Prefix=QtInstallDir/Qt5.12.0/5.12.0/msvc2015_64 //prefix是可以是相对路径,相对于QCoreApplication::applicationDirPath(),其他路径都是相对于Prefix的。此处用的是绝对路径,QtInstallDir/Qt5.12.0/5.12.0/msvc2015_64是电脑上qt库的位置。
    3. Binaries=bin //Binaries、Libraries、include的值与 Prefix的值或当前路径 组装出对应的路径。
    4. Libraries=lib
    5. Plugins=plugins
    6. Doc=deg\\doc //"\"在INI文件中是特殊字符
    7. Imports=ggt/imports
    8. Qml2Imports=qml
    9. Platforms/WindowsArguments = fontengine=freetype //为windows platform设置参数。为qwindows.dll提供参数。

    qt.conf等号左边的叫键,右边的叫值,值根据具体开发环境进行设置。有效的固定的键名及其默认值如下(可以发现固定键与enum LibraryLocation中的项名是一一对应的)(注意除了固定键,还可以有不固定的参数键,目前qt只提供platformPluginArguments()来处理传入参数):

    1. //QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\src\corelib\global\qlibraryinfo.cpp
    2. static const struct {
    3. char key[19], value[13];
    4. } qtConfEntries[] = {
    5. { "Prefix", "." },
    6. { "Documentation", "doc" }, // should be ${Data}/doc
    7. { "Headers", "include" },
    8. { "Libraries", "lib" },
    9. #ifdef Q_OS_WIN
    10. { "LibraryExecutables", "bin" },
    11. #else
    12. { "LibraryExecutables", "libexec" }, // should be ${ArchData}/libexec
    13. #endif
    14. { "Binaries", "bin" },
    15. { "Plugins", "plugins" }, // should be ${ArchData}/plugins,
    16. { "Imports", "imports" }, // should be ${ArchData}/imports
    17. { "Qml2Imports", "qml" }, // should be ${ArchData}/qml
    18. { "ArchData", "." },
    19. { "Data", "." },
    20. { "Translations", "translations" }, // should be ${Data}/translations
    21. { "Examples", "examples" },
    22. { "Tests", "tests" },
    23. #ifdef QT_BUILD_QMAKE //这个宏表示下面的键值对在编译qmake的时候会用到。
    24. { "Sysroot", "" },
    25. { "SysrootifyPrefix", "" },
    26. { "HostBinaries", "bin" },
    27. { "HostLibraries", "lib" },
    28. { "HostData", "." },
    29. { "TargetSpec", "" },
    30. { "HostSpec", "" },
    31. { "HostPrefix", "" },
    32. #endif
    33. };
    34. ......
    35. static const char platformsSection[] = "Platforms";
    36. ......
    37. QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
    38. {
    39. #if !defined(QT_BUILD_QMAKE) && !defined(QT_NO_SETTINGS)
    40. QScopedPointer<const QSettings> settings(QLibraryInfoPrivate::findConfiguration());
    41. if (!settings.isNull()) {
    42. const QString key = QLatin1String(platformsSection)
    43. + QLatin1Char('/')
    44. + platformName
    45. + QLatin1String("Arguments");
    46. return settings->value(key).toStringList();
    47. }
    48. #else
    49. Q_UNUSED(platformName);
    50. #endif // !QT_BUILD_QMAKE && !QT_NO_SETTINGS
    51. return QStringList();
    52. }
    qt自带examples plugandpaint项目的编译后的文件结构

    All Qt GUI applications require a plugin that implements the Qt Platform Abstraction (QPA) layer in Qt 5. For Windows, the name of the platform plugin is qwindows.dll. This file must be located within a specific subdirectory (by default, platforms) under your distribution directory. Alternatively, it is possible to adjust the search path Qt uses to find its plugins, as described below.

    为了保证下面程序运行,需要在该执行程序路径下(我用于调试,所以放在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放入其中。

    qt程序设置plugin查找路径的方式:

    1、Using qt.conf. This approach is the recommended if you have executables in different places sharing the same plugins.
    2、Using QApplication::addLibraryPath() or QApplication::setLibraryPaths(). This approach is recommended if you only have one executable that will use the plugin.
    3、Using a third party installation utility to change the hard-coded paths in the QtCore library.

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

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

  • 相关阅读:
    AP1236 线性LDO稳压IC 工作原理图分享
    第二课:使用C++实现视频去水印
    magical_spider远程采集方案
    学习人工智能
    Python 2.7 requests库POST请求体中有中文的处理方法
    C++入门精讲——入门看完这一篇就够了
    OWASP API SECURITY TOP 10
    html在线商城购物网站制作——基于HTML+CSS+JavaScript鲜花礼品电商网站
    AES和Rijndael的区别
    【高项笔记】No.3 网络接入技术和网络规划与设计
  • 原文地址:https://blog.csdn.net/qiushangren/article/details/126868864