QLibraryInfo、qt.conf用法及关系总结

1.QLibraryInfo说明

Qt中有个类为QLibraryInfo,Qt官方对其解释如下:

Detailed Description

Many pieces of information are established when Qt is configured and built. This class provides an abstraction for accessing that information. By using the static functions of this class, an application can obtain information about the instance of the Qt library which the application is using at run-time.

You can also use a qt.conf file to override the hard-coded paths that are compiled into the Qt library. For more information, see the Using qt.conf documentation.

See also QSysInfo and Using qt.conf.

中文的意思是:当Qt被构建和配置的时候,很多片段化的信息被建立。 QLibraryInfo类提供访问这些片段化信息的抽象访问接口。通过调用QLibraryInfo类的一些静态函数,应用程序能获取其在运行时用到的一些Qt相关库的信息。你能够用qt.conf文件去改变那些编译到Qt库中的硬编码路径。

下面详细说明:

当安装Qt时,Qt的一些目录路径会被内建到QLibraryInfo类。如下为Qt在Windows下安装后的目录:

                                                                       图1 

 在某些需求、某些情况下,需要获取这些目录路径,如:需要知道Qt的可执行文件、dll所在目录C:\Qt\Qt5.14.1\5.14.1\msvc2017_64\bin,此时就可以通过QLibraryInfo类获取。QLibraryInfo类提供了QLibraryInfo::LibraryLocation枚举,对应上图中的目录,如下:

枚举名枚举值含义

QLibraryInfo::PrefixPath

0所有路径的默认前缀

QLibraryInfo::DocumentationPath

1安装路径中文档位置

QLibraryInfo::HeadersPath

2头文件位置

QLibraryInfo::LibrariesPath

3库的安装位置

QLibraryInfo::LibraryExecutablesPath

4库在运行时所需的已安装可执行文件的位置

QLibraryInfo::BinariesPath

5Qt二进制文件(工具和应用程序)安装位置

QLibraryInfo::PluginsPath

6Qt插件位置

QLibraryInfo::ImportsPath

7QML扩展用于导入的安装位置(QML 1.x)。

QLibraryInfo::Qml2ImportsPath

8QML扩展用于导入的安装位置(QML 2.x)。

QLibraryInfo::ArchDataPath

9通用的、和操作系统有关的Qt数据位置

QLibraryInfo::DataPath

10通用的、和操作系统无关的Qt数据位置

QLibraryInfo::TranslationsPath

11Qt字符串翻译信息的位置

QLibraryInfo::ExamplesPath

12位于安装目录下,Qt例子位置。

QLibraryInfo::TestsPath

13Qt安装目录下测试用例位置

QLibraryInfo::SettingsPath

100Qt设置位置,在Windows下不起作用,无意义。

                                                           表1 

通过QLibraryInfo::location方法可获取上述枚举表示值的字符串路径。QLibraryInfo::location定义如下:

[static] QString QLibraryInfo::location(QLibraryInfo::LibraryLocation loc)

例如,可以用如下代码打印出上述枚举:

#include <QCoreApplication> 
#include<QLibraryInfo>
#include<QDebug>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    for (auto nType = 0; nType <= 13; ++nType)
    {
        auto libLocal = static_cast<QLibraryInfo::LibraryLocation>(nType);
        qDebug() << QLibraryInfo::location(libLocal) << "\n";
    }
     
    // 最后一个
    qDebug() << QLibraryInfo::location(QLibraryInfo::SettingsPath) << "\n";
        
    return a.exec();
}

我本机操作系统是Windows 11,在我本机输出结果如下:

 可以看到:QLibraryInfo::LibraryExecutablesPath和QLibraryInfo::BinariesPath在我本机表示的目录相同;QLibraryInfo::PrefixPath、QLibraryInfo::ArchDataPath、QLibraryInfo::DataPath在我本机表示的目录也相同。

2.qt.conf

   2.1.位置及格式

    qt.conf是一个ini格式的文件。QLibraryInfo将会从以下3个位置加载qt.conf文件:

  1. 利用Qt的资源系统从资源文件:/qt/etc/qt.conf处加载。
  2. 对于macOS,则是位于资源目录下的应用程序簇中。例如:
    app/Contents/Resources/qt.conf。
  3. 包含应用程序的目录,例如:
     QCoreApplication::applicationDirPath() + QDir::separator() + "qt.conf" 

在qlibraryinfo.cpp文件中,我们可以发现这样一个类:

struct QLibrarySettings
{
    QLibrarySettings();
    void load();

    QScopedPointer<QSettings> settings;
}

在QLibrarySettings构造函数中会调用load方法,load中会调用一个私有类的方法:

QSettings *QLibraryInfoPrivate::findConfiguration(){
    QString qtconfig = QStringLiteral(":/qt/etc/qt.conf");
    if (QFile::exists(qtconfig))
        return new QSettings(qtconfig, QSettings::IniFormat);
        
    if (QCoreApplication::instance()) {
	    QDir pwd(QCoreApplication::applicationDirPath());
	    qtconfig = pwd.filePath(QLatin1String("qt.conf"));
	    if (QFile::exists(qtconfig))
	        return new QSettings(qtconfig, QSettings::IniFormat);
	}
	
	return 0;
}

就是说她先会在qrc资源文件中寻找:/qt/etc/qt.conf,如果没有则在应用程序所在路径寻找qt.conf。这和Qt帮助文档中所说的一样。QSettings::IniFormat代表qt.conf是一个ini格式文件,解析的结果会保存在一个QSettings类中.

qt.conf中有许多可以配置的项,我们不必每个都设置,它有一个默认值,保存在一个key-value键值对结构体中:

static const struct {
    char key[19], value[13];
} qtConfEntries[] = {
    { "Prefix", "." },
    { "Documentation", "doc" }, // should be ${Data}/doc
    { "Headers", "include" },
    { "Libraries", "lib" },
#ifdef Q_OS_WIN
    { "LibraryExecutables", "bin" },
#else
    { "LibraryExecutables", "libexec" }, // should be ${ArchData}/libexec
#endif
    { "Binaries", "bin" },
    { "Plugins", "plugins" }, // should be ${ArchData}/plugins
    { "Imports", "imports" }, // should be ${ArchData}/imports
    { "Qml2Imports", "qml" }, // should be ${ArchData}/qml
    { "ArchData", "." },
    { "Data", "." },
    { "Translations", "translations" }, // should be ${Data}/translations
    { "Examples", "examples" },
    { "Tests", "tests" },
#ifdef QT_BUILD_QMAKE
    { "Sysroot", "" },
    { "HostBinaries", "bin" },
    { "HostLibraries", "lib" },
    { "HostData", "." },
    { "TargetSpec", "" },
    { "HostSpec", "" },
    { "HostPrefix", "" },
#endif
};

   2.2 覆盖路径

     qt.conf文件能用来覆盖编译到Qt库中的硬编码路径,也就是1节提到的通过QLibraryInfo::location和QLibraryInfo::LibraryLocation获取到的路径。如果qt.conf中设置了这些路径,则通过QLibraryInfo::location和QLibraryInfo::LibraryLocation获取到的路径将不再是Qt安装时的默认路径,而是qt.conf中设置的这些路径。这在某些情况下会非常有用,如:如果没有qt.conf文件,则Qt库将会用默认硬编码路径去查找插件、翻译文件等路径,这些目录路径在某些目标系统上可能不存在或不能访问,在这种情况下,可以通过在qt.conf文件设置路径,让Qt从qt.conf设置的路径搜索。

      qt.conf文件由路径组构成。每个组对应QLibraryInfo::LibraryLocation枚举即表1中的一个枚举值,如下:

节点

Prefix

QCoreApplication::applicationDirPath()

Documentation

doc

Headers

include

Libraries

lib

LibraryExecutables

libexec

Binaries

bin

Plugins

plugins

Imports

imports

Qml2Imports

qml

ArchData

.

Data

.

Translations

translations

Examples

examples

Tests

tests

Settings

.

                                                         表2 

绝对路径被用于qt.conf文件,即qt.conf文件中Prefix节点是绝对路径,所有其它路径可以用个相对于Prefix节点的相对路径表示,当然也可以用绝对路径表示。在Windows 、 X11上,Prefix是相对于包含应用程序可执行文件所在目录(QCoreApplication::applicationDirPath()返回的目录)。在macOS,Prefix是相对于位于资源目录下的应用程序簇中。例如:application.app/Contents/plugins/   是默认的加载Qt插件的目录。例如:qt.conf文件可能像下面那样:

 [Paths]
  Prefix = /some/path
  Translations = i18n

注意:\ 字符在Windows平台的ini文件被当做特殊字符,推荐用/;如果非用\不可,则用\\进行转义。

2.3.配置参数到平台插件

qt.conf包含Platforms组节点,其键是逗号分割的参数列表,这些参数会被传入平台插件。键的名称是平台插件名,键名第一个字母大写,后面跟随参数,如:

 [Platforms]
  WindowsArguments = fontengine=freetype

将会引起Windows平台插件用freetype字体引擎。

3.为何需要qt.conf?

    在2.2节提到qt.conf文件的作用。下面举一个应用场景:

我们打包自己开发的应用程序给客户时,一般要将Qt的plugins目录放在可执行程序的同一目录下进行打包,如下:

       Qt的plugins目录存放了Qt自己的插件和自己开发的插件,如果该目录不打入包里面,可执行文件运行时会报错,缺少plugins目录的包在运行主程序时,典型的报错如下:

       由于某些原因,在将自己开发出的应用程序打包给客户时, Qt的plugins目录或2.2节表2提到的目录,不能和主程序放在同一目录下或者开发者想要放到自己设定的目录中,此时,可以在qt.conf中更改插件或其它目录路径。如下为更改plugins目录后的qt.conf文件内容:

  可以看到主程序放到D:\QGIS\build\output\bin\Release目录下,而插件目录放到C:/Users/dansh/Desktop/plugins目录,在编辑好qt.conf文件后,将qt.conf放到主程序目录下即可(本例指D:\QGIS\build\output\bin\Release)。如果不在qt.conf文件配置表2中提到的相关目录路径且主程序同一目录下,又搜索不到表2提到的相关目录路径,则主程序会报错或某些功能会缺失。


参考链接:https://blog.csdn.net/GG_SiMiDa/article/details/78528193

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值