I recently had to deploy a Qt Quick application on a Windows machine that did not have Qt installed explicitly on it. I think this is a pretty common use case that can cause quite some headache. You basically have two options if you want to deploy (or install) your Qt or Qt Quick based application to Windows. Either you can use the Windows Installer service directly or use some free or commercial utility to create a MSI based installer application that will deploy your application on Windows. Alternatively or at least as a first step you can package your application into a ZIP, or some other, package together with the necessary libraries that the application depends on. This is what I did and what I am going to explain here. When the package is extracted on the target machine, your Qt or Qt Quick application can be run from that directory just by launching the .exe file. Pretty neat.
Below I will explain some important points on how you want to create the package that you want to distribute your Qt application in. In my case I deployed a Qt Quick application that used Qt/3D and QtWebKit.
I first recommend you to install a great tool for figuring out the required .dll files that you need to include in your package: Windows Dependency Walker. It's a neat free utility that will create a hierarchical tree of the .dll dependencies that an application uses. When you run your application, in the machine that has Qt installed on it, through Dependency Walker you can easily see which Qt .dll files it uses and you need to package with your application.If you are curious, you'll find that Dependency Walker will show you a lot more information about what methods the application used and from which .dll file, which methods are available in the .dll but were not used and a lot more detailed information about each .dll that the application loaded.
When you run your application through Dependency Walker on the machine that does not have Qt installed on it and when it did not run as expected, you can then see which .dll files your app failed to find. This is really a life saver when it comes to application deployment for Windows.
A word on warning, though. Dependency Walker is really good at finding libraries that your application is dynamically linked against. But it will not spot issues when it comes to Qt plugins. If a plugin is not found, there will not be any trace of it in Dependency Walker since Qt will just inform the app that this plugin is not available. So it is important to understand which plugins Qt will need and Dependency Walker cannot help you here.
Deploying dynamically linked Qt application without plugins
This is the easiest type of application to deploy. It's basically a Qt application that only uses one or more Qt modules (the .dll files) that do not depend on plugins. Such an application could for example be a QWidget based application, but one that is not showing images. You can already guess which Qt .dll files your application needs: each of the Qt modules is one Windows .dll file. So when you type in your .pro file for example
CONFIG += network
to do network programming, you know you have to include QtNetwork4.dll in your package.
Where do I find this file you ask? Well - it's in the Qt installation directory on your machine and in the bin/ directory under it. Go there and copy the required .dll files to your deployment folder that you intend to package.
If you have an application does not use Qt plugins on your hands and you want to deploy on Windows, then it's enough to package the .exe file together with all the dependent .dll files in the same root folder. When you extract the package in a directory and launch your application, Windows will first look for the required .dll files in the same folder as where the application was launched. Since this application does not use any plugins it will find all the required Qt .dll files it depends on in the same folder as the application was launched in (the rest of the .dll files should already be installed on the target machine). As an example I could deploy a QWidget based application that reads something of the network by creating a package that contains the following files:
application.exe QtCore4.dll QtGui4.dll QtNetwork4.dll
Deploying Qt applications with plugins
Even if you didn't utilize a plug-in based architecture for your application Qt uses internally plugins. When you deploy your application you need to make sure the plugins are included in the package. Plug-ins are essentially just .dll files that are loaded at runtime.
When Qt is looking for plug-ins to load, it will look in specific folders for the plug-ins. Each plug-in is categorized based on its function and plug-ins that provide similar functionality will be in the same folder. For example all SQL implementation (driver plugins) are in a folder called sqldrivers so when Qt wants to load a SQL driver it will look into that folder.
But Qt must have a way to find the plug-in category folders. Qt has two ways to do this. First, it will look into a folder called plugins that is part of the Qt installation. More important to you, secondly it will use the current directory where the application was launched. Qt will look inside these two folders for the plug-in category folder.
This is why, when you deploy your application, remember to put the plugins into their respective category folder and the category folder on the root level in your package.
So if I want to use QtWebKit to show a webpage in my application, I would need to include the .dll files that QtWebKit depends on and also the runtime plugins that it depends on to show GIF and JPEG images. I would create the following hierarchy in my deployment package:
imageformats/qgif4.dll //<< QtWebKit depends on this imageformats/qjpeg4.dll //<< QtWebKit depends on this application.exe QtCore4.dll QtWebKit4.dll QtNetwork4.dll //<< QtWebKit depends on this QtScript4.dll //<< QtWebKit depends on this QtScriptTools.dll //<< QtWebKit depends on this phonon4.dll //<< QtWebKit depends on this
Deploying Qt Quick applications with plugins
First I must say that if you deploy and application that doesn't use Qt Quick plugins you can deploy it as the example above shows. But if your application uses Qt Quick plugins (you know, for example the import QtWebKit 1.0 line in your QML file if you use WebView) then you need to be aware how Qt loads Qt Quick plugins.
Qt has some good documentation on Qt Quick modules and import paths so I try to be brief about it. But what you need to know is that when you write import in your QML file, Qt will always look for a runtime module in a folder that you specified on that line. So when you write import QtWebKit 1.0, what Qt is actually doing is looking for a folder named QtWebKit. Important for deployment is that Qt will do so in the directory where you launched your application.
In this folder, Qt Quick will look for a file called qmldir. It's a file containing meta-information such as available plugins that represent the component I want to import. If I wanted to use the WebView element in Qt Quick, I would then create a qmldir file and put in a folder called QtWebKit in the root folder of my package. The content of the file would be as follows:
This will tell Qt Quick that the QtQuick 1.0 plugin (that you specified on the import line) is available in a plugin file (a .dll file) called qmlwebkitplugin. Qt will now look for a suitable plugin with the name qmlwebkitplugin - on Windows that plugin is in a file called, unsurprisingly, qmlwebkitplugin.dll in the same folder as the qmldir file.
As I stated in the beginning, I used Qt/3D, Qt Quick and QtWebkit components in my application. To be able to use all of these components and to satisfy the dependencies, my deployment package looks something like this (directory with QML files omitted):
imageformats/qgif4.dll imageformats/qjpeg4.dll sceneformats/qsceneai4.dll QtWebKit/qmldir QtWebKit/qmlwebkitplugin.dll application.exe Qt3D.dll Qt3DQuick.dll QtCore4.dll QtDeclarative.dll QtGui4.dll QtNetwork4.dll QtOpenGL4.dll QtScript4.dll QtScriptTools4.dll QtWebKit4.dll QtXml4.dll QtXmlPatterns4.dll
I can run my application on any machine even without Qt installed when the package is extracted and the application.exe is launched. On the downside the deployment package is rather big because of all the dependencies. QtWebKit module alone is a huge package: almost 17 megabytes. My application doesn't do much fancy and it does not include any images or other multimedia files. Still my deployment package is 52 megabytes big when it's extracted. Qt is actively working on splitting the modules into smaller pieces and Qt5 will deliver an even more plug-in based architecture that will cut down the size of individual modules and eventually your deployment package.