Главная · Все классы · Основные классы · Классы по группам · Модули · Функции

Пример "Class Wizard"

Файлы:

Пример "Class Wizard" показывает, как реализовать линейный мастер используя QWizard.

Снимок экрана примера "Class Wizard"

Многие мастера имеют линейную структуру, со страницей 1, следом - страница 2 и так далее до последней страницы. Некоторые более сложные мастера, в которых разрешены разные пути прохождения на основе информации, предоставляемой пользователем. Пример "License Wizard" показывает, как создавать такие мастера.

Пример "Class Wizard" содержит следующие классы:

Определение класса ClassWizard

Страницы мастера классов

Му увидим как создать подкласс QWizard для реализации нашего собственного мастера. Класс конкретного мастера называется ClassWizard и представляет пять страниц:

Хотя программа - это только пример, если вы нажмёте кнопку Finish (Done в Mac OS X), реальные файлы исходного кода C++ будут действительно сгенерированы.

Класс ClassWizard

Вот определение ClassWizard:

 class ClassWizard : public QWizard
 {
     Q_OBJECT

 public:
     ClassWizard(QWidget *parent = 0);

     void accept();
 };

Класс повторно реализует слот QDialog'а, accept(). Этот слот вызывается, когда пользователь щелкает кнопку Finish.

Вот конструктор:

 ClassWizard::ClassWizard(QWidget *parent)
     : QWizard(parent)
 {
     addPage(new IntroPage);
     addPage(new ClassInfoPage);
     addPage(new CodeStylePage);
     addPage(new OutputFilesPage);
     addPage(new ConclusionPage);

     setPixmap(QWizard::BannerPixmap, QPixmap(":/images/banner.png"));
     setPixmap(QWizard::BackgroundPixmap, QPixmap(":/images/background.png"));

     setWindowTitle(tr("Class Wizard"));
 }

Мы создаём экземпляры пяти страниц и вставляем их в мастер, используя QWizard::addPage(). Порядок в котором они вставлены является также порядком, в котором они будут позднее показаны.

Мы вызываем QWizard::setPixmap(), чтобы установить растровые изображения шапки и фона для всех страниц. Шапка используется в качестве фона для заголовка страницы когда стиль мастера ModernStyle; фон используется в качестве фона диалога в MacStyle. (Для получения дополнительной информации смотрите Элементы страницы мастера.)

 void ClassWizard::accept()
 {
     QByteArray className = field("className").toByteArray();
     QByteArray baseClass = field("baseClass").toByteArray();
     QByteArray macroName = field("macroName").toByteArray();
     QByteArray baseInclude = field("baseInclude").toByteArray();

     QString outputDir = field("outputDir").toString();
     QString header = field("header").toString();
     QString implementation = field("implementation").toString();
     ...
     QDialog::accept();
 }

Если пользователь щелкнет кнопку Finish, мы извлечём информацию из нескольких страниц используя QWizard::field() и сгенерируем файлы. Код длинный и утомительный (и просто что-нибудь делает с благородным искусством проектирования мастеров), поэтому большая его часть здесь опущена. Если вы заинтересовались, то за подробностями обращайтесь к реальному примеру из поставки Qt.

Класс IntroPage

Страницы определены в classwizard.h и реализованы в classwizard.cpp, вместе с ClassWizard. Начнём с самой лёгкой страницы:

 class IntroPage : public QWizardPage
 {
     Q_OBJECT

 public:
     IntroPage(QWidget *parent = 0);

 private:
     QLabel *label;
 };

 IntroPage::IntroPage(QWidget *parent)
     : QWizardPage(parent)
 {
     setTitle(tr("Introduction"));
     setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark1.png"));

     label = new QLabel(tr("This wizard will generate a skeleton C++ class "
                           "definition, including a few functions. You simply "
                           "need to specify the class name and set a few "
                           "options to produce a header file and an "
                           "implementation file for your new C++ class."));
     label->setWordWrap(true);

     QVBoxLayout *layout = new QVBoxLayout;
     layout->addWidget(label);
     setLayout(layout);
 }

Страница унаследована от QWizardPage. Мы установили title и watermark pixmap. Не устанавливая любой subTitle мы обеспечиваем, что для этой страницы не будет показан заголовок. (В Windows это обычно для мастеров - показывать растровое изображение водяного знака на первой и последней страницах, а на остальных страницах иметь заголовок.)

Затем мы создаём QLabel и добавляем её в компоновку.

Класс ClassInfoPage

Вторая страница определена и реализована как изложено ниже:

 class ClassInfoPage : public QWizardPage
 {
     Q_OBJECT

 public:
     ClassInfoPage(QWidget *parent = 0);

 private:
     QLabel *classNameLabel;
     QLabel *baseClassLabel;
     QLineEdit *classNameLineEdit;
     QLineEdit *baseClassLineEdit;
     QCheckBox *qobjectMacroCheckBox;
     QGroupBox *groupBox;
     QRadioButton *qobjectCtorRadioButton;
     QRadioButton *qwidgetCtorRadioButton;
     QRadioButton *defaultCtorRadioButton;
     QCheckBox *copyCtorCheckBox;
 };

 ClassInfoPage::ClassInfoPage(QWidget *parent)
     : QWizardPage(parent)
 {
     setTitle(tr("Class Information"));
     setSubTitle(tr("Specify basic information about the class for which you "
                    "want to generate skeleton source code files."));
     setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo1.png"));

     classNameLabel = new QLabel(tr("&Class name:"));
     classNameLineEdit = new QLineEdit;
     classNameLabel->setBuddy(classNameLineEdit);

     baseClassLabel = new QLabel(tr("B&ase class:"));
     baseClassLineEdit = new QLineEdit;
     baseClassLabel->setBuddy(baseClassLineEdit);

     qobjectMacroCheckBox = new QCheckBox(tr("Generate Q_OBJECT &macro"));

     groupBox = new QGroupBox(tr("C&onstructor"));
     ...
     registerField("className*", classNameLineEdit);
     registerField("baseClass", baseClassLineEdit);
     registerField("qobjectMacro", qobjectMacroCheckBox);
     registerField("qobjectCtor", qobjectCtorRadioButton);
     registerField("qwidgetCtor", qwidgetCtorRadioButton);
     registerField("defaultCtor", defaultCtorRadioButton);
     registerField("copyCtor", copyCtorCheckBox);

     QVBoxLayout *groupBoxLayout = new QVBoxLayout;
     ...
 }

Сначала мы установили title, subTitle и logo pixmap страницы. Растровое изображение логотипа выводится на экран в заголовке страницы в ClassicStyle и ModernStyle.

Затем мы создаём дочерние виджеты, создаём поля мастера, связанные с ними, и помещаем их в компоновки. Поле className создано с символом звёздочки(*) после его имени. Это делает его обязательным полем, т.е., поле должно быть заполнено перед тем, как пользователь сможет нажать кнопку Next (Continue в Mac OS X). Значения полей доступны из любой другой страницы с использованием QWizardPage::field(), или из кода мастера используя QWizard::field().

Класс CodeStylePage

Третья страница определена и реализована так:

 class CodeStylePage : public QWizardPage
 {
     Q_OBJECT

 public:
     CodeStylePage(QWidget *parent = 0);

 protected:
     void initializePage();

 private:
     QCheckBox *commentCheckBox;
     QCheckBox *protectCheckBox;
     QCheckBox *includeBaseCheckBox;
     QLabel *macroNameLabel;
     QLabel *baseIncludeLabel;
     QLineEdit *macroNameLineEdit;
     QLineEdit *baseIncludeLineEdit;
 };

 CodeStylePage::CodeStylePage(QWidget *parent)
     : QWizardPage(parent)
 {
     setTitle(tr("Code Style Options"));
     setSubTitle(tr("Choose the formatting of the generated code."));
     setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo2.png"));

     commentCheckBox = new QCheckBox(tr("&Start generated files with a "
     ...
     setLayout(layout);
 }

 void CodeStylePage::initializePage()
 {
     QString className = field("className").toString();
     macroNameLineEdit->setText(className.toUpper() + "_H");

     QString baseClass = field("baseClass").toString();

     includeBaseCheckBox->setChecked(!baseClass.isEmpty());
     includeBaseCheckBox->setEnabled(!baseClass.isEmpty());
     baseIncludeLabel->setEnabled(!baseClass.isEmpty());
     baseIncludeLineEdit->setEnabled(!baseClass.isEmpty());

     if (baseClass.isEmpty()) {
         baseIncludeLineEdit->clear();
     } else if (QRegExp("Q[A-Z].*").exactMatch(baseClass)) {
         baseIncludeLineEdit->setText("<" + baseClass + ">");
     } else {
         baseIncludeLineEdit->setText("\"" + baseClass.toLower() + ".h\"");
     }
 }

Код в конструкторе очень похож на такой же, что мы сделали для ClassInfoPage, поэтому мы пропустили большую его часть.

Функция initializePage() - это то, что делает этот класс интересным. Она повторно реализована из QWizardPage и используется для инициализации некоторых полей страницы с значениями из предыдущей страницы (а именно, className и baseClass). Например, если имя класса на странице 2 - SuperDuperWidget, по умолчанию имя макроса на странице 3 SUPERDUPERWIDGET_H.

Классы OutputFilesPage и ConclusionPage очень похожи на CodeStylePage, поэтому мы не будем рассматривать их здесь.

Смотрите также QWizard, Пример "License Wizard" и Пример "Trivial Wizard".


Copyright © 2008 Trolltech Торговые марки
Qt 4.3.5