【Qt IFW】 覆盖安装向导制作

需求:

给qt编写的桌面软件制作安装向导,检测安装路径,覆盖安装

软件主程序下有OpenVino、python 2个子模块,可选安装

安装Qt IFW

download:Index of /official_releases/qt-installer-framework

Qt Installer Framework Manual:Qt Installer Framework Manual

目录结构说明

总体结构

建立目录结构如下:

  • HyperVisionIFW:项目名称
  • docs:存放文档
  • V0.4.2: 区分不同版本(由D:\Qt\QtIFW-4.2.0\examples\startmenu修改而来)

config目录


config.xml 必要文件

<?xml version="1.0" encoding="UTF-8"?>
<Installer>
    <Name>HyperVision</Name>
    <Version>0.4.2</Version>
    <Title>HyperVision安装向导</Title>
    <Publisher>CZTEK</Publisher>
    <!-- Directory name is used in component.xml -->
    <StartMenuDir>HyperVision0.4.2</StartMenuDir>
    <TargetDir>@ApplicationsDirX64@/CZTEK/HyperVision0.4.2</TargetDir>
    <WizardStyle>Classic</WizardStyle>
    <StyleSheet>style.qss</StyleSheet>
    <TitleColor>#FFFFFF</TitleColor>
    <Logo>logo45.png</Logo>
</Installer>

字段含义见:Configuration File | Qt Installer Framework Manual

style.qss 界面样式表

QWidget
{
    color: white;
    background-color: rgb(65, 65, 65);
}
​
QPushButton
{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(150, 150, 150, 60%), stop:1 rgba(50, 50, 50, 60%));
    border-color: rgb(60, 60, 60);
    border-style: solid;
    border-width: 2px;
    border-radius: 9px;
    min-height: 20px;
    max-height: 20px;
    min-width: 60px;
    max-width: 60px;
    padding-left: 15px;
    padding-right: 15px;
}
​
QPushButton:pressed, QPushButton:checked
{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(50, 50, 50, 60%), stop:1 rgba(150, 150, 150, 60%));
}


packages目录

根据自己项目实际情况划分模块

root.openvino表示为root的子模块

每个组件下包含data、meta 2个文件夹

data下存放需要打包的exe、dll、其他文件

meta下存放安装脚本、UI、组件配置信息

对应界面如下:

root

  • data

./data/script/uninstallscript.qs 卸载脚本,自动点击maintenancetool界面next按钮

// 卸载脚本:如果程序已安装,则会调用 maintenance 工具,自动进行卸载。
function Controller()
{
    gui.clickButton(buttons.NextButton);
    gui.clickButton(buttons.NextButton);
 
    // 连接信号槽
    installer.uninstallationFinished.connect(this, this.uninstallationFinished);
}
 
// 当卸载完成时,触发
Controller.prototype.uninstallationFinished = function()
{
    gui.clickButton(buttons.NextButton);
}
 
// 与完成页面上的部件交互
Controller.prototype.FinishedPageCallback = function()
{
    gui.clickButton(buttons.FinishButton);
}
  • meta

 ./meta/package.xml

<?xml version="1.0" encoding="UTF-8"?>
<Package>
    <DisplayName>HyperVision</DisplayName>
    <Description>主程序</Description>
    <Version>0.5.2</Version>
    <ReleaseDate>2022-02-18</ReleaseDate>
    <Default>true</Default>
    <Script>installscript.qs</Script>
    <UserInterfaces>
        <UserInterface>targetwidget.ui</UserInterface>
    </UserInterfaces>
</Package>

./meta/installscript.qs 安装脚本,创建快捷方式,覆盖安装

var targetDirectoryPage = null;
 
// default constructor
function Component()
{
    installer.gainAdminRights();
    component.loaded.connect(this, this.installerLoaded);
}
 
// 实用函数,类似于 QString QDir::toNativeSeparators()
var Dir = new function () {
    this.toNativeSparator = function (path) {
        if (installer.value("os") == "win")
            return path.replace(/\//g, '\\');
        return path;
    }
};
 
Component.prototype.createOperations = function()
{
    try 
    {
        // call default implementation to actually install README.txt!
        component.createOperations();
 
        if (systemInfo.productType === "windows") 
        {
            //开始菜单快捷方式
            component.addOperation("CreateShortcut",               
                                   "@TargetDir@/HyperVision.exe",    
                                   "@StartMenuDir@/HyperVision.lnk",
                                   "workingDirectory=@TargetDir@");
     
            //桌面快捷方式
            component.addOperation("CreateShortcut",
                                   "@TargetDir@/HyperVision.exe",
                                   "@DesktopDir@/HyperVision.lnk",
                                   "workingDirectory=@TargetDir@");
        }    
    }catch (e) {
        print(e);
    }
}
 
// 加载组件后立即调用
Component.prototype.installerLoaded = function()
{
    installer.setDefaultPageVisible(QInstaller.TargetDirectory, false);
    installer.addWizardPage(component, "TargetWidget", QInstaller.TargetDirectory);
 
    targetDirectoryPage = gui.pageWidgetByObjectName("DynamicTargetWidget");
    targetDirectoryPage.windowTitle = "选择安装目录";
    targetDirectoryPage.description.setText("请选择程序的安装位置:");
    targetDirectoryPage.targetDirectory.textChanged.connect(this, this.targetDirectoryChanged);
    targetDirectoryPage.targetDirectory.setText(Dir.toNativeSparator(installer.value("TargetDir")));
    targetDirectoryPage.targetChooser.released.connect(this, this.targetChooserClicked);
 
    gui.pageById(QInstaller.ComponentSelection).entered.connect(this, this.componentSelectionPageEntered);
}
 
// 当点击选择安装位置按钮时调用
Component.prototype.targetChooserClicked = function()
{
    var dir = QFileDialog.getExistingDirectory("", targetDirectoryPage.targetDirectory.text);
    if (dir != "") {
        targetDirectoryPage.targetDirectory.setText(Dir.toNativeSparator(dir));
    }
}
 
// 当安装位置发生改变时调用
Component.prototype.targetDirectoryChanged = function()
{
    var dir = targetDirectoryPage.targetDirectory.text;
    if (installer.fileExists(dir) && installer.fileExists(dir + "/HyperVision.exe")) {
        targetDirectoryPage.warning.setText("<p style=\"color: red\">检测到程序已安装,继续将会被覆盖。</p>");
    } else {
        targetDirectoryPage.warning.setText("");
    }
    installer.setValue("TargetDir", dir);
}
 
// 当进入【选择组件】页面时调用
Component.prototype.componentSelectionPageEntered = function()
{
    var dir = installer.value("TargetDir");
    if (installer.fileExists(dir) && installer.fileExists(dir + "/maintenancetool.exe")) {
        installer.execute(dir + "/maintenancetool.exe", "--script=" + dir + "/script/uninstallscript.qs");
    }
}

./meta/targetwidget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>TargetWidget</class>
 <widget class="QWidget" name="TargetWidget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>491</width>
    <height>190</height>
   </rect>
  </property>
  <property name="sizePolicy">
   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
    <horstretch>0</horstretch>
    <verstretch>0</verstretch>
   </sizepolicy>
  </property>
  <property name="minimumSize">
   <size>
    <width>491</width>
    <height>190</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="QLabel" name="description">
     <property name="text">
      <string>description</string>
     </property>
    </widget>
   </item>
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout">
     <property name="spacing">
      <number>6</number>
     </property>
     <item>
      <widget class="QLineEdit" name="targetDirectory">
       <property name="readOnly">
        <bool>true</bool>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="targetChooser">
       <property name="text">
        <string>...</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
   <item>
    <widget class="QLabel" name="warning">
     <property name="enabled">
      <bool>true</bool>
     </property>
     <property name="text">
      <string>warning</string>
     </property>
    </widget>
   </item>
   <item>
    <spacer name="verticalSpacer">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>122</height>
      </size>
     </property>
    </spacer>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>


root.openvino

  • data

  • meta

  • ./meta/package.xml
<?xml version="1.0" encoding="UTF-8"?>
<Package>
    <DisplayName>OpenVino</DisplayName>
    <Description>深度学习工具库</Description>
    <Version>2021.4.752</Version>
    <ReleaseDate>2022-02-18</ReleaseDate>
    <Default>true</Default>
</Package>

root.python

  • data

  • meta

  • ./meta/package.xml
<?xml version="1.0" encoding="UTF-8"?>
<Package>
    <DisplayName>Python</DisplayName>
    <Description>Python解释器</Description>
    <Version>3.7</Version>
    <ReleaseDate>2022-02-18</ReleaseDate>
    <Default>true</Default>
</Package>


打包安装包

编写一个运行脚本 build.bat

D:/Qt/QtIFW-4.2.0/bin/binarycreator.exe -c ./config/config.xml -p ./packages hypervision-windows-x86-0.4.2.0222.exe -v
pause

-c 指定config路径

-p 指定包路径

双击build.bat

等待运行完毕后,生成hypervision-windows-x86-0.4.2.0222.exe

效果图


 
————————————————
转载于:https://blog.csdn.net/qq_40602000/article/details/123139346

Qt Installer Framework(Qt IFW)是用于创建安装程序的工具包。该工具包提供了一种简单但功能强大的方法来构建跨平台的安装程序。Qt IFW 不仅可以用于 Qt 应用,还可以用于任何 C++ 应用程序。 Qt IFW安装界面可以自定义,包括界面的风格、字体、背景和自定义图像。程序员可以根据自己的需求和应用程序的视觉效果来配置安装界面。Qt IFW 提供了一组默认的安装界面,包括典型的 Windows、Mac 和 Linux 风格。 安装界面的主要元素包括安装欢迎界面、许可协议界面、安装位置界面、组件选择界面和安装进度界面。安装欢迎界面提供了应用程序的简短描述和安装过程的总体摘要。许可协议界面显示了应用程序的许可协议,并要求用户同意才能继续安装安装位置界面允许用户选择安装路径,也可以在此界面上指定其他安装选项,例如创建快捷方式和应用程序的开始菜单项。组件选择界面允许用户选择要安装的组件,而且可以选择不安装某些组件。安装进度界面允许用户监视安装过程的进度,并在安装完成后提供一些可选操作。 除了默认的安装界面,Qt IFW 还支持自定义的安装界面。程序员可以使用 Qt Designer 或手动编写界面元素来创建自己的安装界面。在自定义安装界面中,程序员可以使用各种控件、图像和布局,以满足应用程序的特定需求。自定义安装界面对于需要显示特定信息或功能的应用程序非常有用。 Qt IFW安装界面是方便实用的,可以快速构建和自定义,以满足各种应用程序的需求。它提供了方便的用户界面,使用户能够轻松安装应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值