需求:
给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