学会这些,QtIFW制作安装包不再是难题

news2024/12/23 10:33:50

一文看懂如何利用QtIFW制作安装包,小白也能看懂且学会的软件安装包制作教程;(本文不基于Qt工程)

1 前言

1.1 安装包制作工具的选择

安装程序生成工具就是将应用程序和依赖的文件打包到一个可执行的安装程序种,可以简化用户的安装流程和体验,但开发的软件依赖和配置过于繁杂的时候,制作一个安装包就特别必要,所以需要简单学习一下安装程序生成工具,以下是常见的安装程序生成工具:

  1. Inno Setup
    • 免费且开源的安装程序制作工具,适用于Windows平台。
    • 使用Pascal脚本语言编写安装程序脚本。
    • 提供了丰富的功能和灵活的自定义选项。
    • 拥有详细的文档和活跃的社区支持。
  2. NSIS (Nullsoft Scriptable Install System)
    • 免费且开源的安装程序制作工具,适用于Windows平台。
    • 使用自定义的脚本语言编写安装程序脚本。
    • 具有较小的安装包大小和快速的安装速度。
    • 社区支持广泛,有大量的插件可用。
  3. InstallShield
    • 商业的安装程序制作工具,适用于多个平台,包括Windows、Linux和macOS。
    • 提供了强大的功能和灵活的自定义选项。
    • 拥有可视化界面和向导,使得制作安装程序变得简单。
    • 文档和支持资源丰富,适用于中大型企业项目。
  4. WiX Toolset (Windows Installer XML)
    • 免费且开源的安装程序制作工具,适用于Windows平台。
    • 使用XML和自定义的脚本语言编写安装程序脚本。
    • 可以创建符合Windows Installer标准的安装程序。
    • 需要一定的学习曲线,但具备强大的灵活性和可扩展性。
  5. Advanced Installer
    • 商业的安装程序制作工具,适用于Windows平台。
    • 提供了易于使用的可视化界面和向导,使得制作安装程序变得简单。
    • 具有丰富的功能,如自动升级、数字签名等。
    • 提供文档和支持渠道。
  6. QtIFW (Qt Installer Framework)
    • 开源的安装程序制作工具,由Qt官方提供,适用于多个平台,包括Windows、Linux和macOS。
    • 使用基于XML的描述语言来配置和自定义安装程序。
    • 可以轻松创建复杂的安装程序,并具有强大的自定义能力。
    • 拥有官方的文档和示例,同时有活跃的社区支持。

这里不卖关子,就选择QtIFWQtIFW本身就是作为Qt项目的一部分开发的,框架本身使用Qt。然而,它可以用于安装所有类型的应用程序,包括(但不限于)使用Qt构建的应用程序。

而且它是跨平台且使用XML的描述语言来配置安装程序的,所以这里选择QtIFW

1.2 QtIFW概述

Qt Installer Framework(QtIFW)是一个开源的、跨平台的安装和打包工具套件,用于创建易于使用和可定制的安装程序。下面是Qt Installer Framework的详细介绍和优势:

  1. 跨平台支持:Qt Installer Framework可以在多个操作系统上运行,包括Windows、macOS和Linux,能够为不同平台创建一致的安装体验。
  2. 灵活的定制能力:Qt Installer Framework提供了丰富的定制选项,允许根据自己的需求来配置安装程序的外观和行为。可以定义自定义页面、创建预安装和后安装脚本、添加自定义图标和皮肤等,以满足特定的品牌和用户需求。
  3. 完整的安装体验:通过使用Qt Installer Framework,可以为用户提供完整的安装体验,包括选择目标安装位置、自定义组件选择、显示许可协议、执行预安装和后安装操作等。这有助于确保用户能够轻松地安装和配置应用程序。
  4. 强大的脚本支持:Qt Installer Framework支持使用脚本(如JavaScript)执行各种操作,例如文件复制、注册表编辑、环境变量设置等。这使得可以在安装过程中进行更高级的自定义和配置。
  5. 更新和升级支持:除了安装功能,Qt Installer Framework还提供了更新和升级支持。可以创建自动化的更新程序,使用户能够轻松地获取和安装新版本的应用程序。
  6. 可扩展性和社区支持:Qt Installer Framework是一个活跃的开源项目,拥有庞大的社区支持。可以通过插件系统来扩展框架的功能,并利用社区提供的丰富资源和解决方案。

2 下载安装及环境配置

  • 下载

下载地址:https://download.qt.io/official_releases/qt-installer-framework/

版本选择:选择最新的版本即可

然后根据你的操作系统选择安装包下载;

在这里插入图片描述

  • 安装

按照安装向导去操作即可,没有坑和注意事项;

在这里插入图片描述

  • 环境配置

将bin目录配置到环境变量中,这里必须添加,不然后面没办法打包;

在这里插入图片描述

3 简单使用

3.1 打包示例项目

我们先不管自己的项目;

QtIFW安装后,是提供了一些示例的项目的,我们先针对某个示例项目打包,走通流程;

  • 找到startmenu项目

QtIFW安装目录\examples\startmenu

在这里插入图片描述

  • 开始打包

进入startmenu目录;

在该目录下打开cmd窗口;

在这里插入图片描述

运行打包命令(先不管具体含义,先把流程打通,后面再看具体含义):

binarycreator -c config\config.xml -p packages README

在这里插入图片描述

如上图,没报错就说明打包成功了;

然后在我们的项目根目录下就可以看到制作好的安装包了;

在这里插入图片描述

  • 运行安装包,安装并查看效果

首先运行没问题

在这里插入图片描述

然后在开始菜单中找到README文件:

在这里插入图片描述

点击,就会打开这个readme文件;

在这里插入图片描述

大功告成啦!!!

3.2 分析示例项目结构

整个的目录结构应该就是如下的一个情况:

examples/
└── startmenu/
    ├── config/
    │   └── config.xml
    ├── packages/
    │   └── org.qtproject.ifw.example/
    │       ├── data/
    │       │   └── README.txt
    │       └── meta/
    │           ├── installscript.qs
    │           └── package.xml
    ├── README
    └── startmenu.pro

在该结构中,startmenu项目包含以下文件和文件夹:

  • config/:包含配置文件相关的文件夹。
  • config.xml:定义了安装程序的设置和信息,例如安装路径、安装界面的外观、需要安装的软件包等。可以使用Qt IFW的IFWConfig工具或者手动编辑该文件。
  • packages/:是存放软件包及其描述文件的目录。每个软件包文件夹都包含一个或多个软件包,其结构如下:
-packages
    - com.vendor.root
        - data
        - meta
    - com.vendor.root.component1
        - data
        - meta
    - com.vendor.root.component1.subcomponent1
        - data
        - meta
    - com.vendor.root.component2
        - data
        - meta
  • org.qtproject.ifw.example/:示例软件包的目录。
  • data/这一个存是放着软件包的安装文件的目录,这些文件将被复制到用户计算机上的目标路径。【这是最重要的目录,目标软件所有的可执行程序以及依赖等都放到这个文件夹下,QtIFW才能针对这个软件进行安装包制作】
  • meta/:包含安装程序的元数据文件,通常包含安装脚本文件、许可协议文件、安装程序的图标文件等等,后续在具体的配置讲解中会提到;
  • installscript.qs:安装脚本文件,定义了安装过程,包括安装前的准备工作、安装期间的操作以及安装完成后的清理工作等。使用IFWConfig工具创建安装程序时,会自动生成安装脚本文件;手动创建安装程序时,需要自己编写安装脚本文件。
  • ``package.xml`:描述了要安装的软件包和组件,例如库文件、可执行文件、帮助文档等。也可以使用IFWConfig工具或者手动编辑该文件。
  • README:项目的说明文档,包含有关项目、安装程序和开发细节的其他信息(这个文件对于QtIFW的使用是可有可无的)。
  • startmenu.pro:项目的Qt工程文件(后续我们不做Qt工程,这个文件可以不用管)。

总结一下,根目录下两个文件夹;

config文件夹里面配置安装包的设置和信息;

packages文件夹内是一个或多个软件包;

每个软件包目录下有一个data和一个meta目录;

meta放的是安装包的元数据;

data放的是待打包的全量文件(可执行程序及依赖);

当然这个目录并不是定死的,需要根据项目实际情况进行甄别;

3.3 打包命令详解

  • 先看看刚才我们用的命令
binarycreator -c config\config.xml -p packages README

binarycreator:这不用多说;

-c config\config.xml:指定配置文件config.xml的路径;

-p packages:指定包含要添加到安装程序的组件的目录路径。也就是指定软件包在哪里

README:指定安装包名称;

  • 进阶用法
binarycreator [options] -c config.xml -p packages path/to/output/installer

[options]:用于指定命令的其他选项。常见的选项包括:

  • --platform <platform>:指定目标平台(例如,win32-msvc2019maclinux)。

  • --offline-only:指定仅创建离线安装程序,不从互联网下载任何组件。

  • --online-only:指定仅创建在线安装程序,从互联网下载所有组件。

  • --no-sdk:指定不包含Qt开发工具包(SDK)。

  • --no-force-overwrite:指定如果目标文件已存在,则不覆盖它。

  • --no-system-detection:指定不检测系统信息。

  • --verbose:显示详细的日志输出。

  • --help:显示命令的帮助信息。

-c config.xml:指定配置文件 config.xml 的路径。
-p packages:指定包含要添加到安装程序的组件的目录路径。
path/to/output/installer:指定生成的安装程序的输出路径和名称。可以指定一个文件路径,作为最终生成的安装程序的存储位置和名称。上面我们执行的命令中,只指定了名称,就生成在了项目根目录下

  • 结合上面的项目结构看看

config目录没问题;

packages目录就有点问题了,因为上面说了,这个目录下可以放多个软件包,那么如果有多个软件包在目录下怎么打包呢?

默认情况下,Qt Installer Framework(qtifw)不会为每个软件包生成单独的安装程序。它将所有软件包组合到一个统一的安装程序中,用户可以选择安装其中的哪些软件包。

如果要打包指定的安装包,可以在命令中指定:

binarycreator  -c config.xml -p packages installer --component Package2

使用了--component Package2选项来指定只打包Package2软件包。

另外,如果要将所有的软件包都分别打包,可以在config.xml中指定,具体使用参考后面的配置编写教程;

4 进阶教程

4.1 最终安装包工作流程

下图就是我们制作好的安装包默认的安装过程;

介绍页面、选择安装文件夹、选择安装的组件、许可协议、选择设置开始菜单快捷方式、安装;

在这里插入图片描述

也就是下图中的几个主要的步骤;

在这里插入图片描述

4.2 编写配置文件

4.2.1 config.xml
  • 典型的配置文件

以下就是一个典型的config.xml文件内容

<?xml version="1.0"?>
<Installer>
    <Name>Some Application</Name>
    <Version>1.0.0</Version>
    <Title>Some Application Setup</Title>
    <Publisher>Your Company</Publisher>
    <ProductUrl>http://www.your-fantastic-company.com</ProductUrl>
    <InstallerWindowIcon>installericon</InstallerWindowIcon>
    <InstallerApplicationIcon>installericon</InstallerApplicationIcon>
    <Logo>logo.png</Logo>
    <Watermark>watermark.png</Watermark>
    <RunProgram>@TargetDir@/YourAppToRun</RunProgram>
    <RunProgramArguments>
        <Argument>Argument 1</Argument>
        <Argument>Argument 2</Argument>
    </RunProgramArguments>
    <RunProgramDescription>My nice application</RunProgramDescription>
    <StartMenuDir>Some Application Entry Dir</StartMenuDir>
    <MaintenanceToolName>SDKMaintenanceTool</MaintenanceToolName>
    <AllowNonAsciiCharacters>true</AllowNonAsciiCharacters>
    <Background>background.png</Background>

    <TargetDir>@HomeDir@/testinstall</TargetDir>
    <AdminTargetDir>@RootDir@/testinstall</AdminTargetDir>
    <RemoteRepositories>
        <Repository>
            <Url>http://www.your-repo-location/packages/</Url>
        </Repository>
    </RemoteRepositories>
</Installer>

部分元素的简单说明如下,更多详细的内容和使用方法见官网:配置文件 |Qt安装程序框架手册

元素说明
Name要安装的产品的名称,必填项;
Version要安装的产品的版本采用以下格式: [0-9]+((.|-)[0-9]+)* 例如 1-1; 1.2-2; 3.4.7;必填项.
Title安装程序标题栏上显示的名称;
Publisher软件的发行人(如 Windows 控制面板中所示)。
ProductUrl产品网址,指向产品信息的页面的URL。
InstallerApplicationIcon安装包图标的文件名,通过附加“.icns”(macOS)“.ico”(Windows)后缀来查找实际文件。在Unix上不适用
InstallerWindowIcon用于安装程序应用程序的自定义窗口图标的文件名,使用PNG格式。仅在Windows和Linux上使用,在macOS上不适用。
Logo标志的图片;
WatermarkPNG格式水印的图片,如果要显示的话,需要加上<WizardShowPageList>false</WizardShowPageList>
Banner横幅图片配置,但是WizardStyle必须设置为Modern
Background设置背景图片,但是WizardStyle必须设置为Mac,需要保证<WizardShowPageList>false</WizardShowPageList>
PageListPixmap设置左侧指引上面的图片,需要保证<WizardShowPageList>true</WizardShowPageList>
WizardStyle设置向导页面的整体样式(“Modern”, “Mac”, “Aero” or “Classic”);
StyleSheet设置样式表文件;
WizardDefaultWidth设置向导的默认宽度(以像素为单位)。设置横幅图像将覆盖此设置;
WizardDefaultHeight设置向导的默认高度(以像素为单位),设置水印图像将覆盖这一点;
WizardMinimumWidth设置向导的最小宽度(以像素为单位);
WizardMinimumHeight设置向导的最小高度(以像素为单位);
WizardShowPageList控制是否显示左侧列出安装程序页面的小组件;
ProductImages产品图片的配置;
TitleColor设置标题和副标题的颜色(采用 HTML 颜色代码,例如“#88FF33”);
RunProgram如果用户接受操作,则在安装程序完成后执行命令。提供应用程序的完整路径;
RunProgramArguments传递给指定的程序的参数。可以添加多个子元素,每个子元素都指定一个参数;
RunProgramDescription在用于在安装后运行程序的复选框旁边显示的文本。如果已设置但未提供说明,则会显示 UI;
StartMenuDirWindows 菜单中产品的默认程序组的名称;
TargetDir用于安装的默认目标目录。在 Linux 上,这通常是用户的主目录;
AdminTargetDir具有管理员权限的安装的默认目标目录。仅在 Linux 上可用,您通常不希望在管理员用户的主目录中安装;
LocalCacheDir用于存储元数据缓存的目录名称。这不包括前导目录,前导目录是根据用于存储缓存文件的合适平台特定位置自动确定的。用户可以覆盖安装程序设置中的路径。默认值是根据要安装的产品的名称生成的 UUID;
PersistentLocalCache设置为安装程序退出时是否应从本地缓存中删除提取的元数据。否则,将保留缓存的内容以加快后续提取速度;
RemoteRepositories远程存储库列表。此元素可以包含多个子元素,每个子元素都包含指定访问存储库的 URL 的子元素。有关更多信息,请参阅配置存储库;
RepositoryCategories可以包含子元素列表的类别的名称。有关更多信息,请参阅配置存储库类别;
MaintenanceToolName生成的维护工具的文件名。默认为维护工具。将追加特定于平台的可执行文件扩展名;
MaintenanceToolIniFile生成的维护工具配置的文件名;
MaintenanceToolAlias将创建到应用程序目录的维护工具别名的文件名。自选。仅在 macOS 上使用;
RemoveTargetDir设置为卸载时不应删除目标目录;
AllowNonAsciiCharacters控制安装路径是否可以包含非ASCII字符;

安装好后,windows系统可以在控制面板中查看配置的详情;

如下,更多的内容去试试就知道啦!

在这里插入图片描述

4.2.2 package.xml

这是软件包信息配置文件:

<?xml version="1.0"?>
<Package>
    <DisplayName>QtGui</DisplayName>
    <Description>Qt gui libraries</Description>
    <Description xml:lang="de_de">Qt GUI Bibliotheken</Description>
    <Version>1.2.3</Version>
    <ReleaseDate>2009-04-23</ReleaseDate>
    <Name>com.vendor.root.component2</Name>
    <Dependencies>com.vendor.root.component1</Dependencies>
    <Virtual>false</Virtual>
    <Licenses>
        <License name="License Agreement" file="license.txt" />
    </Licenses>
    <Script>installscript.qs</Script>
    <UserInterfaces>
        <UserInterface>specialpage.ui</UserInterface>
        <UserInterface>errorpage.ui</UserInterface>
    </UserInterfaces>
    <Translations>
        <Translation>sv_se.qm</Translation>
        <Translation>de_de.qm</Translation>
    </Translations>
    <DownloadableArchives>component2.7z, component2a.7z</DownloadableArchives>
    <AutoDependOn>com.vendor.root.component3</AutoDependOn>
    <SortingPriority>123</SortingPriority>
    <UpdateText>This changed compared to the last release</UpdateText>
    <Default>false</Default>
    <ForcedInstallation>false</ForcedInstallation>
    <ForcedUpdate>false</ForcedUpdate>
    <Essential>false</Essential>
    <Replaces>com.vendor.root.component2old</Replaces>
    <Operations>
        <Operation name="AppendFile">
            <Argument>@TargetDir@/A.txt</Argument>
            <Argument>lorem ipsum</Argument>
        </Operation>
        <Operation name="Extract">
            <Argument>@TargetDir@/Folder1</Argument>
            <Argument>content.7z</Argument>
        </Operation>
        <Operation name="Extract">
            <Argument>@TargetDir@/Folder2</Argument>
        </Operation>
    </Operations>
    <TreeName moveChildren="true">com.vendor.subcomponent</TreeName>
</Package>
  • 部分元素及说明如下,详细的参考官网
  1. <DisplayName>:指定软件包的显示名称为"QtGui"。
  2. <Description>:提供了一个关于软件包的描述信息,指出它是Qt图形用户界面库。
  3. <Description xml:lang="de_de">:为了国际化支持,该元素提供了一个德语版本的描述信息。
  4. <Version>:指定软件包的版本号为"1.2.3"。
  5. <ReleaseDate>:指定软件包的发布日期为"2009-04-23"。
  6. <Name>:指定软件包的唯一标识符为"com.vendor.root.component2"。
  7. <Dependencies>:指定软件包依赖的其他软件包,这里依赖"com.vendor.root.component1"。
  8. <Virtual>:指示软件包是否是虚拟包,即实际上没有提供任何文件。
  9. <Licenses>:定义许可证信息,这里提供了一个名为"License Agreement"的许可证文件"license.txt"。
  10. <Script>:指定安装脚本文件为"installscript.qs"。
  11. <UserInterfaces>:定义用户界面文件,这里列出了两个界面文件"specialpage.ui"和"errorpage.ui"。
  12. <Translations>:定义翻译文件,这里列出了两个翻译文件"sv_se.qm"和"de_de.qm"。
  13. <DownloadableArchives>:指定可下载的存档文件,这里有两个文件"component2.7z"和"component2a.7z"。
  14. <AutoDependOn>:指定软件包自动依赖的其他软件包,这里自动依赖"com.vendor.root.component3"。
  15. <SortingPriority>:指定软件包的排序优先级为123。
  16. <UpdateText>:提供软件包更新时的文本描述,指出与上一个版本相比的更改内容。
  17. <Default>:指示软件包是否作为默认选择。
  18. <ForcedInstallation>:指示软件包是否要求强制安装。
  19. <ForcedUpdate>:指示软件包是否要求强制更新。
  20. <Essential>:指示软件包是否是必需的。
  21. <Replaces>:指定该软件包可以替代的旧版本软件包"com.vendor.root.component2old"。
  22. <Operations>:定义操作列表,包括"AppendFile"和两个"Extract"操作,用于在安装过程中执行特定的文件操作。
  23. <TreeName moveChildren="true">:指定组件树的名称为"com.vendor.subcomponent",并设定其子组件是否移动。
4.2.3 installscript.qs

官网地址:https://doc.qt.io/qtinstallerframework/scripting.html

推荐博客:http://t.csdn.cn/xrqn6

installscript.qs是一个用于安装程序的脚本文件,它使用了Qt Installer Framework提供的安装脚本语言。在这个脚本中,可以定义需要执行的操作来完成安装过程。

function Component()
{
    // 添加操作函数
    function addOperation(op)
    {
        installer.addOperation(op);
    }

    // 组件名称
    this.componentName = "MyApp";
    // 组件版本号
    this.componentVersion = "1.0.0";

    // 开始安装前的初始化操作
    this.installationStarted = function()
    {
        console.log("Installation started");
    }

    // 条件判断
    if (systemInfo.productType === "windows")
    {
        // Windows平台特定操作
        var startMenuDir = installer.value("StartMenuDir");
        var shortcutPath = startMenuDir + "\\MyApp.lnk";
        addOperation("CreateShortcut", "@TargetDir@/MyApp.exe", shortcutPath);
    }
    else if (systemInfo.productType === "osx")
    {
        // macOS平台特定操作
        var applicationsDir = installer.value("ApplicationsDir");
        var shortcutPath = applicationsDir + "/MyApp.app";
        addOperation("CopyDirectory", "@TargetDir@/MyApp.app", shortcutPath);
    }

    // 结束安装后的清理操作
    this.installationFinished = function()
    {
        console.log("Installation finished");
    }
}

// 创建组件实例
var component = new Component();

  1. componentNamecomponentVersion:用于定义组件的名称和版本号。
  2. installationStarted:在安装开始前被调用的函数,可以用于执行一些初始化操作。
  3. 条件判断:根据systemInfo.productType的值(表示当前的操作系统类型)进行条件判断,针对不同的平台进行不同的操作。
  4. 操作函数:addOperation是一个辅助函数,用于添加操作到安装脚本中。它接收一个或多个参数,这些参数定义了需要执行的操作及其参数。
  5. 结束安装后的清理操作:installationFinished是在安装完成后被调用的函数,可以用于执行一些清理操作。

在示例中,根据平台类型执行了不同的操作。对于Windows平台,使用CreateShortcut操作创建了一个名为MyApp.lnk的快捷方式,指向@TargetDir@/MyApp.exe;对于macOS平台,则通过CopyDirectory操作将@TargetDir@/MyApp.app复制到Applications目录下。

可以根据实际需求,通过添加其他操作函数来执行更多的操作,如复制文件、创建目录、注册表项等。

更高级的一些操作,需要结合实际需求来看怎么配置;

下面这个是上面演示的项目的文件的代码注释:

function Component() {
    // 默认构造函数
}

Component.prototype.createOperations = function() {
    // 调用默认实现来安装 README.txt!
    component.createOperations();

    if (systemInfo.productType === "windows") {
        component.addOperation(
            "CreateShortcut",
            "@TargetDir@/README.txt", // 快捷方式目标文件路径
            "@StartMenuDir@/jmz.lnk", // 快捷方式创建位置
            "workingDirectory=@TargetDir@", // 工作目录
            "iconPath=%SystemRoot%/system32/SHELL32.dll", // 图标文件路径
            "iconId=2", // 图标索引
            "description=Open README file" // 描述信息
        );
    }
}

5 完整示例

5.1 新建一个项目目录

类似上面提到的结构,新建一个目录,以及一些必要的文件;

这边我创建的目录如下:

test/
└── calculator/
    ├── config/
    │   └── config.xml
    └── packages/
        └── installer_1/
            ├── data/
            │   └── 现在为空
            └── meta/
                ├── installscript.qs
                └── package.xml

5.2 复制可执行程序到data目录

就是把打包好的文件全部放到data目录下;

至于怎么打包,这里不过多叙述,可以看看我另外一篇关于python打包gui程序的博客;

在这里插入图片描述

5.3 编写config.xml

<?xml version="1.0" encoding="UTF-8"?>
<Installer>
    <Name>九陌斋计算器</Name>
    <Version>1.0.0</Version>
    <Title>九陌斋计算器</Title>
    <Publisher>九陌斋</Publisher>
	<ProductUrl>https://blog.jiumoz.com</ProductUrl>
	<InstallerApplicationIcon>favicon</InstallerApplicationIcon>
	<InstallerWindowIcon>app.png</InstallerWindowIcon>
	<Logo>logo.png</Logo>
    <TargetDir>@ApplicationsDir@/九陌斋计算器</TargetDir>
	<AllowNonAsciiCharacters>true</AllowNonAsciiCharacters>
	<WizardStyle>Mac</WizardStyle>
	<StartMenuDir>九陌斋计算器</StartMenuDir>
</Installer>
  • <Name>: 指定安装程序的名称为"九陌斋计算器"。
  • <Version>: 指定安装程序的版本号为"1.0.0"。
  • <Title>: 指定安装程序对话框的标题为"九陌斋计算器"。
  • <Publisher>: 指定发布者为"九陌斋"。
  • <ProductUrl>: 指定产品的网址为"https://blog.jiumoz.com"。
  • <InstallerApplicationIcon>: 指定安装程序的应用图标为"favicon.ico",这里后缀要省略。
  • <InstallerWindowIcon>: 指定安装程序对话框的窗口图标为"app.png"。
  • <Logo>: 指定安装程序对话框中显示的Logo为"app.png"。
  • <TargetDir>: 指定安装程序的目标安装目录为"@ApplicationsDir@/九陌斋计算器",即在应用程序目录下创建一个名为"九陌斋计算器"的文件夹。
  • <AllowNonAsciiCharacters>: 允许在安装程序对话框中使用非ASCII字符。
  • <WizardStyle>: 设置安装程序对话框的风格为"Mac",类似于 macOS 风格。
  • <StartMenuDir>: 指定在开始菜单中创建一个名为"九陌斋计算器"的文件夹。

这里我们要把要用到的文件也放到config目录下:

这里要注意一下,QtIFW里面好像所有的图片都不能用两次,比如<InstallerWindowIcon>app.png</InstallerWindowIcon><Logo>logo.png</Logo>,图片其实是一个,但是也要复制重命名一下,不然会报错,没有过多的研究,知道的同学可以留言交流一下

在这里插入图片描述

5.4 编写package.xml

<?xml version="1.0" encoding="UTF-8"?>
<Package>
    <DisplayName>九陌斋计算器</DisplayName>
    <Description>基于PySide6的简单计算器程序,还存在一些bug,敬请担待!</Description>
    <Version>1.0.0</Version>
    <ReleaseDate>2023-09-27</ReleaseDate>
	<Name>installer_1</Name>
    <Licenses>
        <License name="九陌斋计算器安装协议" file="license.txt" />
    </Licenses>
    <Script>installscript.qs</Script>
</Package>

  • <DisplayName>: 指定软件包的显示名称为"九陌斋计算器"。

  • <Description>: 指定软件包的描述为"基于PySide6的简单计算器程序,还存在一些bug,敬请担待!"。

  • <Version>: 指定软件包的版本号为"1.0.0"。

  • <ReleaseDate>: 指定软件包的发布日期为"2023-09-27"。

  • <Name>: 指定软件包的名称为"installer_1"。

  • <Licenses>: 指定软件包的许可证信息。

  • <License>: 指定软件包的许可证名称为"九陌斋计算器安装协议",并指定许可证文件为"license.txt"。

  • <Script>: 引用安装脚本文件installscript.qs。

这里我们要新建一个协议文档放到meta目录下,并写一些简单的内容:

在这里插入图片描述

5.5 编写installscript.qs


function Component()
{
    // default constructor
}

Component.prototype.createOperations = function()
{
    component.createOperations(); 
    if (systemInfo.productType === "windows") 
	{
		
		//开始菜单快捷方式
        component.addOperation(
		"CreateShortcut", 
		"@TargetDir@/calculator.exe",
		"@StartMenuDir@/九陌斋计算器.lnk",
		"workingDirectory=@TargetDir@",
		"iconPath=@TargetDir@/favicon.ico",
		"description=打开九陌斋计算器"
		);
 
        //桌面快捷方式
		component.addOperation(
		"CreateShortcut",
		"@TargetDir@/calculator.exe",
		"@DesktopDir@/九陌斋计算器.lnk",
		"workingDirectory=@TargetDir@",
		"iconPath=@TargetDir@/favicon.ico",
		);
    }
}

这段代码中包含两个快捷方式创建操作,分别是开始菜单快捷方式和桌面快捷方式。每个操作都接受相应的参数来定义快捷方式的属性,如目标文件路径、快捷方式路径、工作目录、图标路径和描述。

需要注意的是,在开始菜单快捷方式操作中,设置了一个自定义的快捷方式名称,即"九陌斋计算器.lnk"。如果需要更改为其他名称,请将"@StartMenuDir@/九陌斋计算器.lnk"中的字符串部分替换为所需的名称。

另外,在桌面快捷方式操作中省略了描述的设置,如果需要添加描述,可以类似开始菜单快捷方式操作那样添加"description=xxx"参数。

这里的配置还是很简单的,就是写了两个快捷方式的添加;

其余的可以进一步跟进实际需求探索;

5.5 运行命令开始打包

binarycreator -c config\config.xml -p packages 九陌斋计算器 -v

后面加-v能查看详细日志

正常只要没报错,就打包成功了;

在这里插入图片描述

查看一下根目录:

nice,大功告成;

在这里插入图片描述

5.6 检验成果

  • 双击运行

在这里插入图片描述

  • 一路往下走,安装完成后查看安装情况:

  • 快捷方式都没问题;

在这里插入图片描述

  • 控制面板查看软件信息没问题

在这里插入图片描述

  • 运行软件没问题

在这里插入图片描述

ok,本文到这里就结束啦,希望你有所收获,欢迎留言交流~


原文链接:https://blog.jiumoz.com/archives/xue-hui-zhe-xie-qtifw-zhi-zuo-an-zhuang-bao-bu-zai-shi-nan-ti

欢 迎 关 注 博 主 个 人 小 程 序!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1051398.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML之如何下载网页中的音频(二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

【算法】莫队

这篇博客起源于本人把一道 p o w ( 2 , n ) pow(2,n) pow(2,n) 的问题考虑成求组合数前缀和的问题qwq&#xff0c;于是接触到了这个新算法来总结一下 参考自这篇文章&#xff0c;写得太好了 首先是一道模板题 题目意思是&#xff0c;给出一个数组a&#xff0c;再给出多个区…

What is an HTTP Flood DDoS attack?

HTTP 洪水攻击是一种针对 Web 和应用程序服务器的第 7 层分布式拒绝服务 &#xff08;DDoS&#xff09; 攻击。HTTP 洪水攻击通过使用 HTTP GET 或 HTTP POST 请求执行 DDoS 攻击。这些请求是有效的&#xff0c;并且针对可用资源&#xff0c;因此很难防范 HTTP 洪水攻击。 匿名…

特斯拉——使用人工智能制造智能汽车

特斯拉(Tesla)是电动汽车开发和推广的先驱。特斯拉对自动驾驶汽车的未来寄予厚望--实际上&#xff0c;每一辆特斯拉汽车都有可能通过软件升级成为自动驾驶汽车。该公司还生产和销售高级电池和太阳能电池板。 汽车的自动驾驶是按从1~5的等级划分的。自适应巡航控制和自动停车系…

论文笔记(整理):轨迹相似度顶会论文中使用的数据集

0 汇总 数据类型数据名称数据处理出租车数据波尔图 原始数据&#xff1a;2013年7月到2014年6月&#xff0c;170万条数据 ICDE 2023 Contrastive Trajectory Similarity Learning with Dual-Feature Attention 过滤位于城市&#xff08;或国家&#xff09;区域之外的轨迹 过…

【SSL】用Certbot生成免费HTTPS证书

1. 实验背景 服务器&#xff1a;CentOS7.x 示例域名&#xff1a; www.example.com 域名对应的web站点目录&#xff1a; /usr/local/openresty/nginx/html 2. 安装docker # yum -y install yum-utils# yum-config-manager --add-repo https://download.docker.com/linux/ce…

采集SEO方法-优化内链与外链建设

采集大量的文章数据&#xff0c;要想批量做SEO优化添加内链外链方法&#xff0c;可以使用简数采集器的处理规则实现。 简数采集器的一个处理规则&#xff0c;可以包含多种SEO方法&#xff0c;还可自由组合&#xff0c;强大灵活方便。 优化内链外链的SEO技巧&#xff1a; 1&a…

基于PYQT5的GUI开发系列教程【二】QT五个布局的介绍与运用

目录 本文概述 作者介绍 创建主窗口 水平布局 垂直布局 栅格布局 分裂器水平布局 分裂器垂直布局 自由布局 取消原先控件的布局的方法 尾言 本文概述 PYQT5是一个基于python的可视化GUI开发框架&#xff0c;具有容易上手&#xff0c;界面美观&#xff0c;多平台…

基于SpringBoot的教学资源库系统的设计与实现

目录 前言 一、技术栈 二、系统功能介绍 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 社会的进步&#xff0c;教育行业发展迅速&#xff0c;人们对教育越来越重视&#xff0c;在当今网络普及的情况下&#xff0c;教学模式也开始逐渐网络化&#xff0c;各大…

Python大数据之Python进阶(四)进程的注意点

文章目录 进程的注意点1. 进程的注意点介绍2. 进程之间不共享全局变量3. 进程之间不共享全局变量的小结4. 主进程会等待所有的子进程执行结束再结束5. 主进程会等待所有的子进程执行结束再结束的小结 进程的注意点 学习目标 能够说出进程的注意点 1. 进程的注意点介绍 进程之…

Polygon Miden交易模型:Actor模式 + ZKP => 并行 + 隐私

1. 引言 前序博客&#xff1a; Polygon Miden&#xff1a;扩展以太坊功能集的ZK-optimized rollupPolygon Miden zkRollup中的UTXO账户混合状态模型 Polygon Miden为&#xff1a; ZK-optimized rollup由客户端生成证明完善Polygon ZK系列解决方案&#xff0c;致力于成为网络…

nodejs+vue网上婚纱购物系统elementui

便了用户足不出门也能进行购物的理念&#xff0c;方便了婚纱影楼的对商品的进一步管理,互联网成为人们快速获取、发布、和传递信息的重要渠道&#xff0c;它在人们政治、经济、生活等各个方面发挥着重要的作用。未来的时代是网络信息的时代&#xff0c;“网上生活方式”是人类今…

软件测试面试复盘

作者&#xff1a;爱塔居 专栏&#xff1a;测试 1、计算机网络七层协议&#xff1a;物理层、数据链路层、网络层、传输层、表示层、会话层、应用层&#xff08;面试问过这个&#xff09; 2.TCP/IP四层模型&#xff1a;应用层、传输层、网络层、网络接口层&#xff08;笔试问过&…

【CMU15-445 Part-14】Query Planning Optimization I

Part14-Query Planning & Optimization I SQL is Declarative&#xff0c;只告诉想要什么而不需要说怎么做。 IBM System R是第一个实现query optimizer查询优化器的系统 Heuristics / Rules 条件触发 静态规则&#xff0c;重写query来remove 低效或者愚蠢的东西&#xf…

基于springboot的洗衣店订单管理系统

目录 前言 一、技术栈 二、系统功能介绍 顾客信息管理 店家信息管理 店铺信息管理 洗衣信息管理 预约功能 洗衣信息 交流区 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息互联网信息的飞速发展&#xff0c;无纸化作业变成了一种趋势&#x…

Springboot中使用拦截器、过滤器、监听器

一、Servlet、Filter&#xff08;过滤器&#xff09;、 Listener&#xff08;监听器&#xff09;、Interceptor&#xff08;拦截器&#xff09; Javaweb三大组件&#xff1a;servlet、Filter&#xff08;过滤器&#xff09;、 Listener&#xff08;监听器&#xff09; Spring…

7.2 怎样定义函数

7.2.1 为什么要定义函数 主要内容&#xff1a; 为什么要定义函数 C语言要求所有在程序中用到的函数必须“先定义&#xff0c;后使用”。这是因为在调用一个函数之前&#xff0c;编译系统需要知道这个函数的名字、返回值类型、功能以及参数的个数与类型。如果没有事先定义&…

400G DR4 QSFP-DD光模块:数据中心应用全攻略

在当今数字化时代&#xff0c;对于企业和供应商来说&#xff0c;高速数据传输至关重要。随着对更快数据传输的需求不断攀升&#xff0c;400G DR4 QSFP-DD光模块已经成为高速网络的最新解决方案。本文将全面介绍400G DR4 QSFP-DD光模块在数据中心应用中的优势和技术规范。 什么…

基于Java的校园体育赛事竞赛管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

性能分析-java虚拟机性能监控

虚拟机性能监控 给一个系统定位问题的时候&#xff0c;知识、经验是关键基础&#xff0c;数据是依据&#xff0c;工具是运用知识处理数据的手段。这里说的数据包括&#xff1a;运行日志、异常堆栈、GC日志、线程快照&#xff08;threaddump/javacore文件&#xff09;、堆转储快…