XII. Doux comme un agneau▲
- tutorials/tutorial/t10/cannonfield.cpp
- tutorials/tutorial/t10/cannonfield.h
- tutorials/tutorial/t10/lcdrange.cpp
- tutorials/tutorial/t10/lcdrange.h
- tutorials/tutorial/t10/main.cpp
- tutorials/tutorial/t10/t10.pro
Dans cet exemple, on ajoute le contrôle de la puissance du canon.
XII-A. Analyse du code ligne par ligne▲
XII-A-1. t10/connonfield.h▲
Le CannonField possède les attributs force (puissance de tir) et angle (angle de tir), définis précédemment.
int angle() const { return currentAngle; }
int force() const { return currentForce; }
public slots:
void setAngle(int angle);
void setForce(int force);
signals:
void angleChanged(int newAngle);
void forceChanged(int newForce);L'interface de la puissance se définit de la même manière que celle de l'angle
private:
QRect cannonRect() const;La définition du cadre du canon se situe dans une fonction séparée.
int currentAngle;
int currentForce;
};La puissance est stockée dans la variable currentForce.
XII-A-2. t10/cannonField.cpp▲
CannonField::CannonField(QWidget *parent)
: QWidget(parent)
{
currentAngle = 45;
currentForce = 0;
setPalette(QPalette(QColor(250, 250, 200)));
setAutoFillBackground(true);
}La puissance est initialisée à zéro.
void CannonField::setAngle(int angle)
{
if (angle < 5)
angle = 5;
if (angle > 70)
angle = 70;
if (currentAngle == angle)
return;
currentAngle = angle;
update(cannonRect());
emit angleChanged(currentAngle);
}On a fait quelques modifications dans la fonction setAngle(). Elle ne redessine que la portion du widget qui contient le canon.
void CannonField::setForce(int force)
{
if (force < 0)
force = 0;
if (currentForce == force)
return;
currentForce = force;
emit forceChanged(currentForce);
}L'implémentation de setForce est similaire à celle de setAngle(). La seule différence réside dans le fait que la valeur de la puissance n'a pas à être représentée ; on n'a donc pas besoin, quand la puissance change, de redessiner le widget.
void CannonField::paintEvent(QPaintEvent * /* event */)
{
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::blue);
painter.translate(0, height());
painter.drawPie(QRect(-35, -35, 70, 70), 0, 90 * 16);
painter.rotate(-currentAngle);
painter.drawRect(QRect(30, -5, 20, 10));
}On dessine comme au chapitre XI.
QRect CannonField::cannonRect() const
{
QRect result(0, 0, 50, 50);
result.moveBottomLeft(rect().bottomLeft());
return result;
}La fonction cannonRect() retourne le cadre contenant le canon dans les coordonnées relatives au widget. On crée d'abord un rectangle de dimensions 50 x 50 ; ensuite on le déplace jusqu'à ce que le coin inférieur gauche coïncide avec le coin inférieur gauche du widget.
La méthode QWidget::rect() retourne le cadre d'un QWidget dans ses propres coordonnées. Les coordonnées du coin supérieur gauche sont toujours (0,0).
XII-A-3. t10/main.cpp▲
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{Le constructeur demeure globalement le même : on a juste ajouté quelques détails.
LCDRange *force = new LCDRange;
force->setRange(10, 50);On a ajouté un nouveau LCDRange qui va être utilisé pour indiquer la puissance.
connect(force, SIGNAL(valueChanged(int)),
cannonField, SLOT(setForce(int)));
connect(cannonField, SIGNAL(forceChanged(int)),
force, SLOT(setValue(int)));On connecte un widget cannonField, comme on l'a fait pour le widget angle.
QVBoxLayout *leftLayout = new QVBoxLayout;
leftLayout->addWidget(angle);
leftLayout->addWidget(force);
QGridLayout *gridLayout = new QGridLayout;
gridLayout->addWidget(quit, 0, 0);
gridLayout->addLayout(leftLayout, 1, 0);
gridLayout->addWidget(cannonField, 1, 1, 2, 1);
gridLayout->setColumnStretch(1, 10);Au chapitre IX, on avait placé le contrôle de l'angle dans la cellule du coin inférieur gauche. À présent, on voudrait deux widgets dans cette cellule. On crée donc une boîte de disposition verticale, on met cette boîte dans la cellule et on ajoute angle et force dans cette boîte.
force->setValue(25);On initialise la puissance à 25.
XII-B. Exécuter l'application▲
On peut maintenant contrôler la valeur de la puissance.
XII-C. Exercices▲
Faites varier la taille du canon en fonction de la puissance.
Placez le canon dans le coin inférieur droit.
Essayez encore d'améliorer l'interface. Par exemple, faites en sorte que les touches + et – du clavier permettent d'augmenter ou de diminuer la puissance et que la touche entrée déclenche le tir. Si vous êtes troublé par le comportement des touches Left et Right, vous pouvez aussi le changer.
Remarque : réimplémentez QWidget::KeyPressEvent().




