Commit 00a00704 authored by Friedemann Kleint's avatar Friedemann Kleint

Doc: Add documentation on how to write Wizards in code.

Reviewed-by: default avatarLeena Miettinen <>
Acked-by: default avatarAlessandro Portale <>
parent e8496ca3
......@@ -45,6 +45,7 @@ HELP_DEP_FILES = $$PWD/qtcreator-api.qdoc \
$$PWD/coding-style.qdoc \
$$PWD/external-tool-spec.qdoc \
$$PWD/qtcreator-dev.qdoc \
$$PWD/qtcreator-dev-wizards.qdoc \
$$PWD/qtcreator-dev.qdocconf = CREATE API DOC
//! [0]
#include "webpagewizard.h"
#include <utils/filewizarddialog.h>
#include <utils/qtcassert.h>
#include <QtCore/QXmlStreamWriter>
#include <QtGui/QGridLayout>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QPlainTextEdit>
namespace MyPlugin {
namespace Internal {
//! [1]
WebContentPageWizardPage::WebContentPageWizardPage(QWidget *parent) :
m_titleLineEdit(new QLineEdit),
m_textEdit(new QPlainTextEdit),
QGridLayout *layout = new QGridLayout(this);
QLabel *titleLabel = new QLabel(tr("&Title"));
layout->addWidget(titleLabel, 0, 0);
layout->addWidget(m_titleLineEdit, 0, 1);
QLabel *contentLabel = new QLabel(tr("&Content"));
layout->addWidget(contentLabel, 1, 0, 1, 1, Qt::AlignTop);
layout->addWidget(m_textEdit, 1, 1);
setTitle(tr("Web Page Contents"));
connect(m_titleLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotChanged()));
connect(m_textEdit, SIGNAL(textChanged()), this, SLOT(slotChanged()));
QString WebContentPageWizardPage::title() const
return m_titleLineEdit->text();
QString WebContentPageWizardPage::contents() const
return m_textEdit->toPlainText();
void WebContentPageWizardPage::slotChanged()
const bool completeNow = !m_titleLineEdit->text().isEmpty()
&& m_textEdit->blockCount() > 0;
if (completeNow != m_complete) {
m_complete = completeNow;
emit completeChanged();
//! [1] //! [2]
WebContentWizardDialog::WebContentWizardDialog(QWidget *parent) :
Utils::FileWizardDialog(parent), m_contentPage(new WebContentPageWizardPage)
//! [2] //! [3]
WebPageWizard::WebPageWizard(const Core::BaseFileWizardParameters &parameters,
QObject *parent) :
Core::BaseFileWizard(parameters, parent)
QWizard *WebPageWizard::createWizardDialog(QWidget *parent,
const QString &defaultPath,
const WizardPageList &extensionPages) const
WebContentWizardDialog *dialog = new WebContentWizardDialog(parent);
foreach (QWizardPage *p, extensionPages)
return dialog;
WebPageWizard::generateFiles(const QWizard *w,
QString *) const
Core::GeneratedFiles files;
const WebContentWizardDialog *dialog = qobject_cast<const WebContentWizardDialog*>(w);
QTC_ASSERT(dialog, return files; )
const QString fileName = Core::BaseFileWizard::buildFileName(dialog->path(), dialog->fileName(), QLatin1String("html"));
Core::GeneratedFile file(fileName);
QString contents;
QXmlStreamWriter writer(&contents);
writer.writeTextElement(QLatin1String("title"), dialog->title());
writer.writeEndElement(); // HEAD
writer.writeTextElement(QLatin1String("h1"), dialog->title());
writer.writeTextElement(QLatin1String("p"), dialog->contents());
writer.writeEndElement(); // BODY
writer.writeEndElement(); // HTML
return files;
//! [3]
} // namespace Internal
} // namespace MyPlugin
//! [0]
//! [0]
#include "basefilewizard.h"
#include "utils/filewizarddialog.h"
#include <QtGui/QWizardPage>
class QLineEdit;
class QPlainTextEdit;
namespace MyPlugin {
namespace Internal {
//! [1]
class WebContentPageWizardPage : public QWizardPage
explicit WebContentPageWizardPage(QWidget *parent = 0);
QString title() const;
QString contents() const;
virtual bool isComplete() const { return m_complete; }
private slots:
void slotChanged();
QLineEdit *m_titleLineEdit;
QPlainTextEdit *m_textEdit;
bool m_complete;
//! [1] //! [2]
class WebContentWizardDialog : public Utils::FileWizardDialog
explicit WebContentWizardDialog(QWidget *parent = 0);
QString title() const { return m_contentPage->title(); }
QString contents() const { return m_contentPage->contents(); }
WebContentPageWizardPage *m_contentPage;
//! [2] //! [3]
class WebPageWizard : public Core::BaseFileWizard
explicit WebPageWizard(const Core::BaseFileWizardParameters &parameters,
QObject *parent = 0);
virtual QWizard *createWizardDialog(QWidget *parent,
const QString &defaultPath,
const WizardPageList &extensionPages) const;
virtual Core::GeneratedFiles generateFiles(const QWizard *w,
QString *errorMessage) const;
//! [3]
} // namespace Internal
} // namespace MyPlugin
//! [0]
//! [0]
bool MyPlugin::initialize(const QStringList &arguments, QString *errorMessage)
Core::BaseFileWizardParameters p(IWizard::FileWizard);
p.setDescription(tr("Creates a Web Page."));
p.setDisplayName(tr("Web Page"));
addAutoReleasedObject(new WebPageWizard(p));
//! [0]
** This file is part of Qt Creator
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of this
** file.
** If you have questions regarding the use of this file, please contact
** Nokia at
\page qtcreator-dev-wizards.html
\title Creating Wizards in Code
\section1 Introduction
If the functionality provided by template-based
\l{}{custom wizards}
is not sufficient for your case, you can write wizards in code.
A wizard in Qt Creator is an instance of a class implementing
the Core::IWizard interface that is registered with ExtensionSystem::PluginManager.
Implementing wizards requires:
\o Deciding on a base class:
\o Core::IWizard is a very generic interface that does
not make any assumption about what the wizard does and
what its UI looks like.
\o Core::BaseFileWizard should be used for wizards that
generate files using a UI based on Utils::Wizard.
\o Providing a set of parameters that determine how the wizard shows up
in the list of wizards in the \gui{New File or Project} dialog.
When deriving from Core::IWizard, virtual functions returning the
values have to be implemented.
When deriving from Core::BaseFileWizard, a parameter class
Core::BaseFileWizardParameters needs to be passed to the constructor,
on which the parameters can be set. This allows for easy creation
of several wizard instances with slightly different parameters.
\o Implementing the wizard UI
Typically, this will be a class derived from Utils::Wizard.
Utils::Wizard extends QWizard with the functionality to show a progress
bar on the left.
\o Implementing the wizard functionality
When deriving from Core::BaseFileWizard, a list of Core::GeneratedFile
needs to be populated with the files and their contents.
\note The files are not actually written to the disk. This will be
done by Core::BaseFileWizard after performing overwrite checks and prompting
the user accordingly.
\section2 Relevant Classes
\o Class
\o Description
\o Core::IWizard
\o Qt Creator wizard interface, implementations of which are registered with
\o Core::BaseFileWizard
\o Inherits Core::IWizard and provides a base class for generating files with a UI
based on QWizard.
\o Core::BaseFileWizardParameters
\o Contains parameters for Core::BaseFileWizard.
\o Core::GeneratedFile
\o A file as produced by Core::BaseFileWizard, containing name, contents and some
\o Utils::FileWizardPage
\o Introductory wizard page asking for file name and path.
\o Utils::FileWizardDialog
\o A wizard dialog presenting a Utils::FileWizardPage, which can be extended
by custom pages.
\o Utils::ProjectIntroPage
\o Introductory wizard page asking for project name and path.
\o ProjectExplorer::BaseProjectWizardDialog
\o Base class for project wizard dialogs, presenting
a Utils::ProjectIntroPage.
\section2 Parameters
The parameters listed below determine how the wizard shows up
in the list of wizards in the \gui{New File or Project} dialog.
Wizards in Qt Creator are grouped by categories.
\o Type
\o Parameter Name
\o Description
\o Core::IWizard::WizardKind
\o kind
\o Enumeration value that indicates the type of the wizard (project, class, file).
\o QIcon
\o icon
\o Icon to show.
\o QString
\o description
\o Descriptive text.
\o QString
\o displayName
\o Name to be shown in the list.
\o QString
\o id
\o Unique identifier for the wizard. It also determines the order within a category.
\o QString
\o category
\o Identifier of the category under which the wizard is to be listed. It also
determines the order of the categories.
\o QString
\o displayCategory
\o Description of the category.
\section1 Example
\section2 Introduction
In this example, we create a wizard
for writing HTML files consisting of a title and a paragraph,
making use of QXmlStreamWriter.
For the UI, we use Utils::FileWizardDialog and extend it by a page
letting the user enter title and contents.
In our BaseFileWizard implementation, we create the file contents
using QXmlStreamWriter.
\section2 The WebContentPageWizardPage Class
Let us start with the wizard page. We use a QLineEdit for the title
and a QPlainTextEdit for the content, arranged in a QGridLayout with
descriptive labels.
\note The QGridLayout was chosen to be able to accommodate the large
vertical span of the QPlainTextEdit. For standard controls, a
QFormLayout should be considered, which will lay out the labels
according to the platform guide lines.
On top of that, we implement validation logic to ensure content is entered.
We implement QWizardPage::isComplete() to return true when both input widgets
have contents, enabling the \gui{Next} button. For this to happen
as the user enters text, we need to connect to the changed() signal of the
controls and emit QWizardPage::completeChanged() once the complete status changes.
\snippet webpagewizard/webpagewizard.h 1
\snippet webpagewizard/webpagewizard.cpp 1
\section2 The WebContentWizardDialog Class
The wizard dialog extends Utils::FileWizardDialog, which presents an
introductory page asking for file name and path.
We add our WebContentPageWizardPage after that.
\snippet webpagewizard/webpagewizard.h 2
\snippet webpagewizard/webpagewizard.cpp 2
\section2 The WebContentWizard Class
In our implementation of Core::BaseFileWizard, we overwrite
createWizardDialog() to return an instance of our WebContentWizardDialog,
initially set to the path passed in. We also add the extension pages
we receive. Extension pages are for example the wizard pages asking for
a project to add the files to and whether to add the files to a version control
In generateFiles(), we obtain the parameters from our wizard and populate
the list of Core::GeneratedFile with our file. To generate the contents,
we use QXmlStreamWriter.
\snippet webpagewizard/webpagewizard.h 3
\snippet webpagewizard/webpagewizard.cpp 3
\section2 Plugin Registration
In order for the wizard to be found by the \gui{New} dialog, we need to
register it with ExtensionSystem::PluginManager, which also takes care
of deleting it:
\snippet webpagewizard/webpagewizardplugin.cpp 0
\section2 Complete Example Code
Here is the complete code of \c webpagewizard.h:
\snippet webpagewizard/webpagewizard.h 0
The complete code of \c webpagewizard.cpp looks as follows:
\snippet webpagewizard/webpagewizard.cpp 0
The registration of the wizard in the \c initialize() method
of a plugin looks like:
\snippet webpagewizard/webpagewizardplugin.cpp 0
......@@ -80,7 +80,7 @@
\o \l{Creating Plugins}
\o \l{Qt Creator Coding Rules}
\o \l{Wizards}
\o \l{Creating Wizards in Code}
\o \l{User Interface Text Guidelines}
......@@ -39,7 +39,7 @@ sources.fileextensions = "*.cpp *.qdoc"
imagedirs = $SRCDIR/images $SRCDIR/templates/images
outputdir = ../api/html
exampledirs =
exampledirs = ../api/examples
indexes = qt.index
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment