Silent install Qt run installer on ubuntu server
I wanted to know if there is a way to do a silent install of the Qt run installer on Ubuntu Server?
I mean by-pass the options of the installer and do a default install?
Updated Answer:
Newer Qt installers have a proper CLI that allows you to do something like:
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
See --help
for all options. To figure out package names, go through a graphical install but stop at the final confirmation screen that lists the package names for all your selections.
Previous Answer
The Qt toolkit is packaged using the Qt Installer Framework (QtIFW). QtIFW installers support a --script
option that allows you to programatically control the installation via the Controller Scripting API. Here's qt-installer-noninteractive.qs
file to install Qt 5 non-interactively:
// 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);
}
This script demonstrates how to select/deselect certain components. Customize for your needs or just remove the lines entirely for a default installation. Likewise, you may want to customize or remove the TargetDirectoryLineEdit
line. Run the Qt installer like:
qt-opensource-linux-x64-5.5.1.run --script qt-installer-noninteractive.qs
Add -platform minimal
for a headless installation. Future installers based on newer versions of QtIFW should be able to use a --silent
option instead (see QTIFW-166).
Add --verbose
for more verbose console output (helpful for gleaning component names, wizard page names, etc). This link is also helpful for figuring out component names.
As of installer 4.X
, you don't need to play with JS files anymore. Version 4.0
of the Qt online installer has first-class support for headless installation. See this answer for more information.
As of installer 3.0.2-online
29-11-2017, you must add a delay in your JS script because the "Next" button in the "Welcome" page is disabled for one second or so.
Controller.prototype.WelcomePageCallback = function() {
gui.clickButton(buttons.NextButton, 3000);
}
For once, they explain on the 3.2.1-online
29-01-2020 release page how to skip the new form
Controller.prototype.ObligationsPageCallback = function() {
var page = gui.pageWidgetByObjectName("ObligationsPage");
page.obligationsAgreement.setChecked(true);
page.completeChanged();
gui.clickButton(buttons.NextButton);
}
Some may wonder how to create the mysterious qtaccount.ini
file (required since 3.2.1-2-online
). Qt only tells us that it should be placed in ~/.local/share/Qt/
. I was unable to find any other information. The installer creates this file itself when you enter your credentials for the first time. So simply do a manual installation and quit after the accound form. The generated file looks like
[General]
[email protected]
pass=mypass
[QtAccount]
[email protected]
jwt=a long hash
u=a small hash
2020 update: There's a better way now.
Version 4.0
of the Qt online installer has first-class support for headless installation.
See this answer below for more info.
Original answer:
Bypassing "User Data Collection" screen
As of October 8, 2019, an extra screen has been added on Windows which will cause the installation to hang. You can click through it with the following addition to your .qs
file:
Controller.prototype.DynamicTelemetryPluginFormCallback = function() {
var widget = gui.currentPageWidget();
widget.TelemetryPluginForm.statisticGroupBox.disableStatisticRadioButton.checked = true;
gui.clickButton(buttons.NextButton);
}
Selecting "Archive" and "Latest releases"
Another recent change is to package categories. LTS is now the only one selected by default, meaning that you cannot install the latest Qt version without first selecting "Latest releases" in the package categories.
Here's how to do that:
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();
// ...
}
See here for a more complete example for Windows.