控制脚本
对于每个安装程序您可以指定一个控制脚本用来与安装程序的部分UI或功能进行交互控制脚本可以在向导中添加和删除页面更改现有页面进行附加检查以及通过模拟用户单击来与UI交互例如这允许安装时无需人的参与
脚本格式必须与QJSEngine兼容
本节介绍为实现这种控制脚本而调用的函数功能它还概述了安装程序页面以及每个页面上可用的小部件例如按钮单选按钮和行编辑
编写控制脚本
最小的有效脚本至少需要包含一个构造函数如下所示:
function Controller()
{
}
以下示例显示了一个更高级的脚本该脚本使用gui JavaScript全局对象方法用于在简介页面上设置新页面标题和欢迎消息并在目标文件夹页面上自动单击下一步按钮:
function Controller()
{
}
Controller.prototype.IntroductionPageCallback = function()
{
var widget = gui.currentPageWidget(); // get the current wizard page
if (widget != null) {
widget.title = "New title."; // set the page title
widget.MessageLabel.setText("New Message."); // set the welcome text
}
}
Controller.prototype.TargetDirectoryPageCallback = function()
{
gui.clickButton(buttons.NextButton); // automatically click the Next button
}
有关可在控制脚本中使用的JavaScript全局对象的更多信息请参见Scripting API章节
预定义的安装程序页面
QInstaller JavaScript对象提供对以下预定义安装程序页面的访问:
> 介绍
> 目标文件夹
> 组件选择
> 许可证检查
> 开始菜单选择
> 准备安装
> 执行安装
> 安装完成
buttons JavaScript对象提供了一组可在安装程序页面上使用的按钮
以下各节描述了可与安装程序页面交互的用户可实现函数以及每个页面上可用的小部件
简介页面
实现Controller.prototype.IntroductionPageCallback()函数用来与简介页面上的部件进行交互
向导按钮:
> 下一步按钮
> 取消按钮
部件 | 简要描述 |
---|---|
ErrorLabel | 显示错误信息 |
MessageLabel | 显示消息默认显示"欢迎来到 |
InformationLabel | 显示进度信息 |
单选按钮 | 简要描述 |
---|---|
PackageManagerRadioButton | 包管理器单选按钮作为维护工具运行时在页面上显示 |
UpdaterRadioButton | 更新程序单选按钮作为维护工具运行时在页面上显示 |
UninstallerRadioButton | 卸载程序单选按钮作为维护工具运行时在页面上显示 |
进度条 | 简要描述 |
---|---|
InformationProgressBar | 进度条获取远程包时显示 |
Qt核心功能 | 简要描述 |
---|---|
packageManagerCoreTypeChanged() | 如果要在维护工具的类型更改时收到通知请连接到此信号 注意:仅当用户启动二进制文件即所谓的维护工具(安装后)并在单选按钮之间切换时才发出此信号 |
示例代码:
function Controller()
{
var widget = gui.pageById(QInstaller.Introduction); // get the introduction wizard page
if (widget != null)
widget.packageManagerCoreTypeChanged.connect(onPackageManagerCoreTypeChanged);
}
onPackageManagerCoreTypeChanged = function()
{
console.log("Is Updater: " + installer.isUpdater());
console.log("Is Uninstaller: " + installer.isUninstaller());
console.log("Is Package Manager: " + installer.isPackageManager());
}
许可协议页面
实现Controller.prototype.LicenseAgreementPageCallback()函数用来与许可协议页面上的部件进行交互
向导按钮:
> 下一步按钮
> 取消按钮
> 返回按钮
部件 | 简要描述 |
---|---|
LicenseListWidget | 列出可用许可证 |
LicenseTextBrowser | 显示被选择许可证内容 |
AcceptLicenseLabel | 在接受许可证单选按钮旁边显示的文本 |
RejectLicenseLabel | 在拒绝许可证单选按钮旁边显示的文本 |
单选按钮 | 简要描述 |
---|---|
AcceptLicenseRadioButton | 接收许可协议 |
RejectLicenseRadioButton | 拒绝许可协议默认选中 |
目标文件夹页面
实现Controller.prototype.TargetDirectoryPageCallback()函数用来与目标文件夹选择页面上的部件进行交互
向导按钮:
> 下一步按钮
> 取消按钮
> 返回按钮
部件 | 简要描述 |
---|---|
MessageLabel | 显示消息 |
TargetDirectoryLineEdit | 显示安装目标文件夹值 |
WarningLabel | 显示警告 |
组件选择页面
实现Controller.prototype.ComponentSelectionPageCallback()函数用来与组件选择页面上的部件进行交互
向导按钮:
> 下一步按钮
> 取消按钮
> 返回按钮
方法 | 简要描述 |
---|---|
selectAll() | 尽可能选择所有可用包 |
deselectAll() | 尽可能反选所有可用包 |
selectDefault() | 将可用包的选择状态重置为初始状态 |
selectComponent(id) | 选择具有id(string)的包 |
deselectComponent(id) | 反选具有id(string)的包 |
按钮 | 简要描述 |
---|---|
SelectAllComponentsButton | 尽可能选择所有可用包 |
DeselectAllComponentsButton | 尽可能反选所有可用包 |
SelectDefaultComponentsButton | 将可用包的选择状态重置为初始状态 |
ResetComponentsButton | 重置为已安装组件状态 |
FetchCategoryButton | 从类别中获取组件 |
部件 | 简要描述 |
---|---|
CategoryGroupBox | 包含用于选择存储库类别的复选框 |
Installer Framework 3.1引入了存储库类别作为一项新功能 使用包含存储库类别的安装程序时可以按其显示名称选择类别获取其内容然后选择包含的组件进行安装
您可以从类别中获取组件如下所示:
Controller.prototype.ComponentSelectionPageCallback = function()
{
var page = gui.pageWidgetByObjectName("ComponentSelectionPage");
// if CategoryGroupBox is visible, check one of the checkboxes
// and click fetch button before selecting any components
var groupBox = gui.findChild(page, "CategoryGroupBox");
if (groupBox) {
console.log("groupBox found");
// findChild second argument is the display name of the checkbox
var checkBox = gui.findChild(page, "Archive");
if (checkBox) {
console.log("checkBox found");
console.log("checkBox name: " + checkBox.text);
if (checkBox.checked == false) {
checkBox.click();
var fetchButton = gui.findChild(page, "FetchCategoryButton");
if (fetchButton) {
console.log("fetchButton found");
fetchButton.click();
} else {
console.log("fetchButton NOT found");
}
}
} else {
console.log("checkBox NOT found");
}
} else {
console.log("groupBox NOT found");
}
// you can now select components from the fetched category
}
开始菜单文件夹页面
实现Controller.prototype.StartMenuDirectoryPageCallback()函数用来与准备安装页面上的部件进行交互
向导按钮:
> 下一步按钮
> 取消按钮
> 返回按钮
部件 | 简要描述 |
---|---|
StartMenuPathLineEdit | 显示用于创建程序快捷方式的文件夹 |
准备安装页面
实现Controller.prototype.ReadyForInstallationPageCallback()函数用来与准备安装页面上的部件进行交互
向导按钮:
> 提交按钮
> 取消按钮
> 返回按钮
部件 | 简要描述 |
---|---|
MessageLabel | 显示消息 |
TaskDetailsBrowser | 显示有关安装的一些更详细的信息 |
执行安装页面
实现Controller.prototype.PerformInstallationPageCallback()函数用来与执行安装页面上的部件进行交互
向导按钮:
> 提交按钮
> 取消按钮
完成页面
实现Controller.prototype.FinishedPageCallback()函数用来与安装完成页面上的部件进行交互
向导按钮:
> 提交按钮
> 取消按钮
> 完成按钮
部件 | 简要描述 |
---|---|
MessageLabel | 显示消息 |
RunItCheckBox | 文本字段通知用户可以在安装完成后启动应用程序 |
自定义页面
自定义页面被注册为Dynamic${ObjectName}其中${ObjectName}是在UI文件中设置的对象名称 因此将调用Dynamic${ObjectName}Callback()函数通过部件的对象名称(从UI文件)可以实现对部件的访问
示例代码:
function Component()
{
// add page with widget \c SomePageWidget before the target directory page
installer.addWizardPage(component, "SomePageWidget", QInstaller.TargetDirectory)
}
Component.prototype.DynamicSomePageWidgetCallback = function()
{
var page = gui.pageWidgetByObjectName("DynamicSomePageWidget");
page.myButton.click, /https://p.download-x.com/direct child of the UI file's widget
page.someFancyWidget.subWidget.setText("foobar") // nested widget
}
消息框
在执行安装程序时例如程序可能会显示一些有关发生错误的消息框 在用户系统上运行程序时这没问题但这可能会破坏自动化测试套件 为解决此问题Qt Installer框架显示的所有消息框均可通过特定标识符进行访问
标识符 | 可选值 | 描述 |
---|---|---|
OverwriteTargetDirectory | Yes, No | 确认使用已有文件夹作为安装目标文件夹 |
installationError | OK, Retry, Ignore | 执行安装时发生致命错误 |
installationErrorWithRetry | Retry, Ignore, Cancel | 执行安装时发生错误 最终可以选择重试以再次运行 |
AuthorizationError | Abort, OK | 无法获取提升的权限 |
OperationDoesNotExistError | Abort, Ignore | 尝试执行操作时发生错误但该操作不存在 |
isAutoDependOnError | OK | 调用包脚本时发生错误 无法评估该包是否对其他包具有自动依赖性 |
isDefaultError | OK | 调用包脚本时发生错误 无法评估该包是否默认安装 |
DownloadError | Retry, Cancel | 从远程存储库下载存档哈希时发生错误 用户可以选择重试 |
archiveDownloadError | Retry, Cancel | 从远程存储库下载档案时发生错误用户可以选择重试 |
WriteError | OK | 写入维护工具时发生错误 |
ElevationError | OK | 无法获取提升的权限 |
unknown | OK | 删除某些包时发生未知错误 |
Error | OK | 通用错误 |
stopProcessesForUpdates | Retry, Ignore, Cancel | 更新包时发生错误 必须先退出一些正在运行的应用程序或进程然后才能执行更新用户可以选择“重试”以在停止后在此运行 |
Installer_Needs_To_Be_Local_Error | OK | 安装程序是从网络位置启动的但是不支持通过网络进行安装 |
TargetDirectoryInUse | No | 安装的目标文件夹已经包含其他安装 |
WrongTargetDirectory | OK | 安装的目标文件夹是文件或符号链接 |
AlreadyRunning | OK | 另一个应用程序实例已在运行 |
示例代码:
function Controller()
{
installer.autoRejectMessageBoxes;
installer.setMessageBoxAutomaticAnswer("OverwriteTargetDirectory", QMessageBox.Yes);
installer.setMessageBoxAutomaticAnswer("stopProcessesForUpdates", QMessageBox.Ignore);
}