[ fromfile: designer-integration.xml id: designer-integration ]
Consider the ProductForm
, a form for Product
instances, shown in Figure 9.17.
QFormLayout is a convenience widget that facilitates organizing QLabel and input widgets in a two-column format.
The ProductForm
widget can accept data from the user for a new Product
object.
It can be used to display (read-only) or edit the values of a stored Product
instance.
The buttons can have text and roles that depend upon the usage mode.
For example, in response to the user adding a new Product, clicking , should result in the values in the form being used to create a new Product
instance.
If instead the user clicks "Cancel", the values would be discarded.
In edit mode, when the user clicks , the values in the form would replace the values in the already stored instance.
In info mode, when the user clicks , the form should dismiss, and the button should be hidden.
While it is used, the ProductForm
has a reference to the Product
it is editing, as shown in Figure 9.18.
The first step is to pick a base classname, (e.g., ProductForm
), and write a header (ProductForm.h
) and implementation file (ProductForm.cpp
) for it, as usual.
Next, create a form in Designer with the same base name (ProductForm.ui
).
Setting the objectName
for the root object of this form (ProductForm
) then enables uic
to generate a header file for a corresponding Ui class (Ui_ProductForm
).
Figure 9.19 shows how uic
takes as input, the special XML file with a .ui extension produced by Designer, and generates a header file that you can #include
in your code.
Example 9.10 shows a small segment of the generated code.
It defines both a Ui_ProductForm
class and a Ui::ProductForm
derived class.
It is your choice which one to use in your C++ code.
As you can see, there is a data member that points to each widget in the Designer form.
The name of each member comes from the object name as set in the Designer form, giving you full control over member names in generated code.
Example 9.10. src/designer/productform/ui_ProductForm.h
[ . . . . ] class Ui_ProductForm { public: QVBoxLayout *verticalLayout; QFormLayout *formLayout; QLabel *label; QDoubleSpinBox *priceSpinbox; QLabel *label_2; QLabel *label_3; QLineEdit *nameLineEdit; QLabel *label_4; QTextEdit *descriptionEdit; QDateEdit *dateEdit; QSpacerItem *verticalSpacer; QDialogButtonBox *buttonBox; void setupUi(QDialog *ProductForm) [ . . . . ] }; namespace Ui { class ProductForm: public Ui_ProductForm {}; } // namespace Ui [ . . . . ]
<include src="src/designer/productform/ui_ProductForm.h" href="src/designer/productform/ui_ProductForm.h" id="ui-productform.h" mode="cpp"/>
What Is a Ui Class? | |
---|---|
A Ui class is a class that contains only auto-generated code produced by the |
QDialog accept() and reject() | |
---|---|
Designer initially connects a couple of signals from the QDialogButtonBox to the QDialog |
Following are three approaches to integration of a Ui class with a custom QWidget-based form class.
Aggregation as a pointer member
Multiple (private) Inheritance
Aggregation as an embedded object
Aggregation by pointer is the recommended (and default) approach because it has the advantage of making it possible to change the Ui file without causing binary breakage with the ProductForm
header file.
Example 9.11 shows aggregation by pointer member.
ProductForm.h
uses a forward class declaration instead of including the Ui_ProductForm.h
directly.
Example 9.11. src/designer/delegation/productform.h
[ . . . . ] #include <QDialog> class Product; class Ui_ProductForm; class QWidget; class QAbstractButton; class ProductForm : public QDialog { Q_OBJECT public: explicit ProductForm(Product* product = 0, QWidget* parent=0); void setModel(Product* model); public slots: void accept(); void commit(); void update(); private: Ui_ProductForm *m_ui; Product* m_model; }; [ . . . . ]
<include src="src/designer/delegation/productform.h" href="src/designer/delegation/productform.h" id="productform-delegation.h" mode="cpp"/>
Only the implementation file, shown in Example 9.12, depends on the uic-generated header file. This makes it easier to place this class into a library, for example.
Example 9.12. src/designer/delegation/productform.cpp
#include <QtGui> #include "productform.h" #include "ui_ProductForm.h" #include "product.h" ProductForm::ProductForm(Product* product, QWidget* parent) : QDialog(parent), m_ui(new Ui::ProductForm), m_model(product) { m_ui->setupUi(this); update(); } void ProductForm::setModel(Product* p) { m_model =p; } void ProductForm::accept() { commit(); QDialog::accept(); } void ProductForm::commit() { if (m_model == 0) return; qDebug() << "commit()"; m_model->setName(m_ui->nameLineEdit->text()); QTextDocument* doc = m_ui->descriptionEdit->document(); m_model->setDescription(doc->toPlainText()); m_model->setDateAdded(m_ui->dateEdit->date()); m_model->setPrice(m_ui->priceSpinbox->value()); } void ProductForm::update() { if (m_model ==0) return; qDebug() << "update()"; m_ui->nameLineEdit->setText(m_model->name()); m_ui->priceSpinbox->setValue(m_model->price()); m_ui->dateEdit->setDate(m_model->dateAdded()); m_ui->descriptionEdit->setText(m_model->description()); }
<include src="src/designer/delegation/productform.cpp" href="src/designer/delegation/productform.cpp" id="productform-delegation.cpp" mode="cpp"/>
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |