I. Le principe du MVC (Model, View, Controller)▲
Lorsqu'on programme une interface graphique, il est recommandé d'utiliser le principe du MVC.
Je vais vous expliquer ce principe tel que je l'ai compris.Si vous le connaissez mieux que moi, merci de corriger mes erreurs ou imprécisions pour en faire profiter tout le monde.
MVC est une méthode de conception pour le développement d'applications qui permet de séparer le développement en trois parties :
- le modèle de données (le modèle) ;
- l'interface utilisateur (la vue) ;
- la logique de contrôle (le contrôleur).
Vous pouvez lire le très bon article de Wikipédia en français à ce sujet. Pour ceux qui n'ont pas de problèmes avec l'anglais, vous pouvez lire l'explication du MVC dans la doc de Qt ainsi que le très bon article de Steve Burbeck sur la manière d'utiliser cette méthode.
- Le modèle représente le comportement de l'application : traitement des données, interactions avec la base de données, etc. Il décrit les données manipulées par l'application et définit les méthodes d'accès.
- La vue correspond à l'interface avec laquelle l'utilisateur interagit. Les résultats renvoyés par le modèle sont dénués de toute présentation, mais sont présentés par les vues. Plusieurs vues peuvent afficher les informations d'un même modèle. Elle peut être conçue en HTML ou tout autre « langage » de présentation. La vue n'effectue aucun traitement, elle se contente d'afficher les résultats des traitements effectués par le modèle et de permettre à l'utilisateur d'interagir avec eux.
- Le contrôleur prend en charge la gestion des événements de synchronisation pour mettre à jour la vue ou le modèle. Il n'effectue aucun traitement, ne modifie aucune donnée, il analyse la requête du client et se contente d'appeler le modèle adéquat et de renvoyer la vue correspondant à la demande.
On utilise très souvent ce type de méthode pour la réalisation d'applications Web. On peut citer par exemple des framework tels que :
- Ruby on Rails (Ruby) ;
- Django (Python) ;
- Code Igniter (PHP).
Le fait d'utiliser le MVC dans le milieu du Web est un choix de développement très important. Avec Qt, il est aussi largement souhaitable d'utiliser cette méthode.
II. Le principe avec Qt▲
On voit que les objets ont besoin de communiquer entre eux. Prenons pour exemple ce petit programme :
Comme nous pouvons le voir, il est composé d'un QLCDNumber, d'un QSlider et d'un QPushButton, le tout agencé dans un QVBoxLayout. Vous pouvez le réaliser comme cela :
import
com.trolltech.qt.gui.QApplication;
import
com.trolltech.qt.gui.QWidget;
import
com.trolltech.qt.gui.QLCDNumber;
import
com.trolltech.qt.gui.QSlider;
import
com.trolltech.qt.gui.QPushButton;
import
com.trolltech.qt.gui.QVBoxLayout;
import
com.trolltech.qt.core.Qt;
public
class
MonLCD1 extends
QWidget
{
public
MonLCD1
(
)
{
QLCDNumber lcd =
new
QLCDNumber
(
2
);
QSlider slider =
new
QSlider
(
Qt.Orientation.Horizontal);
QPushButton quit =
new
QPushButton
(
tr
(
"Quit"
));
QVBoxLayout layout =
new
QVBoxLayout
(
);
layout.addWidget
(
lcd);
layout.addWidget
(
slider);
layout.addWidget
(
quit);
setLayout
(
layout);
setWindowTitle
(
tr
(
"Mon LCD"
));
}
public
static
void
main
(
String args[])
{
QApplication.initialize
(
args);
MonLCD1 widget =
new
MonLCD1
(
);
widget.show
(
);
QApplication.exec
(
);
}
}
Si vous lancez le code, vous verrez que ce n'est qu'une simple boîte de dialogue avec quelques widgets posés dedans. Le but, maintenant, ce serait de connecter un peu tout cela, pour que, lorsqu'on bouge le slider ça change la valeur inscrite sur le LCD et que lorsque l'on clique sur le bouton Quit, ça quitte l'application.
III. Les principes de signaux▲
Si on regarde la doc pour la classe QSlider, on voit que celle-ci possède les signaux suivants :
Signal | Description |
---|---|
valueChanged | Ce signal est émis lorsque la valeur du slider a changé. |
sliderPressed | Ce signal est émis lorsque l'utilisateur commence à déplacer le slider. |
sliderMoved | Ce signal est émis lorsque l'utilisateur bouge le slider. |
sliderReleased | Ce signal est émis lorsque l'utilisateur relâche le bouton. |
Pour savoir qu'un signal a été émis, on doit le connecter à une méthode. Dans le cas de notre objet, ce qui pourrait être bien, c'est d'afficher la valeur de notre slider sur l'écran LCD.
IV. Connecter notre signal▲
Ce qu'il nous faut, c'est changer la valeur du LCD en fonction de celle du slider. La méthode display() de QLCDNumber nous permet de faire cela. Le signal envoyé par valueChanged nous donne la valeur modifiée. Il nous suffit donc de connecter le signal valueChanged(int) du slider avec la méthode display(int) de lcd. Voici comment on fait cela :
slider.valueChanged.connect
(
lcd, "display(int)"
);
De même, nous souhaitons que notre bouton quitte l'application. Nous allons donc connecter le signal clicked() du bouton à la méthode quit() de QApplication .Cependant, nous avons besoin de passer en paramètre la référence de l'objet QApplication. Pour la récupérer, il nous faut utiliser QApplication.instance().
quit.clicked.connect
(
QApplication.instance
(
), "quit()"
);
Ajoutez ces deux lignes à la fin du constructeur de MonLCD et observez le résultat...
V. Une application fonctionnelle ▲
Pour bien faire les choses, nous aurions pu créer un nouveau widget LCDRange qui soit un LCD modifiable par un slider. Voici ce que ça donne avec quelques modifications de style en plus :
import
com.trolltech.qt.gui.*;
import
com.trolltech.qt.core.Qt;
public
class
MonLCD extends
QWidget
{
public
MonLCD
(
)
{
LCDRange lcdRange =
new
LCDRange
(
);
QPushButton quit =
new
QPushButton
(
tr
(
"Quit"
));
quit.setFont
(
new
QFont
(
"Times"
, 18
, QFont.Weight.Bold.value
(
)));
quit.clicked.connect
(
QApplication.instance
(
), "quit()"
);
QVBoxLayout layout =
new
QVBoxLayout
(
);
layout.addWidget
(
lcdRange);
layout.addWidget
(
quit);
setLayout
(
layout);
setWindowTitle
(
tr
(
"Mon LCD"
));
}
class
LCDRange extends
QWidget
{
public
LCDRange
(
)
{
QLCDNumber lcd =
new
QLCDNumber
(
2
);
lcd.setSegmentStyle
(
QLCDNumber.SegmentStyle.Filled);
QSlider slider =
new
QSlider
(
Qt.Orientation.Horizontal);
slider.setRange
(
0
, 99
);
slider.setValue
(
0
);
slider.valueChanged.connect
(
lcd, "display(int)"
);
QVBoxLayout layout =
new
QVBoxLayout
(
);
layout.addWidget
(
lcd);
layout.addWidget
(
slider);
setLayout
(
layout);
}
}
public
static
void
main
(
String args[])
{
QApplication.initialize
(
args);
MonLCD widget =
new
MonLCD
(
);
widget.show
(
);
QApplication.exec
(
);
}
}
VI. Un petit exercice▲
Pour mettre en œuvre tout ce que nous avons vu au cours des précédents chapitres, vous pouvez essayer de faire quelque chose dans le genre :
VII. Remerciements▲
Merci à Thibaut Cuvelier pour la mise en page et à Jacques Thery pour la relecture !