文章目录
一、引言
对于每个安装程序,可以指定与安装程序的UI或功能的某些部分交互的控制脚本。控制脚本可以向安装向导添加或删除页面、更改现有页面、执行额外的检查,并通过模拟用户单击与UI交互。例如,允许无人值守的安装。
注意:脚本格式必须与QJSEngine兼容。
本节描述为实现这样的控制脚本而调用的函数。同时还概述安装程序页面和每个页面上可用的小部件,如按钮、单选按钮和行编辑。
二、编写控制脚本
一个脚本至少需要包含一个构造函数,如下:
function Controller()
{
}
下面例子展示了一个高级的脚本,它使用gui JavaScript全局对象方法在介绍页面上设置新的页面标题和欢迎信息,并自动单击目标目录页面上的Next按钮:
function Controller()
{
}
Controller.prototype.IntroductionPageCallback = function()
{
var widget = gui.currentPageWidget(); // 得到当前的页面向导
if (widget != null) {
widget.title = "New title."; // 设置页面的标题
widget.MessageLabel.setText("New Message."); // 设置欢迎显示的文本
}
}
Controller.prototype.TargetDirectoryPageCallback = function()
{
gui.clickButton(buttons.NextButton); // 自动单击“Next”按钮
}
下表总结了可以在控制器和组件脚本中使用的全局JavaScript对象。
序号 | JavaScript对象 | 描述 |
---|---|---|
1 | QDesktopServices | 提供常用桌面环境的访问方法 |
2 | QFileDialog | 提供一个对话框,允许用户选择文件或目录 |
3 | QInstaller | 提供从Qt脚本访问安装程序状态和页面 |
4 | QMessageBox | 提供一个模态对话框,用于通知用户或向用户询问问题并接收答案 |
5 | buttons | 提供可在安装程序页面上使用的按钮 |
6 | component | 表示Qt脚本所属的当前组件 |
7 | console | 提供用于记录和调试的方法 |
8 | gui | 启用与安装程序UI的交互 |
9 | installer | 提供访问Qt安装程序框架的核心功能 |
10 | 提供与QtScript的兼容性 | |
11 | systeminfo | 提供操作系统的信息 |
QInstaller JavaScript对象提供了对以下预定义安装程序页面的访问:
Introduction----------------------简介页面
TargetDirectory--------------------安装文件夹选择页面
ComponentSelection----------------组件选择页面
LicenseCheck ----------------------License选择页面
StartMenuSelection-----------------开始菜单快捷方式选择页面
ReadyForInstallation--------------准备安装提示页面
PerformInstallation---------------执行安装页面
InstallationFinished--------------安装完成提示页面
三、各个安装程序页面的交互
本节内容将描述可以实现的与安装程序页面和每个页面上可用的小部件交互的功能。
(3-1)Introduction页面
通过实现controller .prototype. introtionpagecallback()函数来与介绍页面上的小部件交互。
该向导中有两个按钮:
NextButton
CancelButton
Widgets | 详细描述 |
---|---|
ErrorLabel | 显示错误消息。 |
MessageLabel | 显示一条消息。默认情况下,它显示“欢迎使用<Name>安装向导”消息。 |
InformationLabel | 显示进度信息。 |
Radio Buttons | 详细描述 |
---|---|
PackageManagerRadioButton | 作为维护工具运行时,页面上显示的包管理器单选按钮。 |
UpdaterRadioButton | 作为维护工具运行时,页面上显示的更新程序单选按钮。 |
UninstallerRadioButton | 当作为维护工具运行时,页面上显示的卸载程序单选按钮。默认选中。 |
Progress Bar | 详细描述 |
---|---|
InformationProgressBar | 获取远程包时显示的进度条。 |
Qt Core Feature | Brief Description |
---|---|
packageManagerCoreTypeChanged() |
如果想在维修工具的类型发生变化时得到通知,必须连接此信号。Note: 只有当用户启动了所谓的二进制维护工具(安装后)并在单选按钮之间切换时才会发出信号。 |
示例代码
function Controller()
{
var widget = gui.pageById(QInstaller.Introduction); // 获取 introduction 向导页面
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());
}
(3-2)License Agreement页面
通过实现Controller.prototype.LicenseAgreementPageCallback()函数来与许可协议页面上的小部件交互。
页面中按钮:
NextButton
CancelButton
BackButton
Widgets | 详细描述 |
---|---|
LicenseListWidget |
列出可用的license。 |
LicenseTextBrowser |
显示所选license文件的内容。 |
AcceptLicenseLabel |
显示接受许可证单选按钮旁边的文本。 |
RejectLicenseLabel |
显示拒绝许可证单选按钮旁边的文本。 |
Radio Buttons | 详细描述 |
---|---|
AcceptLicenseRadioButton |
接受许可协议。 |
RejectLicenseRadioButton |
拒绝许可协议。默认选中。 |
(3-3)Target Directory页面
通过实现Controller.prototype.TargetDirectoryPageCallback()函数来与目标目录选择页面上的小部件交互。
页面中可用按钮:
NextButton
CancelButton
BackButton
Widgets | 详细描述 |
---|---|
MessageLabel |
显示帮助信息 |
TargetDirectoryLineEdit |
显示安装目标目录的值。 |
WarningLabel |
显示一个警告。 |
(3-4)Component Selection页面
通过实现Controller.prototype.ComponentSelectionPageCallback()函数来与组件选择页面上的小部件交互。
页面中按钮:
NextButton
CancelButton
BackButton
Methods | 详细信息 |
---|---|
selectAll() |
如果可能,选择所有可用的包。 |
deselectAll() |
如果可能,取消选择所有可用的包。 |
selectDefault() |
将可用包的检查状态重置为初始状态。 |
selectComponent(id) |
选择带有id (string)的包。 |
deselectComponent(id) |
取消选择带有id (string)的包。 |
Push Buttons | 详细描述 |
---|---|
SelectAllComponentsButton |
如果可能,选择所有可用的包。 |
DeselectAllComponentsButton |
如果可能,取消选择所有可用的包。 |
SelectDefaultComponentsButton |
将可用包的检查状态重置为初始状态 |
ResetComponentsButton |
重置为已安装的组件。 |
FetchCategoryButton |
从类别中获取组件。 |
Widgets | 详细信息 |
---|---|
CategoryGroupBox |
包含用于选择存储库类别的复选框 |
安装程序框架3.1将存储库类别作为一个新特性引入。当使用包含存储库类别的安装程序时,可以根据类别的显示名称选择类别,获取其内容,然后选择包含的组件进行安装。
例如:可以从一个类别中获取组件,如下:
Controller.prototype.ComponentSelectionPageCallback = function()
{
var page = gui.pageWidgetByObjectName("ComponentSelectionPage");
//如果CategoryGroupBox可见,选中其中一个复选框 ,并在选择任何组件之前单击获取按钮
var groupBox = gui.findChild(page, "CategoryGroupBox");
if (groupBox) {
console.log("groupBox found");
// findChild第二个参数是复选框的显示名称
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");
}
//现在可以从获取的类别中选择组件
}
(3-5)Start Menu Directory页面
通过实现Controller.prototype.StartMenuDirectoryPageCallback()函数来与准备安装页面上的小部件交互。
页面按钮:
-
NextButton
-
CancelButton
-
BackButton
Widgets 详细描述 StartMenuPathLineEdit
显示创建程序快捷方式的目录。
(3-6)执行安装页面
通过实现Controller.prototype.PerformInstallationPageCallback()函数来与执行安装页面上的小部件交互。
页面按钮:
CommitButton
CancelButton
(3-7)完成页面
通过实现Controller.prototype.FinishedPageCallback()函数来与安装完成页面上的小部件交互。
页面按钮:
CommitButton
CancelButton
FinishButton
Widgets | 详细描述 |
---|---|
MessageLabel |
显示帮助信息 |
RunItCheckBox |
文本字段,通知用户他们可以在安装过程结束后启动应用程序。 |
四、对于自定义页面的交互
自定义页面注册为Dynamic O b j e c t N a m e , 其 中 {ObjectName},其中 ObjectName,其中{ObjectName}是UI文件中设置的对象名称。因此,调用Dynamic${ObjectName}Callback()函数。小部件可以使用它们的对象名称(来自UI文件)来寻址。
例如:
function Component()
{
//在选择安装目录页面 新增加自定义的页面SomePageWidget
installer.addWizardPage(component, "SomePageWidget", QInstaller.TargetDirectory)
}
Component.prototype.DynamicSomePageWidgetCallback = function()
{
var page = gui.pageWidgetByObjectName("DynamicSomePageWidget");
page.myButton.click, //UI文件中的myButton按钮
page.someFancyWidget.subWidget.setText("foobar")
}
Message Boxes
例如,在执行安装程序应用程序时,应用程序可能会显示一些发生错误时的消息框。当在最终用户的系统上运行应用程序时,但它可能会破坏自动化测试套件。为了克服这个问题,Qt安装程序框架显示的所有消息框都可以通过特定的标识符确认。
Identifier | Possible Answers | 描述 |
---|---|---|
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);
}
五、总结
安装脚本主要用于获取安装包几个向导页面的相关(运行环境参数,界面中小部件参数,操作系统环境参数等)。并提供了调试的机制和方法。
可见,安装脚本语法与JavaScript可以说几乎一样。