Qt Creator wizards are powerful code-generation tools that expedite time to development. In this article, I'll discuss the types of Qt Creator wizards that are available to developers at present, with a focus on templated wizards. I'll also provide helpful tips for preparing to write them.
Qt Creator Wizards
Here's an example of a screen in a Qt Creator wizard. This particular wizard, packaged with Qt, is a JSON-based templated Qt Creator wizard.
Within Qt Creator, whenever you endeavor to create a new file or project, you are directed to the New File or Project dialog. Selecting an entry from that dialog and clicking the Choose… button creates an instance of a wizard or guided process like in the above image. That wizard will assist in the generation of file(s) corresponding to your selection.
Ultimately, these Qt Creator wizards reduce development time by eliminating redundant steps in code production. They streamline the process of file and project generation by reducing the workflow to simply filling out a few fields and/or clicking a few buttons. Additionally, they provide a means to standardize project and class creation — as well as initial and/or structural formatting — across your development team.
There are two primary types of Qt Creator wizards: JSON-based wizards and XML-based wizards. You can accomplish most common tasks using either one. For tailored functionality not provided by those types, you may wish to design a custom C++-based wizard, which would be exposed to Qt Creator via a plugin.
XML-based wizards allow you to accept information from the user, manipulate that data into populating template files, which are constructed at a target location from copies in the wizard directory. Additional screens [described as desired within the XML] are created and injected into existing project and class wizards. These screens extend the information collection capacity of the wizard to assist with appropriately populating the template files during the generation process.
In addition to user-entered field values, there are several predefined standard variables available to the generator, including date, time, project name, source and target paths, etc. Another feature offered by these wizards is localization: the field labels and values can be assigned different translations based on the current locale. Validation rules may also be applied to your variables and user inputs.
Note: The XML-based wizard format is deprecated in favor of the newer JSON-based wizard format. It is recommended that you use the JSON format when creating new wizards, if possible.
JSON-based wizards provide a superset of the functionality available in XML-based wizards. The JSON wizard interpreter comes with a JsExpander, which contains its own QJSEngine. In addition to the features supported by XML-based wizards, the expander-engine package offers the ability to evaluate JS statements and to execute scripts within your wizard without having to resort to the full-blown C++-plugin to achieve the same. Some of the objects Qt Creator registers with the QJSEngine include (but are not necessarily limited to):
Util provides functionality for general file and path checking and manipulation.
Cpp provides functionality for class and class file name transformations.
Modeling provides functionality for converting between element and file names.
QtSupport provides functionality for class name manipulation in ui files and for obtaining a list of Qt dependencies.
Vcs provides functionality for obtaining information associated with Vcs IDs.
The range of functionality available within the JS engines is extended by these registered components to assist with common wizard challenges.
C++-plugin-based wizards offer a way to tailor the plugin to your needs. You can use your plugin to register additional objects with the JS engine and proceed with using JSON-based wizards, or you can build custom wizards from the ground up to look the way you desire and most often to perform more complex tasks that are either not as easily achieved via the available JS engine or simply out of the realm of possibility via that route.
Creating a C++-plugin-based wizard involves writing two primary classes:
1. A wizard factory class deriving from Core::IWizardFactory
This is the class that is registered with ExtensionSystem::PluginManager and that will be used to generate instances of your custom wizard.
2. A wizard class deriving from Utils::Wizard
Instances of this class will be generated by your custom wizard factory when runWizard is called.
C++ wizards have basically devolved into a method of last resort. Most of the functionality required by wizards can generally be satisfied by the JSON-based wizards, which were developed with the intention of reducing code duplication and simplifying the wizard code base.
Below are some items to be aware of when preparing to develop Qt Creator wizards that will help get you started and productive more quickly.
Preparing Your Wizard Development Environment
Though unnecessary, there are a couple things you can do to prepare your environment for developing Qt Creator wizards that will greatly increase your productivity. They can also provide you with debugging capabilities you wouldn’t otherwise have access to.
Start Qt Creator with the -customwizard-verbose argument
This will cause Qt Creator to log wizard output messages. This is particularly helpful in catching errors during wizard development such as missing source files required for wizard display — or for file generation — as well as invalid JSON/XML.
Assign Qt-Creator-wizard-related actions to keyboard shortcuts
There are two key pieces of functionality that will greatly expedite wizard development. In order to use them, you have to navigate to Tools > Options > Environment > Keyboard from within Qt Creator. Assign shortcuts for the “Actions” listed below. (One note: under the default configuration the Ctrl-Shift-K and Ctrl-Shift-M shortcuts are available. But when attempting to enter a shortcut that is already in use, the Key Sequence should turn red, and a message warning of potential conflicts should be shown beneath it.)
The Factory Reset Action will unload all the wizard factories and attempt to reparse and reload the wizards the next time you enter the New File or Project dialog. Without the availability of this action, you would need to exit and restart Qt Creator each time you wanted to test a change you’ve made to your wizard.
The Inspect Action will open a dialog containing a view of the wizard state at the time of the call to Inspect. The dialog is non-modal, allowing you to have multiple open at a time and to track the history of your wizard’s variables at different screens/states within your wizard.
If the wizards you design are not placed in specific directories, Qt Creator will not know where to find them or how to load them. So, in order for Qt Creator to detect your custom wizards, they must be located in one of the following directories:
The Qt Creator build/installation directory:
<Qt Creator source directory>/share/qtcreator/templates/wizards/
When developing for/contributing to Qt Creator or when building a custom C++-based wizard plugin you will want to create your wizards here. At this point running qmake will copy your custom wizard directory over to the corresponding build directory where it can be detected by subsequent runs of Qt Creator.
<Qt Creator build directory>/share/qtcreator/templates/wizards/ (for Windows and Linux)
/Applications/Qt Creator.app/Contents/Resources/templates/wizards (for Macs)
The local user’s configuration directory:
%APPDATA%\QtProject\qtcreator\templates\wizards (for Windows)
$HOME/.config/QtProject/qtcreator/templates/wizards (for Linux and Macs)
This option is preferred for local wizards that do not require processing by qmake and is the most likely place you will want to be storing your custom wizards with the exception of contributing back to Qt or of developing a C++-plugin-based wizard.
Although the standard wizards are organized into a directory hierarchy by type, this pattern does not need to be followed. The wizards will instead be displayed and organized in the New File or Project dialog according to configuration options specified in the wizard’s configuration file.
Several control types are available to template wizards, including:
A check box control whose value depends on its checked state.
A combo box used for entry selection from a list.
A text label for displaying information to the user.
A line edit control, which allows the user to manipulate a string of data within a single line.
A combination line edit and button control to allow the user to select a path. The button opens a dialog for selecting the path via a UI as opposed to the error-prone manual entry method provided by the corresponding line edit.
A control to create a gap between consecutively defined controls.
A text edit control, which allows the user to manipulate a potentially multi-line string of data within a block. These controls will be laid out on the screens of your wizard as described in your wizard configuration files. The input data associated with those controls can be accessed via the name property you assign them.
To reiterate: Qt Creator wizards are powerful code-generation tools that expedite time to development. They can simultaneously help familiarize team members with any common company/team code/hierarchy formatting practices. They’re relatively simple to learn, and there are tools available to catch and notify you of any problems you might run into along the way. Consider giving wizards a try and see how much time the automated code generation can help your team!
Here are some additional useful references you may find useful when developing Qt Creator wizards: