VIII. Construire des widgets en vrac ! ▲
- tutorials/tutorial/t6/main.cpp

#include <QApplication>
#include <QFont>
#include <QGridLayout>
#include <QLCDNumber>
#include <QPushButton>
#include <QSlider>
#include <QVBoxLayout>
#include <QWidget>
class LCDRange : public QWidget
{
public:
LCDRange(QWidget *parent = 0);
};
LCDRange::LCDRange(QWidget *parent)
: QWidget(parent)
{
QLCDNumber *lcd = new QLCDNumber(2);
lcd->setSegmentStyle(QLCDNumber::Filled);
QSlider *slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 99);
slider->setValue(0);
connect(slider, SIGNAL(valueChanged(int)),
lcd, SLOT(display(int)));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(lcd);
layout->addWidget(slider);
setLayout(layout);
}
class MyWidget : public QWidget
{
public:
MyWidget(QWidget *parent = 0);
};
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
QPushButton *quit = new QPushButton(tr("Quit"));
quit->setFont(QFont("Times", 18, QFont::Bold));
connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
QGridLayout *grid = new QGridLayout;
for (int row = 0; row < 3; ++row) {
for (int column = 0; column < 3; ++column) {
LCDRange *lcdRange = new LCDRange;
grid->addWidget(lcdRange, row, column);
}
}
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(quit);
layout->addLayout(grid);
setLayout(layout);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}VIII-A. Analyse du code ligne par ligne ▲
class LCDRange : public QWidget
{
public:
LCDRange(QWidget *parent = 0);
};Le widget LCDRange est un widget sans la moindre méthode : il possède juste un constructeur. Ce genre de widget n'est pas très utile, mais on rajoutera des méthodes plus tard.
LCDRange::LCDRange(QWidget *parent)
: QWidget(parent)
{
QLCDNumber *lcd = new QLCDNumber(2);
lcd->setSegmentStyle(QLCDNumber::Filled);
QSlider *slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 99);
slider->setValue(0);
connect(slider, SIGNAL(valueChanged(int)),
lcd, SLOT(display(int)));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(lcd);
layout->addWidget(slider);
setLayout(layout);
}Ce code est emprunté au constructeur MyWidget du chapitre VII. La seule différence réside dans le fait que le bouton Quit a été enlevé et que la classe a été renommée.
class MyWidget : public QWidget
{
public:
MyWidget(QWidget *parent = 0);
};MyWidget, lui aussi, ne contient aucune méthode : il ne contient qu'un constructeur.
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
QPushButton *quit = new QPushButton(tr("Quit"));
quit->setFont(QFont("Times", 18, QFont::Bold));
connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));Le bouton qui était jusqu'à maintenant inclus dans ce qui s'appelle à présent LCDRange n'en fait plus partie ; désormais on a un bouton Quit unique et plusieurs objets LCDRange
QGridLayout *grid = new QGridLayout;On crée un QWidget avec un QGridLayout qui va contenir trois colonnes.
QGridLayout arrange automatiquement ses widgets en lignes et en colonnes : vous pouvez spécifier les numéros des lignes et des colonnes quand vous ajoutez des widgets à l'objet QGridLayout qui va se charger de les disposer sur la grille.
for (int row = 0; row < 3; ++row) {
for (int column = 0; column < 3; ++column) {
LCDRange *lcdRange = new LCDRange;
grid->addWidget(lcdRange, row, column);
}
}On crée neuf objets LCDRange, qui sont tous des widgets enfants de l'objet grid, et qu'on arrange sur une grille de trois lignes et de trois colonnes.
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(quit);
layout->addLayout(grid);
setLayout(layout);Pour terminer, on ajoute à l'outil de disposition principal le bouton Quit et la grille de disposition grid contenant les objets LCDRange à l'outil de disposition principal. La fonction QWidget::addLayout() est similaire à la fonction QWidget::addWidget() et permet d'ajouter un objet de disposition enfant à l'outil de disposition principal.
C'est tout.
VIII-B. Lancer l'application ▲
Ce programme montre la facilité d'utilisation simultanée de plusieurs widgets. Comme dans le chapitre précédent, chacun se comporte comme l'association d'un curseur et d'un affichage numérique LCD. Là encore, la différence réside dans l'implémentation.
VIII-C. Exercices ▲
Au lancement de l'application, initialisez chaque curseur avec une valeur différente et/ou aléatoire.



