IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Débuter dans la création d'interfaces graphiques avec PyQt 4

Image non disponible


précédentsommairesuivant

XII. Doux comme un agneau

Image non disponible

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.

 
Sélectionnez
     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

 
Sélectionnez
private:
     QRect cannonRect() const;

La définition du cadre du canon se situe dans une fonction séparée.

 
Sélectionnez
     int currentAngle;
     int currentForce;
 };

La puissance est stockée dans la variable currentForce.

XII-A-2. t10/cannonField.cpp

 
Sélectionnez
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.

 
Sélectionnez
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.

 
Sélectionnez
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.

 
Sélectionnez
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.

 
Sélectionnez
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

 
Sélectionnez
MyWidget::MyWidget(QWidget *parent)
     : QWidget(parent)
 {

Le constructeur demeure globalement le même : on a juste ajouté quelques détails.

 
Sélectionnez
  LCDRange *force = new LCDRange;
     force->setRange(10, 50);

On a ajouté un nouveau LCDRange qui va être utilisé pour indiquer la puissance.

 
Sélectionnez
     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.

 
Sélectionnez
     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.

 
Sélectionnez
 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

Faire varier la taille du canon en fonction de la puissance.

Placer 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().


précédentsommairesuivant

Copyright © 2009 - 2021 Developpez.com LLC Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.