Qt Jambi : codons notre première fenêtre

Natim

Dans ce tutoriel, nous allons voir les bases de la création d'un projet en utilisant Qt Jambi. Nous verrons comment ouvrir une fenêtre.

Commentez

- Titre : Qt Jambi : codons notre première fenêtre

- Auteur : Natim

- Parution : 28 avril 2011

- Mise à jour : 5 juillet 2011

- Licence :

Sommaire

- I. Code minimal d'un projet Qt Jambi

- I-A. Analysons pas à pas ...

- I-A-1. QApplication, la classe de base

- I-A-2. Lancement de l'application

- II. Affichage d'un widget

- III. Compilation de notre premier programme en Qt Jambi

- III-A. La classe Test.java

- III-B. Compilation

- III-C. Lancement

- IV. Améliorons notre application...

- V. Remerciements

I - Code minimal d'un projet Qt Jambi

Un projet en Java est composé d'au moins une classe contenant une fonction main. Selon votre EDI, vous pouvez créer un projet Java et y ajouter les bibliothèques (qtjambi.jar en l'occurrence). Voici à quoi doit ressembler la méthode main de votre objet principal :

import com.trolltech.qt.gui.QApplication;
...
public static void main(String[] args) {
QApplication.initialize(args);

QApplication.exec();
}

C'est le code minimal d'une application Qt en Java. Comme vous pouvez le constater, c'est vraiment très court et c'est un des points forts de Qt.

I-A - Analysons pas à pas ...

import com.trolltech.qt.gui.QApplication;

On utilise la classe QApplication de Jambi qui est la classe de base de tout programme Qt. Il faut donc la situer dans l'arborescence pour que le compilateur Java la retrouve. J'ai utilisé le chemin complet car je n'ai utilisé que cet objet. On peut aussi décider d'inclure tous les objets de la GUI comme ceci :

import com.trolltech.qt.gui.*;

D'un point de vue performance, ça ne change rien. D'un point de vue lisibilité du code, ça peut permettre à un programmeur de voir tout de suite de quoi il va s'agir et ce que la classe va utiliser. Je vais dans ce cours utiliser des import explicites dans la mesure du possible (tant que ça ne nuit pas à la lisibilité).

I-A-1 - QApplication, la classe de base

La première ligne du main crée un nouvel objet de type QApplication. Cet objet est un singleton (une classe dont il n'existe qu'une seule instance), cela veut dire qu'on n'en crée aucun objet, on l'utilise seulement. À la différence du C++, il n'y a pas de constructeur, puisqu'on ne crée pas d'objet QApplication. On utilise donc la méthode statique initialize de la classe QApplication pour initialiser l'application et c'est cette méthode qui s'occupe de créer l'instance unique.De manière à pouvoir passer des ordres (comme des options d'affichages par exemple) au framework Qt, on donne les paramètres de la ligne de commande.

I-A-2 - Lancement de l'application

La méthode statique de la classe QApplication permet de lancer l'application. Entre l'initialisation et l'exécution, on va créer nos objets (boîtes de dialogue, fenêtres...). Ce n'est que lors de l'exécution de cette méthode que tout va s'enclencher. Lorsque la méthode exec s'arrête, notre programme est terminé.

II - Affichage d'un widget

Dans la plupart des bibliothèques GUI, dont Qt fait partie, tous les éléments d'une fenêtre sont appelés des widgets. Les boutons, les cases à cocher, les images... tout ça, ce sont des widgets. La fenêtre elle-même est considérée comme un widget. Pour provoquer l'affichage d'une fenêtre, il suffit de demander à afficher n'importe quel widget. Ici, par exemple, nous allons afficher un bouton. Voici le code complet que j'aimerais que vous utilisiez. Il utilise le code de base de tout à l'heure mais y ajoute quelques lignes :

import com.trolltech.qt.gui.QApplication;
import com.trolltech.qt.gui.QPushButton;
...
public static void main(String[] args) {
QApplication.initialize(args);

QPushButton bouton = new QPushButton("Alors, la forme ?");
bouton.show();

QApplication.exec();
}

On a ajouté un import, celui de notre nouveau widget, le QPushButton (un bouton poussoir pour les anglophobes). On crée notre objet bouton avec comme texte "Alors, la forme ?" et on l'affiche. Comme un bouton ne peut pas "flotter" comme ça sur votre écran, Qt l'insère automatiquement dans une fenêtre. On a en quelque sorte créé une "fenêtre-bouton". Bien entendu, dans un vrai programme plus complexe, on crée d'abord une fenêtre et on y insère ensuite plusieurs widgets, mais là on commence simplement. Notre code est prêt, il ne reste plus qu'à compiler et exécuter le programme !

III - Compilation de notre premier programme en Qt Jambi

III-A - La classe Test.java

Pour les exemples, je préfère vous donner le fichier complet :

import com.trolltech.qt.gui.QApplication;
import com.trolltech.qt.gui.QPushButton;

public class Test
{
public static void main(String[] args) {
QApplication.initialize(args);

QPushButton bouton = new QPushButton("Alors, la forme ?");
bouton.show();

QApplication.exec();
}
}

III-B - Compilation

Si vous avez tout installé convenablement, un simple javac devrait fonctionner.

javac Test.java

Si votre classpath n'est pas bien défini, ça ne marchera pas... Je vous conseille de le définir (ça dépend de votre système d'exploitation). Sinon, vous pouvez le définir juste pour cette commande comme cela :

javac -cp /chemin/de/qtjambi.jar:. Test.java

Sous Windows ça ressemblera sûrement plus à :

javac -cp c:\chemin\de\qtjambi.jar:. Test.java

III-C - Lancement

Pour les utilisateurs de Windows et Linux :

java Test

Pour les utilisateurs de Mac OS X :

java -XstartOnFirstThread Test

IV - Améliorons notre application...

Tout à l'heure, on a un peu innové en transformant le »Hello World » habituel par un »Alors, la forme ? ». Maintenant, on peut s'amuser un petit peu avec notre fenêtre-bouton. Ce serait bien que l'on puisse cliquer sur le bouton pour fermer la fenêtre. On peut aussi fixer une taille par défaut ou changer la couleur et la police. Mettre un titre à la fenêtre aussi.

import com.trolltech.qt.core.*;
import com.trolltech.qt.gui.*;

public class HelloWorld
{
public static void main(String args[])
{
// Initialise l'application Qt
QApplication.initialize(args);

// Crée un bouton poussoir, bouton, dont le texte est Alors, la forme ?
QPushButton bouton = new QPushButton("Alors, la forme ?");

// Fixe la taille du bouton à 120x40
bouton.resize(120, 40);

// Fixe la police de caractères en Times 18 Gras
bouton.setFont(new QFont("Times", 18, QFont.Weight.Bold.value()));

// Définit l'action du clic sur le bouton. (on quitte l'application)
bouton.clicked.connect(QApplication.instance(), "quit()");

// Fixe le titre de la fenêtre
bouton.setWindowTitle("Hello World");

// Affiche le bouton
bouton.show();

// Lance l'application //
QApplication.exec();
}
}

C'est bien commenté donc je doute que vous ayez des problèmes pour comprendre. Il y a un point un peu plus compliqué :

bouton.clicked.connect(QApplication.instance(), "quit()");

La méthode connect va nous permettre de mettre une action sur un widget. En l'occurrence, on décide de connecter l'action clicked() de notre bouton à la méthode quit() de notre objet QApplication. Comme QApplication est une classe statique et que la fonction connect attend une instance d'objet, la classe QApplication possède une méthode instance() qui permet de retourner l'objet de notre application principale. Ce que je vous disais tout à l'heure à propos de QApplication, c'est qu'on l'utilisait en tant que classe statique. Cela est une protection. Pour être sûr que les programmeurs ne créent pas deux objets QApplication dans le même programme, les développeurs du framework ont décidé que ce serait la classe elle même qui allait gérer son propre et unique objet. Cet objet est créé par la méthode statique initialize(). Et, lorsqu'on a besoin de l'objet, on utilise la méthode statique instance() pour le récupérer. Comme cela, on est sûr de parler toujours du même objet et, en plus, on n'a pas besoin de se demander si on a accès à notre objet. Il suffit d'importer QApplication pour y avoir accès. On importe les dépendances et ensuite on crée une simple fenêtre avec un bouton qui quitte l'application lorsque l'on clique dessus. Si vous souhaitez compiler en ligne de commande :

# Compiler
javac HelloWorld.java
# Lancer
java HelloWorld.java

Si vous n'avez aucune erreur, c'est que vous êtes prêts à continuer et que vous êtes relativement habiles avec Java. Si vous avez des erreurs, c'est que tout n'est pas encore très bien configuré et qu'il vous faut relire le chapitre expliquant comment installer Qt Jambi.

Nous y sommes enfin arrivés, champagne ! Vous l'avez vu, le code nécessaire pour ouvrir une fenêtre toute simple constituée d'un bouton est ridicule. Quelques lignes à peine et rien de bien compliqué à comprendre au final. C'est ce qui fait la force de Qt : un code simple est un beau code, dit-on. Qt s'efforce de respecter ce dicton à la lettre, vous vous en rendrez compte dans les prochains chapitres. Dans ceux-ci, nous allons voir comment changer l'apparence du bouton, comment faire une fenêtre un peu plus complexe. Nous découvrirons aussi le mécanisme des signaux et des slots, un des principes les plus importants de Qt qui permet de gérer les événements : un clic sur un bouton pourra, par exemple, provoquer l'ouverture d'une nouvelle fenêtre ou sa fermeture !

V - Remerciements

Merci à Thibaut Cuvelier pour la mise en page et à Jacques Thery pour la relecture !