我想知道在Ubuntu Server上是否有一种方法可以静默安装Qt运行安装程序?
我的意思是绕过安装程序的选项并进行默认安装?
我想知道在Ubuntu Server上是否有一种方法可以静默安装Qt运行安装程序?
我的意思是绕过安装程序的选项并进行默认安装?
新版的Qt安装程序拥有完整的命令行界面,可以让你像下面这样操作:
qt-unified-windows-x86-4.2.0-online.exe ^
--accept-licenses ^
--default-answer ^
--confirm-command install ^
qt.qt5.5158.win64_msvc2019_64 ^
qt.qt5.5158.qtcharts ^
qt.qt5.5158.debug_info ^
qt.qt5.5158.src ^
qt.tools.qtcreator
查看所有选项请使用--help
。要弄清包名称,请进行图形安装,但停止在列出所有选择的包名称的最终确认屏幕。
Qt工具包使用Qt安装程序框架(QtIFW)进行打包。 QtIFW安装程序支持--script
选项,允许您通过控制器脚本API以编程方式控制安装。以下是用于非交互式安装Qt 5的qt-installer-noninteractive.qs
文件:
// Emacs mode hint: -*- mode: JavaScript -*-
function Controller() {
installer.autoRejectMessageBoxes();
installer.installationFinished.connect(function() {
gui.clickButton(buttons.NextButton);
})
}
Controller.prototype.WelcomePageCallback = function() {
// click delay here because the next button is initially disabled for ~1 second
gui.clickButton(buttons.NextButton, 3000);
}
Controller.prototype.CredentialsPageCallback = function() {
gui.clickButton(buttons.NextButton);
}
Controller.prototype.IntroductionPageCallback = function() {
gui.clickButton(buttons.NextButton);
}
Controller.prototype.TargetDirectoryPageCallback = function()
{
gui.currentPageWidget().TargetDirectoryLineEdit.setText(installer.value("HomeDir") + "/Qt");
gui.clickButton(buttons.NextButton);
}
Controller.prototype.ComponentSelectionPageCallback = function() {
var widget = gui.currentPageWidget();
widget.deselectAll();
widget.selectComponent("qt.55.gcc_64");
widget.selectComponent("qt.55.qtquickcontrols");
// widget.deselectComponent("qt.tools.qtcreator");
// widget.deselectComponent("qt.55.qt3d");
// widget.deselectComponent("qt.55.qtcanvas3d");
// widget.deselectComponent("qt.55.qtlocation");
// widget.deselectComponent("qt.55.qtquick1");
// widget.deselectComponent("qt.55.qtscript");
// widget.deselectComponent("qt.55.qtwebengine");
// widget.deselectComponent("qt.extras");
// widget.deselectComponent("qt.tools.doc");
// widget.deselectComponent("qt.tools.examples");
gui.clickButton(buttons.NextButton);
}
Controller.prototype.LicenseAgreementPageCallback = function() {
gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true);
gui.clickButton(buttons.NextButton);
}
Controller.prototype.StartMenuDirectoryPageCallback = function() {
gui.clickButton(buttons.NextButton);
}
Controller.prototype.ReadyForInstallationPageCallback = function()
{
gui.clickButton(buttons.NextButton);
}
Controller.prototype.FinishedPageCallback = function() {
var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm;
if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) {
checkBoxForm.launchQtCreatorCheckBox.checked = false;
}
gui.clickButton(buttons.FinishButton);
}
此脚本演示如何选择/取消选择特定组件。根据您的需求进行自定义,或者完全删除这些行以进行默认安装。同样,您可能想要自定义或删除TargetDirectoryLineEdit
行。运行Qt安装程序如下:
qt-opensource-linux-x64-5.5.1.run --script qt-installer-noninteractive.qs
为了进行无头安装,请添加-platform minimal
选项。基于QtIFW更新版本的未来安装程序应该可以使用--silent
选项代替(请参见QTIFW-166)。
如果需要获取组件名称、向导页面名称等更详细的控制台输出,请添加--verbose
选项。此链接也有助于确定组件名称。
qt-opensource-linux-x64-android-5.7.0.run
,-platform minimal
会出现 Unknown option: p, l, a, t, f, o, r, m
的错误提示,--platform minimal
会出现 Unknown option: platform
的错误提示,而 --silent
则会出现 Unknown option: silent
的错误提示。在没有 UI 系统的情况下,还会出现 QXcbConnection: Could not connect to display
和 Aborted (core dumped)
的错误提示。 - ssc从安装程序4.X
开始,您不再需要操作JS文件。Qt在线安装程序版本4.0
已经支持无头安装。有关更多信息,请参见此答案。
从安装程序3.0.2-online
29-11-2017开始,您必须在JS脚本中添加延迟,因为“欢迎”页面上的“下一步”按钮会被禁用一秒钟左右。
Controller.prototype.WelcomePageCallback = function() {
gui.clickButton(buttons.NextButton, 3000);
}
他们在3.2.1-online
2020年1月29日的发布页面上首次解释如何跳过新表单。
Controller.prototype.ObligationsPageCallback = function() {
var page = gui.pageWidgetByObjectName("ObligationsPage");
page.obligationsAgreement.setChecked(true);
page.completeChanged();
gui.clickButton(buttons.NextButton);
}
有些人可能想知道如何创建神秘的qtaccount.ini
文件(从3.2.1-2-online
开始需要)。 Qt只告诉我们应该将其放置在〜/ .local / share / Qt /
中。我找不到任何其他信息。安装程序会在您首次输入凭据时自行创建此文件。因此,在填写账户表格后进行手动安装并退出即可。生成的文件看起来像这样
[General]
email=my.email@domain.ca
pass=mypass
[QtAccount]
email=my.email@domain.ca
jwt=a long hash
u=a small hash
Controller.prototype.CredentialsPageCallback
。查看其他答案以了解如何使用它。您的用户名和密码将自动填充为 qtaccount.ini
。 - Nil对于不同版本的Qt,向导问题的回答可能会有一些细微的差异。为了让它更简单,我打包了一个通用脚本,从离线/在线安装程序中提取Qt。
该脚本: qtci/extract-qt-installer at master · benlau/qtci
使用示例:
extract-qt-installer qt-opensource-linux-x64-android-5.5.1.run ~/Qt
环境变量
VERBOSE [Optional] Set to "true" will enable VERBOSE output
QT_CI_PAGEAGES [Optional] Select the components to be installed instead of using default (eg. QT_CI_PAGEAGES="qt.59.gcc_64")
Qt在线安装程序版本4.0
现在支持无人值守安装。
有关更多信息,请参见下面的答案。
原始答案:
自2019年10月8日起,在Windows上增加了一屏幕,这将导致安装挂起。您可以通过以下内容向.qs
文件添加点击来通过此屏幕:
Controller.prototype.DynamicTelemetryPluginFormCallback = function() {
var widget = gui.currentPageWidget();
widget.TelemetryPluginForm.statisticGroupBox.disableStatisticRadioButton.checked = true;
gui.clickButton(buttons.NextButton);
}
另一个最近的更改是对软件包类别的调整。现在,默认情况下只选择LTS版本,这意味着您不能安装最新的Qt版本,除非先在软件包类别中选择“最新版本发布”。
以下是如何进行操作:
Controller.prototype.ComponentSelectionPageCallback = function() {
var page = gui.pageWidgetByObjectName("ComponentSelectionPage");
var archiveCheckBox = gui.findChild(page, "Archive");
var latestCheckBox = gui.findChild(page, "Latest releases");
var fetchButton = gui.findChild(page, "FetchCategoryButton");
archiveCheckBox.click();
latestCheckBox.click();
fetchButton.click();
// ...
}
查看 此处 获取更完整的 Windows 示例。
gui.currentPageWidget()
似乎返回一个 JS 对象。凭借纯粹的运气,我在获取小部件后能够执行以下操作:console.log(JSON.stringify(widget));
。我还使用了 --verbose
,但我认为这在这种情况下没有影响。 - Joshua Wadefunction Controller() {
installer.autoRejectMessageBoxes();
installer.setMessageBoxAutomaticAnswer("installationError", QMessageBox.Retry);
installer.setMessageBoxAutomaticAnswer("installationErrorWithRetry", QMessageBox.Retry);
installer.setMessageBoxAutomaticAnswer("DownloadError", QMessageBox.Retry);
installer.setMessageBoxAutomaticAnswer("archiveDownloadError", QMessageBox.Retry);
installer.installationFinished.connect(function() {
gui.clickButton(buttons.NextButton);
})
}
Controller.prototype.WelcomePageCallback = function() {
// click delay here because the next button is initially disabled for ~1 second
gui.clickButton(buttons.NextButton, 3000);
}
Controller.prototype.CredentialsPageCallback = function() {
gui.clickButton(buttons.NextButton);
}
Controller.prototype.IntroductionPageCallback = function() {
gui.clickButton(buttons.NextButton);
}
Controller.prototype.TargetDirectoryPageCallback = function()
{
//dev is the user in our docker image
gui.currentPageWidget().TargetDirectoryLineEdit.setText(installer.value("HomeDir") + "/Qt");
gui.clickButton(buttons.NextButton);
}
Controller.prototype.PerformInstallationPageCallback = function() {
gui.clickButton(buttons.CommitButton);
}
Controller.prototype.ComponentSelectionPageCallback = function() {
function list_packages() {
var components = installer.components();
console.log("Available components: " + components.length);
var packages = ["Packages: "];
for (var i = 0 ; i < components.length ;i++) {
packages.push(components[i].name);
}
console.log(packages.join(" "));
}
list_packages();
var widget = gui.currentPageWidget();
console.log(widget);
widget.deselectAll();
widget.selectComponent("qt.qt5.5130");
widget.selectComponent("qt.qt5.5130.gcc_64");
// widget.deselectComponent("");
gui.clickButton(buttons.NextButton);
}
Controller.prototype.LicenseAgreementPageCallback = function() {
gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true);
gui.clickButton(buttons.NextButton);
}
Controller.prototype.StartMenuDirectoryPageCallback = function() {
gui.clickButton(buttons.NextButton);
}
Controller.prototype.ReadyForInstallationPageCallback = function()
{
gui.clickButton(buttons.NextButton);
}
Controller.prototype.FinishedPageCallback = function() {
var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm;
if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) {
checkBoxForm.launchQtCreatorCheckBox.checked = false;
}
gui.clickButton(buttons.FinishButton);
}
使用详细模式运行,这样您就不必等待太长时间而没有输出。
qt.run -platform minimal --verbose --script ./qt-installer-noninteractive.qs
installationError
/ installationErrorWithRetry
的自动答案设置为QMessageBox.Ignore
来解决,而不是QMessageBox.Retry
。 - Joshua Wadewidget.selectComponent("qt.VERSION.gcc_64");
widget.selectComponent("qt.qt5.VERSION.gcc_64");
- Kriegalex看一下这个很棒的项目:aqtinstall
https://github.com/miurahr/aqtinstall/
它可以在Linux、Mac和Windows机器上安装Qt,无需任何交互。
还有一个使用这个工具的Github操作:https://github.com/jurplel/install-qt-action
aqtinstall
比维护QtIFW
脚本更容易且不会引起太多挫败感。 - Joshua Wade从3.2.1版本开始,凭据现在是必需的,如上面稍微解释过的。一个 qtaccount.ini 文件被创建在 ~/.local/share/qt
中。如果您无法保存并重用此文件,因为您的脚本需要为多个用户工作,您可以使用这个新的 CredentialsPageCallback:
Controller.prototype.CredentialsPageCallback = function() {
var page = gui.pageWidgetByObjectName("CredentialsPage");
page.loginWidget.EmailLineEdit.setText("MYEMAIL");
page.loginWidget.PasswordLineEdit.setText("MYPASSWORD");
gui.clickButton(buttons.NextButton);
}
一如既往地,请小心处理密码,特别是明文传输的情况。
sudo apt install python3-requests p7zip-full wget
wget https://git.kaidan.im/lnj/qli-installer/raw/master/qli-installer.py
chmod +x qli-installer.py
./qli-installer.py 5.11.3 linux desktop
./5.11.3/gcc_64/
中找到。当然,在其他系统/目标(例如mac ios
或linux android android_armv7
)中会有所不同。
网络错误:[QNetworkReply :: NetworkError(UnknownNetworkError)]“无法连接到服务器。请检查您的网络连接并重试。”
- user23014.0
版本现在已经拥有了一流的支持。更多信息请参见此答案。 - Joshua Wadehttps://doc.qt.io/qtinstallerframework/ifw-use-cases-cli.html#unattended-usage - likeicare