JC – février 2007

Atelier Coagul

Programmation C++ avec Qt – suite 1

Préambule

Cet atelier fait suite à l'atelier du 6 février 2007 dont le but était de montrer les facilités apportées à la programmation d'une interface graphique utilisateur (GUI) par un tool-kit tel que Qt, créé et distribué par Trolltech (http://www.trolltech.com/qt).

Prérequis

Connaissances :

Comme pour le précédent atelier, quelques connaissances de la programmation objet (quelque soit le langage) seraient utiles, mais pas absolument indispensables.

Ceux qui souhaiteraient en savoir davantage sur le C++ peuvent lire un des nombreux livres existant sur le sujet.

Installation :

Rappelons que pour exécuter les démonstrations, il faut avoir au préalable installé Qt 4.x.x version Open Source pour Linux. (à partir des sources : temps de compilation relativement long, ou à partir de paquets rpm – voir http://www.trolltech.com/qt).

N'oubliez pas d'ajouter les lignes suivantes :

PATH=/usr/local/Trolltech/Qt-4.2.1/bin:$PATH

export PATH

à votre fichier (caché) profile (ou login, ou bash_profile selon votre distribution) afin de pouvoir exécuter les commandes de compilation des programmes de démonstration.

Présentation de l'atelier

L'atelier comportera plusieurs étapes successives, faisant suite à l'atelier du 6 février. Chacun pourra compiler, s'il le désire, les programmes correspondants et voir le résultat de leur exécution.

Rappelons succinctement les étapes de l'atelier du 6 février :

Première étape (projet demo1) on a créé une application très simple et découvert les outils fournis par Qt pour gérer les projets.

Deuxième étape (projet demo2) : on enrichi notre application en la dotant d'un éditeur de textes.

Troisième étape (projet demo3) : cette étape a montré comment on peut répartir le code du projet entre plusieurs fichiers (même si la taille du projet ne le justifie pas).

On poursuit maintenant avec les étapes suivantes :

Quatrième étape (projet demo4) : ajout d'une barre d'outils et de deux entrées de menu, essai du dialogue d'ouverture de fichier.

Cinquième étape (projet demo5) : créer un dialogue avec Qt Designer et voir comment on peut l'utiliser dans notre application ;

Sixième étape (projet demo6) : utiliser Qt Linguist pour traduire les textes des menus et des messages.

Quatrième étape : le projet demo4

Dans cette quatrième étape, on ajoute une barre d'outils et de deux entrées de menu, ceci permettra de voir la gestion des ressources (ici une seule icône) et de tester le dialogue d'ouverture de fichier proposé par Qt.

Les fichiers du projet, leur listing et les commentaires

Le fichier d'en-tête demowindow.h

#include <QMainWindow>

class QAction;

class QMenu;

class QTextEdit;

class DemoWindow : public QMainWindow

{

Q_OBJECT //demo4

public:

DemoWindow(); //constructeur

QAction *openAct; //demo4

QAction *testAct; //demo4

QAction *exitAct;

QMenu *fileMenu;

QToolBar *fileToolBar; //demo4

QTextEdit *editeur;

private slots: //demo4

void open(); //demo4

void test(); //demo4

};

Commentaires :

Ce fichier regroupe les déclarations des classes utilisées dans le projet et les prototypes des fonctions.

Il reprend le fichier d'en-tête de l'étape 4 auquel on a ajouté les éléments suivants :

On mentionne la macro Q_OBJECT afin de pouvoir utiliser le mécanisme SIGNAL/SLOTS dans notre objet DemoWindow.

On définit deux pointeurs sur des instances de la classe QAction : openAct et testAct.

On ajoute un pointeur sur une instance fileToolBar de la classe QtoolBar.

Enfin, on définit les deux fonctions open() et test(). Ces deux fonctions sont définies comme étant des slots que l'on pourra donc connecter à un signal.

Le fichier source demowindow.cpp

#include <QtGui>

#include "demowindow.h"

DemoWindow::DemoWindow() //constructeur

{

openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); //demo4

openAct->setShortcut(tr("Ctrl+O")); //demo4

openAct->setStatusTip(tr("Open an existing file")); //demo4

connect(openAct, SIGNAL(triggered()), this, SLOT(open())); //demo4

testAct = new QAction(tr("Test"), this); //demo4

testAct->setShortcut(tr("Ctrl+T")); //demo4

testAct->setStatusTip(tr("To make tests")); //demo4

connect(testAct, SIGNAL(triggered()), this, SLOT(test())); //demo4

exitAct = new QAction(tr("E&xit"), this);

exitAct->setShortcut(tr("Ctrl+Q"));

exitAct->setStatusTip(tr("Exit the application"));

connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));

fileMenu = menuBar()->addMenu(tr("&File"));

fileMenu->addAction(openAct); //demo4

fileMenu->addAction(testAct); //demo4

fileMenu->addSeparator(); //demo4

fileMenu->addAction(exitAct);

fileToolBar = addToolBar(tr("File")); //demo4

fileToolBar->addAction(openAct); //demo4

editeur=new QTextEdit;

setCentralWidget(editeur);

resize(400, 300);

statusBar()->showMessage(tr("Ready"));

}

void DemoWindow::open() //demo4

{

QString fileName = QFileDialog::getOpenFileName(this);

if (!fileName.isEmpty())

QMessageBox::information(this, "test open", "file to open :\n"+fileName);

}

void DemoWindow::test() //demo4

{

QMessageBox::information(this, "test", "un test");

}

Commentaires :

Modifications du constructeur de DemoWindow :

On commence par créer la QAction openAct, à laquelle on associe l'icône open.png stockée dans le sous répertoire images. Puis on défini le raccourcis clavier, le texte informatif associé, et on connecte le signal émis par cette QAction lorsqu'on cliquera sur la commande correspondante au slot open() de notre DemoWindow.

Ensuite on fait de même pour la QAction testAct. (il n'y a pas d'icône associée).

Les lignes concernant exitAct sont inchangées.

On ajoute les deux commandes associées aux nouvelles QAction au menu File, ainsi qu'un séparateur avant la commande Exit.

Enfin on crée la barre d'outils sur laquelle on place la commande Open.

Ajout du code de la fonction void DemoWindow::open()

On appelle le dialogue fourni par Qt pour choisir le nom d'un fichier à ouvrir, ce nom est stocké dans la variable fileName de type Qstring.

Puis on effectue un test : si cette variable n'est pas vide (un nom de fichier a été sélectionné et on a cliqué sur le bouton Ok de la boite de dialogue) on affiche le nom du fichier dans une simple boite de dialogue (dans une application réelle il faudrait ici écrire le code permettant l'ouverture du fichier, mais cela dépasse le cadre de cet atelier).

Ajout du code de la fonction void DemoWindow::test()

On se contente dans cette 4ème étape d'afficher une boite de dialogue.

Le fichier source main.cpp

Ce fichier est inchangé.

Le fichier de ressources demo.qrc

<!DOCTYPE RCC><RCC version="1.0">

<qresource>

<file>images/open.png</file>

</qresource>

</RCC>

Ce fichier texte (de type Xml, qui liste les images utilisées – ici une seule !) sera pris en compte lors de la création du fichier de projet demo4.pro pour être compilé.

Compilation et exécution

Ouvrir une console et se placer dans le répertoire demo4.

Exécuter la commande qmake -project : le fichier de projet demo4.pro est créé en fonction des fichiers contenus dans le répertoire du projet. Examiner le contenu de demo4.pro : le fichier demo.qrc est bien pris en compte.

Exécuter ensuite la commande qmake : le fichier Makefile est créé en fonction des éléments contenus dans demo4.pro.

Exécuter la commande make : le fichier exécutable demo4 est créé.

Exécuter la commande demo4 : l'application qui vient d'être créée est lancée, on peut tester le fonctionnement des deux nouvelles commandes que propose le menu File.

Cinquième étape : le projet demo5

Cette cinquième étape nous permettra de créer une boite de dialogue avec QtDesigner et son utilisation dans l'application à partir de la commande File/Test.

Création du dialogue avec QtDesigner

Nous allons tout d'abord réaliser avec QtDesigner le dialogue simple ci-après :

Dans le terminal, taper la commande designer

QtDesigner est lancé et vous propose de créer une New Form. On choisi (par exemple) Dialog with Buttons Bottom et on clique sur Create : un dialogue est édité avec le titre « untitled » et les deux boutons Ok et Cancel.

Dans la fenêtre Property Editor de Qt Designer :

on donne un nom à l'objet dialogue : on renseigne la ligne objectName en inscrivant demoDialog par exemple (c'est sous ce nom qu'il faudra faire appel au dialogue dans l'application) ;

on donne un titre à la fenêtre du dialogue : on renseigne la ligne windowTitle en inscrivant Demonstration Dialog par exemple.

On ajoute maintenant un Label et dans la fenêtre Property Editor on modifie le texte du label, on inscrit par exemple « Type some words : »

Enfin on ajoute une ligne de saisie (line edit) et on conserve son nom proposé par QtDesigner : lineEdit (c'est sous ce nom qu'il faudra faire appel à la ligne de saisie dans l'application)

La construction du dialogue est teminée et on sauvegarde notre travail dans le fichier dlgdemo.ui dans le répertoire demo5.

Utilisation du dialogue

Fichiers projet et makefile

Ouvrir une console et se placer dans le répertoire demo5.

Exécuter la commande qmake -project : le fichier de projet demo5.pro est créé en fonction des fichiers contenus dans le répertoire du projet. Examiner le contenu de demo5.pro : le fichier dlgdemo.ui est bien pris en compte.

Exécuter ensuite la commande qmake : le fichier Makefile est créé en fonction des éléments contenus dans demo5.pro.

Modifications du fichier source demowindow.cpp

Trois méthodes sont décrites dans QtAssistant pour utiliser dans une application un composant créé avec QtDesigner. On utilisera ici la plus simple qui convient bien pour un dialogue simple (« approche directe » – cf QtAssistant)

On commence par inclure le fichier ui_dlgdemo.h (ce fichier n'existe pas encore, il sera créé lors de la compilation du projet car le fichier dlgdemo.ui est bien pris en compte dans le fichier demo5.pro).

Ensuite on réécrit la fonction (slot) DemoWindow::test()

void DemoWindow::test() //demo5

{

//créer le dialogue

QDialog *d = new QDialog; //dialogue standard

Ui::demoDialog dd; //interface déduite du fichier demodialog.ui

dd.setupUi(d); //initialisation du dialogue standard avec l'interface

// exécution de la boite de dialogue

int ret=d->exec();

// récupération des modifications éventuelles

if (ret==QDialog::Accepted) //on a cliqué sur Ok

{

QString motSaisi=dd.lineEdit->text(); //récupération du texte saisi

if (!motSaisi.isEmpty()) editeur->insertPlainText(motSaisi); //insertion dans l'éditeur

}

}

Compilation et exécution :

Exécuter la commande make : le fichier exécutable demo5 est créé.

Exécuter la commande demo5 : l'application qui vient d'être créée est lancée, on peut tester le fonctionnement de notre boite de dialogue.

Sixième étape : le projet demo6

Cette sixième étape montre comment utiliser Qt Linguist pour traduire les textes des menus et des messages. (les explications sont relativement concises, pour plus de détails se référer à l'abondante documentation fournie avec Qt).

Ajouter la ligne :

TRANSLATIONS += demo_fr.ts

dans demo6.pro

Exécuter la commande :

lupdate -verbose demo6.pro

cela entraine la création du fichier demo_fr.ts (fichier XML)

On tape ensuite la commande :

linguist

qui lance QtLinguist.

Ouvrir demo_fr.ts et faire les traductions.

Enfin dans QtLinguist on exécute la commande :

release

le fichier demo_fr.qm est ainsi créé.

Pour que notre application puisse utiliser ce fichier de traduction, il faut apporter les modifications suivantes à main.cpp

fonction main :

#include <QApplication>

#include <QTranslator> //pour les traductions

#include <QLocale> //pour les traductions

#include <QFileInfo> //pour les traductions

#include "demowindow.h"

int main(int argc, char *argv[])

{

QApplication app(argc, argv);

//pour les traductions début

QString dirExe=argv[0];

dirExe = QFileInfo(dirExe).absolutePath();

QString locale = QLocale::system().name();

QTranslator translator;

translator.load(dirExe+"/demo_" + locale);

app.installTranslator(&translator);

//pour les traductions fin

DemoWindow mainWin;

mainWin.show();

return app.exec();

}

Il n'y a pas de modification à apporter aux autres fichiers sources.

Si le fichier demo_fr.qm est trouvé au lancement de l'application, la traduction est effectuée, sinon les textes sont affichés en Anglais. De même si un mot n'a pas été traduit, il sera affiché en Anglais.

page 8/8

2006-12-20T13:14:26