本页内容

macOS 版 Qt - 部署

本文档介绍了如何创建macOS应用程序包,并确保应用程序在运行时能够找到所需的资源。我们将以部署 Qt 源代码包中附带的Plug & Paint示例应用程序为例,演示相关步骤。

macOS 版的 Qt 安装程序包含一个部署工具,可自动完成本文所述的操作流程。

应用程序包

在 macOS 上,GUI 应用程序必须通过“应用程序包”进行构建和运行,该包是一种目录结构,在 Finder 中显示时呈现为单一实体。应用程序包通常包含可执行文件及其所需的所有资源。以下是应用程序包结构的示意图:

macOS 应用程序包结构,其中“Contents”文件夹包含 Frameworks、MacOS、Resources、PlugIns 以及配置文件

应用程序包为用户提供了诸多优势:

  • 由于被识别为单一实体,因此易于安装。
  • 可通过代码访问包的相关信息。

这仅适用于 macOS,超出了本文的讨论范围。有关软件包的更多信息,请参阅Apple 开发者网站。

若要使用 CMake 将应用程序构建为应用程序包,请在可执行目标上设置 MACOSX_BUNDLE 属性:

set_target_properties(plugandpaint PROPERTIES
    MACOSX_BUNDLE TRUE
)

qmake 会自动为您的应用程序生成一个捆绑包。若要禁用此功能,请在应用程序的项目文件(.pro )中添加以下语句:

CONFIG-=app_bundle

静态链接

如果您希望保持简单,且只需部署少量文件,可以使用静态链接库来构建应用程序。

静态构建 Qt

首先安装 Qt 库的静态版本。请注意,您将无法使用插件,并且必须通过静态链接来构建依赖库,例如图像格式库、SQL 驱动程序等。

cd /path/to/Qt
./configure -static <other parameters>

您可以通过运行configure -help 来查看可用的各种选项。

将应用程序链接到静态版本的 Qt

一旦 Qt 以静态方式构建完成,下一步就是重新生成构建文件并重新构建应用程序。

使用 CMake

请务必使用qt_add_executable 包装命令,该命令提供了额外逻辑,例如在静态Qt构建中链接Qt插件。

若要为 Apple 平台构建,需将cmake_minimum_required() 设置为 3.21.1 或更高版本:

cmake_minimum_required(VERSION 3.21.1)

进入包含应用程序的目录:

cd /path/to/Qt/examples/widgets/tools/plugandpaint/app

接下来,将CMAKE_PREFIX_PATH 变量设置为指向您的安装前缀。如果您已有CMake构建,请删除CMakeCache.txt 文件。然后,重新运行CMake:

cmake -DCMAKE_PREFIX_PATH=path/to/Qt/6.12.0/your_platform -S <source-dir> -B <build-dir> -G Ninja

或者,使用便捷脚本qt-cmake ,该脚本会为您自动设置CMAKE_PREFIX_PATH 变量。

path/to/Qt/6.12.0/your_platform/bin/qt-cmake -S <source-dir> -B <build-dir> -G Ninja

最后,进入您的构建目录并运行您首选的构建系统。在本例中,我们使用Ninja 。

cd path/to/build/dir
ninja

现在,只要所有内容都能无错误地编译和链接,您就应该获得一个可供部署的plugandpaint.app 软件包。请尝试将该软件包安装到一台未安装 Qt 或任何 Qt 应用程序的 macOS 机器上。

使用 qmake

首先,进入包含应用程序的目录:

cd /path/to/Qt/examples/widgets/tools/plugandpaint/app

然后,运行 `qmake ` 为应用程序生成新的 Makefile,并执行“clean”构建以生成静态链接的可执行文件:

make clean
qmake -config release
make

您可能希望链接到发布版库,可以在调用qmake 时指定此选项。您可能还希望利用“死代码剥离”功能进一步减小二进制文件的大小。除了-config release 参数外,您还可以向qmake 传递LIBS+= -dead_strip 来实现这一点。

同样,只要所有内容都能无错误地编译和链接,您就应该获得一个可部署的plugandpaint.app 软件包。请尝试将该软件包安装在未安装 Qt 或任何 Qt 应用程序的 macOS 机器上。

检查链接的库

你可以使用otool 检查应用程序链接了哪些其他库:

otool -L plugandpaint.app/Contents/MacOs/plugandpaint

以下是静态链接版Plug & Paint 的输出示例:

plugandpaint.app/Contents/MacOS/plugandpaint:
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon
        (compatibility version 2.0.0, current version 128.0.0)
/System/Library/Frameworks/QuickTime.framework/Versions/A/QuickTime
        (compatibility version 1.0.0, current version 10.0.0)
/usr/lib/libz.1.dylib
        (compatibility version 1.0.0, current version 1.2.3)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices
        (compatibility version 1.0.0, current version 22.0.0)
/usr/lib/libstdc++.6.dylib
        (compatibility version 7.0.0, current version 7.3.0)
/usr/lib/libgcc_s.1.dylib
        (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libmx.A.dylib
        (compatibility version 1.0.0, current version 92.0.0)
/usr/lib/libSystem.B.dylib
        (compatibility version 1.0.0, current version 88.0.0)

如果输出中出现了Qt库,这很可能意味着您的机器上同时安装了动态和静态 Qt 库。链接器总是优先选择动态链接而非静态链接。如果您只想使用静态库,可以采取以下任一方法:

  • 在链接应用程序时,将 Qt 动态库(.dylibs )移至其他目录,链接完成后再将其移回,
  • 或者编辑 `Makefile ` 文件,将 Qt 库的链接行替换为静态库的绝对路径。

例如,将以下内容:

-lQtGui

替换为:

/where/static/qt/lib/is/libQtGui.a

“Plug & Paint”示例由多个组件构成:核心应用程序(Plug & Paint)、Basic Tools插件以及Extra Filters插件。由于无法通过静态链接方式部署插件,因此目前准备的软件包尚不完整。 应用程序虽然可以运行,但由于缺少插件,相关功能将被禁用。要部署基于插件的应用程序,我们应采用框架方法,这是 macOS 特有的。

框架

采用此方法时,请确保 Qt 运行时已随应用程序包正确分发,且插件已安装在正确的位置,以便应用程序能够找到它们。

在框架方法中,有两种方式可将 Qt 与应用程序一同分发:

  • 应用程序包内的私有框架。
  • 标准框架(或者使用已安装二进制文件中的 Qt 框架)。

如果您的 Qt 是通过特殊方式构建的,或者希望确保框架必定存在,则首选第一种方案。这主要取决于您将 Qt 框架放置在何处。

如果您拥有多个 Qt 应用程序,并且希望它们使用单一版本的 Qt 框架而非多个版本,则第二种选项更为合适。

将 Qt 构建为框架

我们假设您已经将 Qt 作为框架安装(这是安装 Qt 时的默认设置),安装路径为 /path/to/Qt 目录。有关如何不使用框架构建 Qt 的更多信息,请参阅《Qt for macOS - 特定问题》文档。

安装时,会设置框架的标识名。动态链接器(dyld )会使用该名称来查找应用程序所需的库。

将应用程序链接到作为框架的 Qt

将 Qt 构建为框架后,我们就可以构建Plug & Paint应用程序了。

使用 CMake

要为 Apple 平台构建,需要将cmake_minimum_required() 设置为 3.21.1 或更高版本:

cmake_minimum_required(VERSION 3.21.1)

进入包含应用程序的目录:

cd /path/to/Qt/examples/widgets/tools/plugandpaint/app

接下来,将CMAKE_PREFIX_PATH 变量设置为指向您的安装前缀。如果您已有CMake构建,请删除CMakeCache.txt 文件。然后,重新运行CMake:

cmake -DCMAKE_PREFIX_PATH=path/to/Qt/6.12.0/your_platform -S <source-dir> -B <build-dir> -G Ninja

或者,使用便捷脚本qt-cmake ,该脚本会为您自动设置CMAKE_PREFIX_PATH 变量。

path/to/Qt/6.12.0/your_platform/bin/qt-cmake -S <source-dir> -B <build-dir> -G Ninja

最后,进入您的构建目录并运行您首选的构建系统。在本示例中,我们使用Ninja 。

cd path/to/build/dir
ninja

现在,只要编译和链接过程均未出现任何错误,您就应该获得了一个可供部署的plugandpaint.app 软件包。请尝试将该软件包安装到一台未安装 Qt 或任何 Qt 应用程序的 macOS 机器上。

使用 qmake

首先,进入包含应用程序的目录:

cd /path/to/Qt/examples/widgets/tools/plugandpaint/app

运行qmake 为应用程序生成新的 Makefile,并执行 clean 构建以生成动态链接的可执行文件:

make clean
qmake -config release
make

这将构建核心应用程序。请使用以下命令构建插件:

cd ../plugandpaint/plugins
make clean
qmake -config release
make

现在为 Qt 框架(例如 Qt GUI)运行 `otool `:

otool -L QtGui.framework/QtGui

您将获得以下输出:

QtGui.framework/QtGui:
/path/to/Qt/lib/QtGui.framework/Versions/4.0/QtGui
        (compatibility version 4.0.0, current version 4.0.1)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon
        (compatibility version 2.0.0, current version 128.0.0)
/System/Library/Frameworks/QuickTime.framework/Versions/A/QuickTime
        (compatibility version 1.0.0, current version 10.0.0)
/path/to/Qt/QtCore.framework/Versions/4.0/QtCore
        (compatibility version 4.0.0, current version 4.0.1)
/usr/lib/libz.1.dylib
        (compatibility version 1.0.0, current version 1.2.3)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices
        (compatibility version 1.0.0, current version 22.0.0)
/usr/lib/libstdc++.6.dylib
        (compatibility version 7.0.0, current version 7.3.0)
/usr/lib/libgcc_s.1.dylib
        (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libmx.A.dylib
        (compatibility version 1.0.0, current version 92.0.0)
/usr/lib/libSystem.B.dylib
        (compatibility version 1.0.0, current version 88.0.0)

对于 Qt 框架,第一行(即path/to/Qt/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.0.0, current version 4.0.1) )将成为该框架的标识名,该标识名将由动态链接器(dyld )使用。

但在部署应用程序时,用户可能并未在指定位置安装 Qt 框架。因此,您必须将框架放置在约定位置,或者将框架打包到应用程序包中。 无论选择哪种方案,都必须确保框架能返回其正确的标识名,并且应用程序会根据这些名称进行查找。幸运的是,我们可以使用install_name_tool 命令行工具来控制这一点。

install_name_tool 支持两种模式:-id 和-change 。-id 模式适用于库和框架,允许我们指定新的标识名;而-change 模式则用于更改应用程序中的路径。

让我们通过将 Qt 框架复制到 Plug & Paint 软件包中来测试一下。查看otool 针对该软件包的输出结果,我们可以发现必须将QtCore 和QtGui 两个框架都复制到软件包中。我们假设当前位于构建该软件包的目录下。

mkdir plugandpaint.app/Contents/Frameworks
cp -R /path/to/Qt/lib/QtCore.framework
        plugandpaint.app/Contents/Frameworks
cp -R /path/to/Qt/lib/QtGui.framework
       plugandpaint.app/Contents/Frameworks

首先,我们在包内创建一个Frameworks 目录。这符合 macOS 应用程序的规范。然后,我们将框架复制到新目录中。由于框架包含符号链接,因此我们使用-R 选项。

install_name_tool -id @executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
       plugandpaint.app/Contents/Frameworks/QtCore.framework/Versions/4.0/QtCore
install_name_tool -id @executable_path/../Frameworks/QtGui.framework/Versions/4.0/QtGui
       plugandpaint.app/Contents/Frameworks/QtGui.framework/Versions/4.0/QtGui

接着运行install_name_tool 来设置框架的标识名。-id 后面的第一个参数是新名称,第二个参数是要重命名的框架。字符串@executable_path 是一个特殊的dyld 变量,用于告知dyld 从可执行文件所在位置开始搜索。新名称指定这些框架位于Frameworks 目录下的直接子目录中。

install_name_tool -change path/to/Qt/lib/QtCore.framework/Versions/4.0/QtCore
        @executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
        plugandpaint.app/Contents/MacOs/plugandpaint
install_name_tool -change path/to/qt/lib/QtGui.framework/Versions/4.0/QtGui
        @executable_path/../Frameworks/QtGui.framework/Versions/4.0/QtGui
        plugandpaint.app/Contents/MacOs/plugandpaint

现在,动态链接器已经知道去哪里查找 `QtCore ` 和 `QtGui` 了。我们必须确保应用程序也知道去哪里查找该库,这需要借助 `install_name_tool` 的 `-change ` 模式。这基本上就是字符串替换的问题,目的是将我们之前为框架设置的标识名进行匹配。

最后,QtGui 框架依赖于QtCore ,因此我们必须记得修改QtGui 的引用:

install_name_tool -change path/to/Qt/lib/QtCore.framework/Versions/4.0/QtCore
        @executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
        plugandpaint.app/Contents/Frameworks/QtGui.framework/Versions/4.0/QtGui

之后,我们再次运行otool ,发现应用程序能够找到这些库。

Plug & Paint示例的插件使其变得有趣。使用插件时,我们需要遵循的基本步骤是:

  • 将插件放入打包文件中,
  • 运行 `install_name_tool ` 以检查插件是否使用了正确的库,
  • 并确保应用程序知道从何处查找这些插件。

我们可以将插件放在打包包中的任意位置,但最佳位置是将其放在Contents/Plugins目录下。当我们构建Plug & Paint插件时,根据其.pro 文件中的DESTDIR 变量,插件的.dylib 文件位于plugandpaint 目录下的plugins 子目录中。我们只需将该目录移动到正确的位置即可。

mv plugins plugandpaint.app/Contents

例如,如果对Basic Tools插件的.dylib 文件运行otool 命令,我们将获得以下信息。

libpnp_basictools.dylib:
libpnp_basictools.dylib
       (compatibility version 0.0.0, current version 0.0.0)
/path/to/Qt/lib/QtGui.framework/Versions/4.0/QtGui
       (compatibility version 4.0.0, current version 4.0.1)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon
       (compatibility version 2.0.0, current version 128.0.0)
/System/Library/Frameworks/QuickTime.framework/Versions/A/QuickTime
       (compatibility version 1.0.0, current version 10.0.0)
/path/to/Qt/lib/QtCore.framework/Versions/4.0/QtCore
       (compatibility version 4.0.0, current version 4.0.1)
/usr/lib/libz.1.dylib
       (compatibility version 1.0.0, current version 1.2.3)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices
       (compatibility version 1.0.0, current version 22.0.0)
/usr/lib/libstdc++.6.dylib
       (compatibility version 7.0.0, current version 7.3.0)
/usr/lib/libgcc_s.1.dylib
       (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libmx.A.dylib
       (compatibility version 1.0.0, current version 92.0.0)
/usr/lib/libSystem.B.dylib
       (compatibility version 1.0.0, current version 88.0.0)

由此可见,该插件链接到了其构建时所依赖的 Qt 框架。由于我们希望插件使用应用程序包中的框架,因此可以按照处理应用程序时的方法对插件进行修改。以 Basic Tools 插件为例:

install_name_tool -change /path/to/Qt/lib/QtCore.framework/Versions/4.0/QtCore
        @executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
        plugandpaint.app/Contents/plugins/libpnp_basictools.dylib
install_name_tool -change /path/to/Qt/lib/QtGui.framework/Versions/4.0/QtGui
        @executable_path/../Frameworks/QtGui.framework/Versions/4.0/QtGui
        plugandpaint.app/Contents/plugins/libpnp_basictools.dylib

我们还必须将tools/plugandpaint/mainwindow.cpp 中的代码修改为cdUp(),以确保应用程序能够找到这些插件。请在mainwindow.cpp 文件中添加以下代码:

#elif defined(Q_OS_MACOS)
if (pluginsDir.dirName() == "MacOS") {
    pluginsDir.cdUp();
}
#endif
macOS Finder 显示已部署的应用程序包及其插件文件夹tools/plugandpaint/mainwindow.cpp 中添加的代码还使我们能够在 Finder 中查看插件,如图所示。

我们还可以添加扩展 Qt 的插件,例如添加 SQL 驱动程序或图像格式。我们只需遵循插件文档中概述的目录结构,并确保它们被包含在QCoreApplication::libraryPaths() 中。让我们按照之前概述的步骤,快速使用图像格式来完成此操作。

将 Qt Image Formats 插件复制到捆绑包中:

cp -R /path/to/Qt/plugins/imageformats
        pluginandpaint.app/Contents/plugins

使用 `install_name_tool ` 将插件链接到包中的框架:

install_name_tool -change /path/to/Qt/lib/QtGui.framework/Versions/4.0/QtGui
        @executable_path/../Frameworks/QtGui.framework/Versions/4.0/QtGui
        plugandpaint.app/Contents/plugins/imageformats/libqjpeg.dylib
install_name_tool -change /path/to/Qt/lib/QtCore.framework/Versions/4.0/QtCore
        @executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
        plugandpaint.app/Contents/plugins/imageformats/libqjpeg.dylib

更新tools/plugandpaint/main.cpp 中的源代码,使其能够识别新的插件。在构建QApplication 之后,我们添加以下代码:

QDir dir(QCoreApplication::applicationDirPath());
dir.cdUp();
dir.cd("plugins");
QCoreApplication::setLibraryPaths(QStringList(dir.absolutePath()));

首先,我们告诉应用程序仅在此目录中查找插件。在我们的情况下,我们希望应用程序仅查找随软件包分发的那些插件。如果我们属于一个更大的 Qt 安装环境,则可以使用QCoreApplication::addLibraryPath() 代替。

警告:在 部署插件时 ,我们会修改源代码,这会在应用程序重新构建时重置默认的标识名称。因此,您必须使用install_name_tool 重复该过程,使应用程序链接到软件包中的正确 Qt 框架。

现在,您应该能够将应用程序移动到另一台未安装 Qt 的 macOS 机器上并运行它。或者,您可以将位于包外的框架移动到另一个目录,并检查应用程序是否仍能运行。

如果您将框架存储在包外的其他位置,应用程序的链接方法类似;您必须确保应用程序和框架在查找 Qt 库以及插件的位置上保持一致。

创建应用程序包

当您完成将应用程序链接到 Qt(无论是静态链接还是作为框架)后,该应用程序即可准备分发。有关更多信息,请参阅Apple 开发者网站。

尽管应用程序的部署过程确实存在一些陷阱,但只要您了解各种问题,就能轻松创建出让所有 macOS 用户满意的软件包。

应用程序依赖项

Qt 插件

所有Qt GUI 应用程序都需要一个在 Qt 中实现Qt 平台抽象(QPA) 层的插件。对于 macOS,该平台插件的名称为libqcocoa.dylib 。该文件必须位于发行版目录下的特定子目录中(默认位置为platforms )。 此外,也可以按照下文所述,调整 Qt 用于查找插件的搜索路径。

您的应用程序可能还依赖于一个或多个 Qt 插件,例如 JPEG 图像格式插件或 SQL 驱动程序插件。请确保将您所需的任何 Qt 插件与应用程序一同分发。与平台插件类似,每种类型的插件都必须位于分发目录中的特定子目录内(例如imageformats 或sqldrivers )。

Qt 插件的搜索路径(以及其他几个路径)被硬编码在QtCore 库中。默认情况下,第一个插件搜索路径将被硬编码为/path/to/Qt/plugins 。但使用预设路径存在某些弊端。 例如,目标机器上可能不存在这些路径。因此,您必须检查各种替代方案,以确保能够找到 Qt 插件:

《如何创建 Qt 插件》文档概述了在为 Qt 应用程序构建和部署插件时需要注意的问题。

其他库

您可以通过otool 命令查看应用程序链接了哪些库。请将应用程序路径作为参数传入该命令:

otool -L MyApp.app/Contents/MacOS/MyApp

编译器专用的库通常无需随应用程序一起分发。但应用程序的部署方式有多种,因为在 macOS 上,Qt 可以通过多种方式进行配置、构建和安装。通常,您的目标将决定您将如何部署应用程序。最后几节将介绍在部署应用程序时必须注意的几点事项。

macOS 部署工具

macOS 部署工具可从QTDIR/bin/macdeployqt 获取。该工具旨在自动生成可部署的应用程序包,其中将 Qt 库作为私有框架包含其中。

macOS 部署工具还会根据以下规则部署 Qt 插件(除非使用了-no-plugins 选项):

  • 平台插件始终会被部署。
  • 插件的调试版本不会被部署。
  • 设计器插件不会被部署。
  • 图像格式插件始终会被部署,但 SVG 图像格式插件除外——该插件仅在应用程序使用 Qt SVG 模块时才会部署。
  • 图标引擎插件始终会被部署。
  • 打印支持插件总是会被部署。
  • 如果应用程序使用了 Qt SQL 模块时,SQL 驱动程序插件才会被部署。
  • 辅助功能插件始终会被部署。
  • 样式插件始终会被部署。

重要提示:如果您选择 不使用 Mac 部署工具,则必须确保您的部署包中包含这些插件。

若要在应用程序包中包含第三方库,请在创建应用程序包后,手动将该库复制到应用程序包中。

macdeployqt 支持以下选项:

选项说明
-verbose=<0-3>0 = 不输出,1 = 错误/警告(默认),2 = 正常,3 = 调试
-no-plugins跳过插件部署
-dmg创建 .dmg 磁盘映像
-no-strip不对二进制文件运行 'strip' 命令
-use-debug-libs使用框架和插件的调试版本进行部署(即-no-strip )
-executable=<path>让给定的可执行文件也使用已部署的框架
-qmldir=<path>在指定路径中部署 .qml 文件所使用的导入项
-qmlimport=<path>将给定路径添加到 QML 导入的搜索位置中
-always-overwrite即使目标文件已存在,仍复制文件
-codesign=<ident>使用给定的身份对所有可执行文件运行codesign 。默认情况下,使用临时签名(-codesign=- )。
-no-codesign禁用代码签名
-hardened-runtime在代码签名时启用强化运行时
-timestamp代码签名时包含安全时间戳(需要互联网连接)
-sign-for-notarization=<ident>激活公证所需的选项(需要互联网连接)。已激活的选项包括-hardened-runtime 、-timestamp 和-codesign=<ident>
-appstore-compliant跳过使用私有 API 的组件的部署
-libpath=<path>将给定的路径添加到库搜索路径中
-fs=<filesystem>设置用于 .dmg 磁盘映像的文件系统(默认为 HFS+)

注意:macOS High Sierra 引入了新的 Apple 文件系统 (APFS)。旧版本的 macOS 无法读取采用 APFS 格式化的 .dmg 文件。默认情况下,macdeployqt 会使用较旧的 HFS+ 文件系统,以确保与 Qt 当前支持的所有 macOS 版本兼容。请使用-fs 选项来指定其他文件系统。

卷名

使用 `-dmg ` 创建的磁盘映像的卷名(即打开的 `.dmg ` 文件的窗口标题中显示的文本)基于运行 `macdeployqt ` 时应用程序的路径。例如,考虑以下用于为Qt Quick 应用程序创建磁盘映像的命令:

macdeployqt /Users/foo/myapp-build/MyApp.app -qmldir=/Users/foo/myapp/qml -dmg

生成的卷名称将为:

/Users/foo/myapp-build/MyApp.app

为确保卷名仅包含应用程序名称而不包含部署机器上的路径,请在同一目录下运行macdeployqt :

cd /Users/foo/myapp-build
macdeployqt MyApp.app -qmldir=/Users/foo/myapp/qml -dmg

生成的卷名称将如下所示:

MyApp.app

授权

在签名时,如果应用程序包中的 Contents/Resources/ 子目录下存在 .entitlements 文件,macdeployqt 将自动使用该子目录中找到的第一个 .entitlements 文件。为避免出现错误,请确保该文件夹中最多只包含一个 .entitlements 文件。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.