Vous êtes sur la page 1sur 89

Interface Utilisateur Graphique (GUI)

Notion de fentre Utilisation des classes : QWidget, QDialog et QMainWindow Les layouts Bote de dialogue modale et non modale Les application SDI et MDI Utilisation des classes : QAction, QMenu, QToolBar, QDockWidget et QStatusBar Graphique et dessin 2D : le framework Graphics View et QPainter QPicture et QImage La gestion d'vnement souris et le glisser-dposer (drag & drop)
(2011-2012)

t.vaira

Interface Utilisateur Graphique

t.vaira

(2011-2012)

Les exemples de Qt

Tous les exemples de ce cours sont disponibles l'adresse suivante : http://tvaira.free.fr/dev/qt/exemples-qt.zip La documentation de Qt fournit de nombreux exemples (plus de 400), notamment :

http://developer.qt.nokia.com/doc/examples-widgets.html http://developer.qt.nokia.com/doc/dialogs-standarddialogs.html http://developer.qt.nokia.com/doc/examples-mainwindow.html http://developer.qt.nokia.com/doc/widgets-windowflags.html http://developer.qt.nokia.com/doc/examples-layouts.html

t.vaira

(2011-2012)

La classe QWidget
La classe QWidget :

hrite de QObject est la classe mre de toutes les classes servant raliser des interfaces graphiques

Les widgets :

sont capable de se "peindre" sont capable de recevoir les vnements souris, clavier sont les lments de base des interfaces graphiques sont tous rectangulaires ils sont ordonns suivant laxe z (gestion de la profondeur) ils peuvent avoir un widget parent
4

t.vaira

(2011-2012)

Notion de fentre

Un widget qui n'est pas incorpor dans un widget parent est appel une fentre. Habituellement, les fentres ont un cadre et une barre de titre, mais il est galement possible de crer des fentres sans dcoration en utilisant des proprits spcifiques (window flags). Dans Qt, QMainWindow et les diffrentes sous-classes de QDialog sont les types de fentres les plus courantes.

t.vaira

(2011-2012)

Les widgets

Il existe beaucoup de sous-classes de QWidget qui fournissent une relle fonctionnalit, telle que QLabel, QPushButton, QListWidget et QTabWidget. Les widgets qui ne sont pas des fentres sont des widgets enfants, affichs dans leur widget parent. La plupart des widgets dans Qt sont principalement utiles en tant que widgets enfants. Par exemple, il est possible d'afficher un bouton en tant que fentre de haut niveau, mais on prfre gnralement mettre les boutons l'intrieur d'autres widgets, tels que QDialog.

t.vaira

(2011-2012)

Widget : exemple n1

Un widget est toujours cr cach, il est donc ncessaire d'appeler la mthode show() pour l'afficher
#include <QApplication> #include <QLabel> int main( int argc, char* argv[] ) { QApplication onAppli( argc, argv )! QLabel *p on"e#te $ ne% QLabel( Q&tring''(rom)t(*(+<,-><center>.on/our 0 tou1<2center><2,->+), 3)LL)! p on"e#te4>1ho%()! 6 return onAppli5e#ec()!

t.vaira

(2011-2012)

Widget : exemple n2

D'une manire gnrale, les widgets sont hirarchiquement inclus les uns dans les autres. Le principal avantage est que si le parent est dplac, les enfants le sont aussi. On ajoute un bouton et les deux lments seront inclus dans un mme widget :
#include <QApplication> #include <QLabel> #include <Q7u1h.utton> int main( int argc, char* argv[] ) { QApplication onAppli( argc, argv )! Q8idget *p a9enetre $ ne% Q8idget()! QLabel* p on"e#te $ ne% QLabel(+555+, p a9enetre)! Q7u1h.utton *p on.outon $ ne% Q7u1h.utton(+Quitter+, p a9enetre)! p a9enetre4>1ho%()! 6 return onAppli5e#ec()!

Widget parent Widgets enfants

t.vaira

(2011-2012)

Widget : exemple n3

Pour rendre actif le bouton, on connecte le signal clicked() mis par l'objet pMonBouton au slot quit() de l'objet MonAppli :
#include <QApplication> #include <QLabel> #include <Q7u1h.utton> int main( int argc, char* argv[] ) { QApplication onAppli( argc, argv )! Q8idget *p a9enetre $ ne% Q8idget()! QLabel* p on"e#te $ ne% QLabel(+555+,p a9enetre)! Q7u1h.utton *p on.outon $ ne% Q7u1h.utton(+Quitter+, p a9enetre)! Q:b/ect''connect(p on.outon, &;<3AL(clic=ed()), > onAppli, &L:"(?uit()))! p a9enetre4>1ho%()! return 6 onAppli5e#ec()!

Si on clique sur le bouton, on quitte l'application. Les applications doivent se terminer proprement en appelant QApplication::quit(). Cette mthode est appele automatiquement lors de la fermeture du dernier widget.

t.vaira

(2011-2012)

Widget : exemple n4

Les sous-classes de QWidget possdent de nombreuses mthodes qui permettent d'agir sur l'aspect visuel :
int main( int argc, char* argv[] ) { QApplication onAppli( argc, argv )! Q8idget *p a9enetre $ ne% Q8idget()! QLabel* p on"e#te $ ne% QLabel(+<h@><em>.on/our 0 tou1<2em><2h@>+,p a9enetre)! Q7u1h.utton *p on.outon $ ne% Q7u1h.utton(+Quitter+,p a9enetre)! p p p p on.outon4>1et<eometrA(B,B,p on"e#te4>%idth(),CB)! on.outon4>move(DB, DB)! on.outon4>re1iEe(-DB, DB)! on.outon4>1et9ont(Q9ont(+Arial+, -*, Q9ont''.old))!

Q:b/ect''connect(p on.outon, &;<3AL(clic=ed()), > onAppli, &L:"(?uit()))! p a9enetre4>1ho%()! return 6 onAppli5e#ec()!

t.vaira

(2011-2012)

10

Widget : exemple n5

Les feuilles de style Qt (QSS) sont un mcanisme puissant qui permet de personnaliser l'apparence des widgets. Les concepts, la terminologie et la syntaxe des feuilles de style Qt sont fortement inspirs par les feuilles de style en cascade (CSS) utilises en HTML mais adaptes au monde de widgets.
int main( int argc, char* argv[] ) { QApplication onAppli( argc, argv )! Q8idget *p a9enetre $ ne% Q8idget()! Q9ile (ile(+?112de(ault5?11+)! i(((ile5open(Q9ile''Fead:nlA)) { Q&tring 1tAle&heet $ QLatin-&tring((ile5readAll())! onAppli51et&tAle&heet(1tAle&heet)! 6 555 p on.outon4>1et&tAle&heet(+bac=ground4color' green+)! 555 return onAppli5e#ec()! 6

t.vaira

(2011-2012)

11

Les layouts (1/2)

Qt fournit un systme de disposition (layout) pour l'organisation et le positionnement automatique des widgets enfants dans un widget. Ce gestionnaire de placement permet l'agencement facile et le bon usage de l'espace disponible. Qt inclut un ensemble de classes QxxxLayout qui sont utiliss pour dcrire la faon dont les widgets sont disposs dans l'interface utilisateur d'une application. Toutes les sous-classes de QWidget peuvent utiliser les layouts pour grer leurs enfants. QWidget::setLayout() applique une mise en page un widget. Lorsqu'un layout est dfini sur un widget de cette manire, il prend en charge les tches suivantes : Positionnement des widgets enfants Gestion des tailles (minimale, prfre) Redimensionnement Mise jour automatique lorsque le contenu change

t.vaira

(2011-2012)

12

Les layouts (2/2)

Quelques layouts : horizontal, vertical, grille, formulaire ...

QHBoxLayout

QFormLayout

QGridLayout

QVBoxLayout

t.vaira

(2011-2012)

13

Widget : exemple n6 (1/3)

On peut rutiliser les widgets de Qt : Par hritage : extension d'un type de widget Par composition : assemblage de widgets
#i(nde( #de(ine G8;H<I"J, G8;H<I"J,

#include <Q8idget> #include <QLKH3umber> #include <Q&lider> cla11 A8idget ' public Q8idget { QJ:.LIK" public' A8idget( Q8idget *parent $ B )! privateM' QLKH3umber *lcd! Q&lider *1lider!

6!

#endi(

t.vaira

(2011-2012)

14

Widget : exemple n6 (2/3)


On instancie deux objets widgets : la barre QSlider et l'affichage LCD QLCDNumber. On connecte : slider->valueChanged(int) (mthode dclencheuse) lcd->display(int) (mthode dclenche)
#include <QN.o#LaAout> #include +mA%idget5h+ A8idget'' A8idget( Q8idget *parent ) ' Q8idget( parent ) { lcd $ ne% QLKH3umber( thi1 )! Il n'y a pas de delete car le 1lider $ ne% Q&lider( Qt'',oriEontal, thi1 )! widget parent se chargera de QN.o#LaAout *mainLaAout $ ne% QN.o#LaAout! mainLaAout4>add8idget(lcd)! la destruction de ses widgets mainLaAout4>add8idget(1lider)! enfants. 1etLaAout(mainLaAout)! 6 connect( 1lider, &;<3AL(valueKhanged(int)), lcd, &L:"(di1plaA(int)) )!

t.vaira

(2011-2012)

15

Widget : exemple n6 (3/3)

Pour finir, on instancie notre nouveau widget et on l'affiche :

#include <QApplication> #include +mA%idget5h+ int main( int argc, char **argv ) { QApplication a( argc, argv )! A8idget %! %51ho%()! 6 return a5e#ec()!

t.vaira

(2011-2012)

16

Encapsulation de Widgets

Exemple de widgets Qt encapsulant d'autres widgets : QGroupBox, QTabWidget

t.vaira

(2011-2012)

17

Widget : exemple n7 (1/3)

En utilisant QStyleFactory::keys(), on obtient la liste des styles disponibles :


#include <QApplication> #include <Qt<ui> #include <QHebug> cla11 AHialog ' public QHialog { QJ:.LIK" public' AHialog(Q8idget *parent) ' QHialog(parent) { QKombo.o# *1tAleKombo.o# $ ne% QKombo.o#! 1tAleKombo.o#4>add;tem1(Q&tAle9actorA''=eA1())! ?Hebug() << Q&tAle9actorA''=eA1()! QLabel *1tAleLabel $ ne% QLabel(tr(+>&tAle '+))! 1tAleLabel4>1et.uddA(1tAleKombo.o#)! connect(1tAleKombo.o#, &;<3AL(activated(Q&tring)), thi1, &L:"(change&tAle(Q&tring)))! O 6

t.vaira

(2011-2012)

18

Widget : exemple n7 (2/3)

La classe QStyle est une classe de base abstraite qui encapsule le look and feel de l'interface graphique. Qt contient un ensemble de sous-classes QStyle qui mulent les styles des diffrentes plates-formes prises en charge par Qt (QWindowsStyle, QMacStyle, QMotifStyle, etc.) Par dfaut, ces modles sont construits dans la bibliothque QtGui. On peut changer pendant l'excution le style de l'application avec setStyle() :
555 private 1lot1' void change&tAle(con1t Q&tring >1tAle3ame) { QApplication''1et&tAle(Q&tAle9actorA''create(1tAle3ame))! QApplication''1et7alette(QApplication''1tAle()4>1tandard7alette())! 6 6!

t.vaira

(2011-2012)

19

Widget : exemple n7 (2/3)

La classe QStyle est une classe de base abstraite qui encapsule le look and feel de l'interface graphique. Qt contient un ensemble de sous-classes QStyle qui mulent les styles des diffrentes plates-formes prises en charge par Qt (QWindowsStyle, QMacStyle, QMotifStyle, etc.) Par dfaut, ces modles sont construits dans la bibliothque QtGui.

t.vaira

(2011-2012)

20

La classe QDialog

La classe QDialog est la classe de base des fentres de dialogue. Elle hrite de QWidget. Une fentre de dialogue (ou bote de dialogue) est principalement utilise pour des tches de courte dure et de brves communications avec l'utilisateur. Une fentre de dialogue (ou bote de dialogue) :

peut tre modale ou non modale. peut fournir une valeur de retour peut avoir des boutons par dfaut peut aussi avoir un QSizeGrip (une poigne de redimensionnement) dans le coin infrieur droit Exemple n3

t.vaira

(2011-2012)

21

Bote de dialogue non modale

Une bote de dialogue non modale (modeless dialog) est un dialogue qui fonctionne indpendamment des autres fentres de la mme application. Exemple : rechercher du texte dans les traitements de texte Une bote de dialogue non modale est affiche en utilisant show() qui retourne le contrle l'appelant immdiatement. Remarque : si la bote de dialogue est visuellement cache, il suffira d'appeler successivement show(), raise() et activateWindow() pour la replacer sur le dessus de la pile.

t.vaira

(2011-2012)

22

QDialog : exemple n1

Pour crer sa propre bote de dialogue, il suffit de crer une classe qui hrite de QDialog.
#include <QApplication> #include <Qt<ui> cla11 AHialog ' public QHialog { public' AHialog() {6 6! int main(int argc, char *argv[]) { QApplication app(argc, argv)! AHialog mAHialog! mAHialog51ho%()! 6 return app5e#ec()!

Bote de dialogue non modale

t.vaira

(2011-2012)

23

Bote de dialogue modale

Une bote de dialogue modale (modal dialog) est un dialogue qui bloque l'entre d'autres fentres visibles de la mme application. Exemple : les dialogues qui sont utiliss pour demander un nom de fichier ou qui sont utiliss pour dfinir les prfrences de l'application sont gnralement modaux. Remarque : les dialogues peuvent tre application modale (par dfaut) ou fentre modale.

La faon la plus commune pour afficher une bote de dialogue modale est de faire appel sa fonction exec(). Lorsque l'utilisateur ferme la bote de dialogue, exec() fournira une valeur de retour utile. Remarque : une alternative est d'appeler setModal(true) ou setWindowModality(), puis show(). Contrairement exec(), show() retourne le contrle l'appelant immdiatement (voir QProgressDialog).

t.vaira

(2011-2012)

24

QDialog : exemple n2

Pour fabriquer une bote de dialogue, il suffit de crer une classe qui hrite de QDialog.
#include <QApplication> #include <Qt<ui> cla11 AHialog ' public QHialog { public' AHialog() {6 6! int main(int argc, char *argv[]) { QApplication app(argc, argv)! AHialog mAHialog! 6 return mAHialog5e#ec()!

Bote de dialogue modale

t.vaira

(2011-2012)

25

Les botes de dialogue Qt (1/2)

Qt fournit un certain nombre de bote de dialogue prtes l'emploi : La classe QInputDialog fournit un dialogue simple pour obtenir une valeur unique de l'utilisateur. La valeur d'entre peut tre une chane, un numro ou un lment d'une liste (getText, getInt, getDouble, getItem). Une tiquette (Label) doit tre place afin de prciser l'utilisateur ce qu'il doit entrer. La classe QColorDialog fournit un dialogue pour la spcification des couleurs. Cela permet aux utilisateurs de choisir les couleurs (getColor). Par exemple, vous pourriez l'utiliser dans un programme de dessin pour permettre l'utilisateur de dfinir la couleur du pinceau. La classe QFontDialog fournit un widget de dialogue de slection d'une police (getFont).

t.vaira

(2011-2012)

26

Les botes de dialogue Qt (2/2)

La classe QFileDialog fournit une bote de dialogue qui permet aux utilisateurs de slectionner des fichiers ou des rpertoires. Elle permet de parcourir le systme de fichiers afin de slectionner un ou plusieurs fichiers ou un rpertoire (getExistingDirectory, getOpenFileName, getOpenFileNames, getSaveFileName). La classe QMessageBox fournit un dialogue modal pour informer l'utilisateur ou pour demander l'utilisateur une question et recevoir une rponse. Elle fournit aussi quatre types prdfinis : QMessageBox::critical(), QMessageBox::information(), QMessageBox::question(), QMessageBox::warning() La classe QErrorMessage fournit une bote de dialogue qui affiche un message d'erreur (showMessage()). Exemple : http://developer.qt.nokia.com/doc/qt-4.8/dialogs-standarddialogs.html
(2011-2012)

t.vaira

27

QDialog : exemple n4 (1/6)

Cet exemple montre l'utilisation de quelques botes de dialogue Qt :


#include <QApplication> #include <Qt<ui> cla11 AHialog ' public Qdialog { QJ:.LIK" public' AHialog() { Q7u1h.utton *modal.utton- $ ne% Q7u1h.utton(+ odale ' Q;nputHialog+)! Q7u1h.utton *modal.utton@ $ ne% Q7u1h.utton(+ odale ' QKolorHialog+)! Q7u1h.utton *nomodal.utton $ ne% Q7u1h.utton(+3on modale ' QIrror e11age+)! Q7u1h.utton *clo1e.utton $ ne% Q7u1h.utton(+>9ermer+)! error e11ageHialog $ ne% QIrror e11age(thi1)! connect(modal.utton-, &;<3AL(clic=ed()), thi1, &L:"(1et;tem()))! connect(modal.utton@, &;<3AL(clic=ed()), thi1, &L:"(1etKolor()))! connect(nomodal.utton, &;<3AL(clic=ed()), thi1, &L:"(1ho% e11age()))! connect(clo1e.utton, &;<3AL(clic=ed()), thi1, &L:"(clo1e()))! 555 1et8indo%"itle(tr(+ odale ou non modale+))! 6 private ' QIrror e11age *error e11ageHialog!

t.vaira

(2011-2012)

28

QDialog : exemple n4 (2/6)

Utilisation de la classe QInputDialog qui fournit un dialogue simple pour obtenir une valeur unique de l'utilisateur. Ici la valeur d'entre est un lment d'une liste (getItem). La valeur de retour (l'lment choisi) est affich en utilisant la classe QMessageBox.

555 private 1lot1' void 1et;tem() { Q&tringLi1t item1! item1 << Q&tring''(rom)t(*(+7rintemp1+) << Q&tring''(rom)t(*(+PtQ+) << Q&tring''(rom)t(*(+Automne+) << Q&tring''(rom)t(*(+,iver+)! bool o=! Q&tring item $ Q;nputHialog''get;tem(thi1, +Q;nputHialog''get;tem()+, +Han1 ?uelle 1ai1on 1omme14nou1 R+, item1, B, (al1e, >o=)! i( (o= >> Sitem5i1ImptA()) Q e11age.o#''in(ormation(thi1, Q&tring''(rom)t(*(+FQpon1e+), item)! 6 555

t.vaira

(2011-2012)

29

QDialog : exemple n4 (3/6)

Utilisation de la classe QColorDialog qui fournit un dialogue pour la spcification des couleurs. Cela permet ici l'utilisateur de choisir la couleur de fond (getColor)pour l'application.
555 void 1etKolor() { QKolor color $ QKolorHialog''getKolor(Qt''green, thi1)! i( (color5i1Nalid()) { thi14>1et7alette(Q7alette(color))! thi14>1etAuto9ill.ac=ground(true)! 6 6 555

t.vaira

(2011-2012)

30

QDialog : exemple n4 (4/6)

Utilisation de la classe QErrorMessage qui fournit une bote de dialogue affichant un message d'erreur (showMessage()). C'est un exemple aussi de bote de dialogue non modale.
void 1ho% e11age() { error e11ageHialog4>1ho% e11age(+bla bla bla 555+)! 6

6!

t.vaira

(2011-2012)

31

QDialog : exemple n4 (5/6)

Dans cet exemple, la macro Q_OBJECT est ncessaire ds qu'un dispositif propre Qt est utilis (ici private slot). L'outil moc permet l'implmentation de ces mcanismes. Si vous fournissez vos classes sous la forme de fichiers spars : dclaration (.h) et dfinition (.cpp) alors le moc sera appel automatiquement. Il gnrera un fichier mocJnomcla11e5cpp partir de votre fichier nomcla11e5h. Le fichier sera ensuite automatiquement compil et li grce au Makefile gnr par qmake. Exemple de rgle prsente dans un Makefile pour Qt :
mocJmA%idget5cpp' mA%idget5h moc T(HI9;3I&) T(;3K7A",) mA%idget5h 4o mocJmA%idget5cpp mocJmA%idget5o' mocJmA%idget5cpp T(KUU) 4c T(KUU9LA<&) T(;3K7A",) 4o mocJmA%idget5o mocJmA%idget5cpp

t.vaira

(2011-2012)

32

QDialog : exemple n4 (6/6)

Pour certains exemples du cours, l'ensemble du programme est fourni dans un seul fichier par souci de simplicit de lecture. Il faut alors appeler l'outil moc manuellement pour gnrer un fichier moc_MyDialog.h qu'il faut ensuite inclure : moc AHialog5cpp 4o mocJ AHialog5h
555 #include +mocJ AHialog5h+ int main(int argc, char *argv[]) { QApplication app(argc, argv)! AHialog mAHialog! mAHialog51ho%()! 6 return app5e#ec()!

t.vaira

(2011-2012)

33

La classe QMainWindow

La classe QMainWindow offre une fentre d'application principale. Une fentre principale fournit un cadre pour la construction de l'interface utilisateur d'une application. QMainWindow a sa propre mise en page laquelle vous pouvez ajouter QToolBars, QDockWidgets, un QMenuBar, et un QStatusBar. Le trac a une zone centrale qui peut tre occupe par n'importe quel type de widget. Le widget central sera gnralement un widget standard de Qt comme un QTextEdit ou un QGraphicsView. Les widgets personnaliss peuvent galement tre utiliss pour des applications avances. On dfinit le widget central avec setCentralWidget().
(2011-2012)

t.vaira

34

QMainWindow : exemple n1

Pour crer sa propre application principale, il suffit de crer une classe qui hrite de QMainWindow et de l'afficher avec show() :
#include <QApplication> #include <Qt<ui> cla11 A ain8indo% ' public Q ain8indo% { public' A ain8indo%() {6 6! int main(int argc, char *argv[]) { QApplication app(argc, argv)! A ain8indo% mA ain8indo%! mA ain8indo%51ho%()! 6 return app5e#ec()!

t.vaira

(2011-2012)

35

QMainWindow : exemple n2

Le widget central sera gnralement un widget standard de Qt comme un QTextEdit ou un QGraphicsView. Les widgets personnaliss peuvent galement tre utiliss pour des applications avances. On dfinit le widget central avec setCentralWidget() :
#include <QApplication> #include <Qt<ui> cla11 A ain8indo% ' public Qmain8indo% { public' A ain8indo%() { Q8idget *central8idget $ ne% Q8idget! 1etKentral8idget(central8idget)! 6 6! int main(int argc, char *argv[]) { QApplication app(argc, argv)! A ain8indo% mA ain8indo%! mA ain8indo%51ho%()! return app5e#ec()! 6

t.vaira

(2011-2012)

36

QMainWindow : exemple n3

Comme on l'a vu prcdemment, on peut maintenant ajouter d'autres widgets dans ce widget principal :
#include <QApplication> #include <Qt<ui> cla11 A ain8indo% ' public Qmain8indo% { public' A ain8indo%() { Q8idget *central8idget $ ne% Q8idget! QLineIdit *login $ ne% QLineIdit! QLineIdit *pa11%ord $ ne% QLineIdit! Q9ormLaAout *(ormLaAout $ ne% Q9ormLaAout! (ormLaAout4>addFo%(+3om dVutili1ateur ' +, login)! (ormLaAout4>addFo%(+ ot de pa11e ' +, pa11%ord)! central8idget4>1etLaAout((ormLaAout)! 1etKentral8idget(central8idget)! 6

6!

t.vaira

(2011-2012)

37

SDI ou MDI

La fentre principale a soit une interface unique (SDI pour Single Document Interface) ou multiples (MDI pour Multiple Document Interface). Pour crer des applications MDI dans Qt, on utilisera un QMdiArea comme widget central.

t.vaira

(2011-2012)

38

QMainWindow : exemple n4

Le widget QMdiArea est utilis comme le widget central de QMainWindow pour crer des applications MDI :

#include <QApplication> #include <Qt<ui> cla11 A ain8indo% ' public Q ain8indo% { public' A ain8indo%() { Q diArea *mdiArea $ ne% Q diArea! 1etKentral8idget(mdiArea)! 6 6!

t.vaira

(2011-2012)

39

QMainWindow : exemple n5

Les sous-fentres de QMdiArea sont des instances de QMdiSubWindow. Elles sont ajoutes une zone MDI avec addSubWindow().
#include <QApplication> #include <Qt<ui> cla11 A ain8indo% ' public Q ain8indo% { public' A ain8indo%() { Q diArea *mdiArea $ ne% Q diArea! Q"e#tIdit *te#tIdit- $ ne% Q"e#tIdit! Q"e#tIdit *te#tIdit@ $ ne% Q"e#tIdit! Q di&ub8indo% *mdi&ub8indo%- $ mdiArea4>add&ub8indo%(te#tIdit-)! Q di&ub8indo% *mdi&ub8indo%@ $ mdiArea4>add&ub8indo%(te#tIdit@)! 22 ouM' Q diArea''&ub8indo%Nie% mdiArea4>1etNie% ode(Q diArea''"abbedNie%)! 1etKentral8idget(mdiArea)!

6!

t.vaira

(2011-2012)

40

La classe QAction

La classe QAction fournit une interface abstraite pour dcrire une action (= commande) qui peut tre insre dans les widgets. Dans de nombreuses applications, des commandes communes peuvent tre invoques via des menus, boutons, et des raccourcis clavier. Puisque l'utilisateur s'attend ce que chaque commande soit excute de la mme manire, indpendamment de l'interface utilisateur utilise, il est utile de reprsenter chaque commande comme une action. Les actions peuvent tre ajouts aux menus et barres d'outils, et seront automatiquement synchronises.

t.vaira

(2011-2012)

41

La classe QMenu

La classe QMenu fournit un widget pour une utilisation dans les barres de menus et les menus contextuels. Un menu contextuel est un menu qui s'affiche lorsqu'on fait un clic droit sur un widget. Un widget menu est un menu de slection. Il peut tre soit un menu droulant dans une barre de menu ou un menu contextuel autonome. Les menus droulants sont indiques par la barre de menu lorsque l'utilisateur clique sur l'lment concern ou appuie sur la touche de raccourci spcifi. Qt implmente donc les menus avec QMenu et QMainWindow les garde dans un QMenuBar. On utilise QMenuBar::addMenu() pour insrer un menu dans une barre de menu. La classe QMenuBar fournit une barre de menu horizontale. Une barre de menu se compose d'une liste d'lments de menu droulant.
(2011-2012)

t.vaira

42

QMainWindow : exemple n6

On peut ajouter de nouveaux menus la barre de menus de la fentre principale en appelant menuBar() qui retourne la QMenuBar de la fentre, puis ajoutez un menu avec QMenuBar::addMenu() :
#include <QApplication> #include <Qt<ui> cla11 A ain8indo% ' public Q ain8indo% { public' A ain8indo%() { Q enu *(ile enu $ ne% Q enu(tr(+>9ichier+), thi1)! menu.ar()4>add enu((ile enu)! Q enu *edit enu $ ne% Q enu(Q&tring''(rom)t(*(+>Pdition+), thi1)! menu.ar()4>add enu(edit enu)! Q enu *help enu $ ne% Q enu(tr(+>Aide+), thi1)! menu.ar()4>add enu(help enu)!

6!

t.vaira

(2011-2012)

43

QMainWindow : exemple n7

On peut soit crer une instance de QAction puis l'ajouter avec addAction() soit crer la QAction directement en utilisant addAction() :
cla11 A ain8indo% ' public Qmain8indo% { public' A ain8indo%() { Q enu *(ile enu $ ne% Q enu(tr(+>9ichier+),thi1)! menu.ar()4>add enu((ile enu)! (ile enu4>addAction(tr(+>Quitter+), ?App, &L:"(?uit()), QWeA&e?uence''Quit)! 555 Q enu *help enu $ ne% Q enu(tr(+Aid>e+), thi1)! menu.ar()4>add enu(help enu)! QAction *action,elp $ ne% QAction(Q&tring''(rom)t(*(+X propo1 de Qt+), thi1)! help enu4>addAction(action,elp)! action,elp4>1et&hortcut(QWeA&e?uence(Qt''WeAJ9-))! 22ou ' 22action,elp4>1et&hortcut(QWeA&e?uence(QWeA&e?uence'',elpKontent1))! connect(action,elp, &;<3AL(triggered()), ?App, &L:"(aboutQt()))! 6 6!

t.vaira

(2011-2012)

44

QMainWindow : exemple n8 (1/4)

On peut ajouter un QMenu un Qmenu avec addMenu() pour crer un sousmenu :

cla11 A ain8indo% ' public Qmain8indo% { public' A ain8indo%() { Q enu *(ile enu $ ne% Q enu(tr(+>9ichier+), thi1)! menu.ar()4>add enu((ile enu)! Q enu *(ile&ub enu $ (ile enu4>add enu(Q&tring''(rom)t(*(+>FQcemment ouvert(1)+))! (ile&ub enu4>addAction(+9ichier- [(ile-5t#t]+)! (ile&ub enu4>addAction(+9ichier@ [(ile@5t#t]+)! (ile&ub enu4>addAction(+9ichierY [(ileY5t#t]+)! 22a/out dVune barre de 1Qparation (ile enu4>add&eparator()! 555

t.vaira

(2011-2012)

45

QMainWindow : exemple n8 (2/4)

Une action peut avoir 2 tats (active, dsactive) en utilisant setCheckable() :

cla11 A ain8indo% ' public Q ain8indo% { public' A ain8indo%() { 555 Q enu *edit enu $ ne% Q enu(Q&tring''(rom)t(*(+>Pdition+), thi1)! menu.ar()4>add enu(edit enu)! QAction *actionIdit $ ne% QAction(Q&tring''(rom)t(*(+<ra1+), thi1)! actionIdit4>1etKhec=able(true)! actionIdit4>1etKhec=ed(true)! edit enu4>addAction(actionIdit)! 555

t.vaira

(2011-2012)

46

QMainWindow : exemple n8 (3/4)

Chaque action d'un menu ou d'une barre d'outils peut avoir une icne QIcon.
cla11 A ain8indo% ' public Q ain8indo% { public' A ain8indo%() { 555 Q enu *help enu $ ne% Q enu(tr(+Aid>e+), thi1)! menu.ar()4>add enu(help enu)! QAction *action,elp $ ne% QAction(Q;con(+help5png+), Q&tring''(rom)t(*(+X propo1 de Qt+), thi1)! help enu4>addAction(action,elp)! action,elp4>1et&hortcut(QWeA&e?uence(QWeA&e?uence'',elpKontent1))! 22action,elp4>1et;con(Q;con(+'2help5png+))! connect(action,elp, &;<3AL(triggered()), ?App, &L:"(aboutQt()))! 555 <SH:K"G7I FKK><FKK ver1ion$+-5B+> <?re1ource><(ile>help5png<2(ile><2?re1ource> <2FKK>

t.vaira

(2011-2012)

47

QMainWindow : exemple n8 (4/4)

On peut aussi utiliser un fichier ressource de Qt (.qrc) pour rfrencer l'image de l'icne. L'outil rcc est alors utilis pour incorporer les ressources dans l'application Qt au cours du processus de construction. rcc gnre un fichier C++ partir des donnes spcifies dans le fichier .qrc.
555 action,elp4>1et;con(Q;con(+'2help5png+))! 555

exemple8.qrc
<SH:K"G7I FKK> <FKK ver1ion$+-5B+> <?re1ource> <(ile>help5png<2(ile> <2?re1ource> <2FKK>

t.vaira

(2011-2012)

48

La classe QToolBar

La classe QToolBar fournit une barre d'outils qui contient un ensemble de contrles (gnralement des icnes) et situe sous les menus. Pour ajouter une barre d'outils, on doit tout d'abord appeler la mthode addToolBar() de QMainWindow. Avec Qt, la barre d'outils utilise des actions pour construire chacun des lments de celle-ci. Les boutons de la barre d'outils sont donc insrs en ajoutant des actions et en utilisant addAction() ou insertAction(). Les boutons peuvent tre spars en utilisant addSeparator() ou insertSeparator(). Mais on peut aussi insrer un widget (comme QSpinBox, QDoubleSpinBox ou QComboBox) l'aide de addWidget() ou insertWidget(). Quand un bouton de la barre est enfonce, il met le signal actionTriggered().
(2011-2012)

t.vaira

49

QMainWindow : exemple n9
cla11 A ain8indo% ' public Qmain8indo% { public' A ain8indo%() { Q enu *(ile enu $ ne% Q enu(tr(+>9ichier+), thi1)! menu.ar()4>add enu((ile enu)! QAction *action3ouveau $ ne% QAction(Q;con(+'2image12ne%5png+), tr(+>3ouveau+), thi1)! action3ouveau4>1et&hortcut1(QWeA&e?uence''3e%)! (ile enu4>addAction(action3ouveau)! (ile enu4>add&eparator()! QAction *actionQuit $ (ile enu4>addAction(tr(+>Quitter+), ?App, &L:"(?uit()), QWeA&e?uence''Quit)! actionQuit4>1et;con(Q;con(+'2image12?uit5png+))! Q"ool.ar *(ile"ool.ar $ add"ool.ar(+9ichier+)! 22(ile"ool.ar4>1et ovable((al1e)! 22(ile"ool.ar4>1et9loatable((al1e)! (ile"ool.ar4>addAction(action3ouveau)! (ile"ool.ar4>addAction(actionQuit)! (ile"ool.ar4>add&eparator()! Q9ontKombo.o# *(ontKombo.o# $ ne% Q9ontKombo.o#! (ile"ool.ar4>add8idget((ontKombo.o#)! 66!

t.vaira

(2011-2012)

50

La classe QDockWidget

La classe QDockWidget fournit un widget qui peut tre ancr dans une QMainWindow ou "flotter" comme une fentre de haut niveau sur le bureau. QDockWidget fournit le concept de dock windows (palettes d'outils ou de fentres d'utilit). Ces dock windows sont des fentres secondaires (ou mini-fentres) placs dans la zone autour du widget central d'une QMainWindow. Beaucoup d'applications connues les utilisent : Qt Designer, OpenOffice, Photoshop, Code::Blocks , ...

t.vaira

(2011-2012)

51

QMainWindow : exemple n10

On peut placer ses propres widgets dans une fentre dockable :


cla11 A ain8indo% ' public Q ain8indo% { public' A ain8indo%() { 555 QHoc=8idget *doc=8idget $ ne% QHoc=8idget(+Hoc=+, thi1)! addHoc=8idget(Qt''Le(tHoc=8idgetArea, doc=8idget)! Q8idget *doc=Kontenu $ ne% Q8idget! doc=8idget4>1et8idget(doc=Kontenu)! QN.o#LaAout *doc=LaAout $ ne% QN.o#LaAout! Q9ile&A1tem odel *model $ ne% Q9ile&A1tem odel! model4>1etFoot7ath(QHir''current7ath())! Q"reeNie% *vueArbre $ ne% Q"reeNie%! vueArbre4>1et odel(model)! doc=LaAout4>add8idget(vueArbre)! Q7u1h.utton *pu1h.utton $ ne% Q7u1h.utton(+3ouveau+)! doc=LaAout4>add8idget(pu1h.utton)! doc=Kontenu4>1etLaAout(doc=LaAout)! 555

t.vaira

(2011-2012)

52

La classe QStatusBar

La classe QStatusBar fournit une barre horizontale approprie pour la prsentation des informations d'tat. QStatusBar permet d'afficher diffrents types d'indicateurs. Une barre d'tat peut afficher trois types de messages diffrents :

temporaire : affich brivement. Exemple : utilis pour afficher les textes explicatifs de la barre d'outils ou des entres de menu. normal : affich tout le temps, sauf quand un message temporaire est affich. Exemple : utilis pour afficher la page et le numro de ligne dans un traitement de texte. permanent : jamais cach. Exemple : utilis pour des indications de mode important comme le verrouillage des majuscules.

La barre d'tat peut tre rcupr l'aide de QMainWindow::statusBar() et remplac l'aide de QMainWindow::setStatusBar().
(2011-2012)

t.vaira

53

QMainWindow : exemple n11

On utilisez showMessage() pour afficher un message temporaire. Pour supprimer un message temporaire, il faut appeler clearMessage(), ou fixer une limite de temps lors de l'appel showMessage().

cla11

{ public' A ain8indo%() { 555 Q&tatu1.ar *barreItat $ 1tatu1.ar()! Q7rogre11.ar *progre11ion $ ne% Q7rogre11.ar! barreItat4>add7ermanent8idget(progre11ion)! barreItat4>1ho% e11age(Q&tring''(rom)t(*(+Le 1ui1 la barre dVQtat+), @BBB)! 555

A ain8indo% ' public Q ain8indo%

t.vaira

(2011-2012)

54

QMainWindow : exemple n12


#include <QApplication> #include <Qt<ui> #include <Qt8ebWit> cla11 A ain8indo% ' public Qmain8indo% { public' A ain8indo%() { Q8idget *central8idget $ ne% Q8idget! Q"ool.ar *url"ool.ar $ add"ool.ar(+)FL+)! QLineIdit *urlIdit $ ne% QLineIdit! QLabel *label $ ne% QLabel(tr(+Adre11e '+))! url"ool.ar4>add8idget(label)! url"ool.ar4>add8idget(urlIdit)! %ebNie% $ ne% Q8ebNie%! QN.o#LaAout *laAout $ ne% QN.o#LaAout! laAout4>add8idget(%ebNie%)! central8idget4>1etLaAout(laAout)! %ebNie%4>load(Q)rl(+http'22%%%5google5(r2+))! 1etKentral8idget(%ebNie%)! 6 private' Q8ebNie% *%ebNie%! 6!

t.vaira

(2011-2012)

55

Graphique 2D

Deux approches pour dessiner en 2D dans Qt :

un modle fonctionnel bas sur QPainter un modle objet bas sur le framework Graphics View

Exemple utilisant l'architecture Graphics View

Exemple utilisant QPainter

t.vaira

(2011-2012)

56

Le framework Graphics View (1/4)

Le framework Graphics View se dcompose en 3 parties essentielles :

La scne La vue Les lments graphiques

L'architecture Graphics View offre une approche base sur le pattern modlevue. Plusieurs vues peuvent observer une scne unique constitue d'lments de diffrentes formes gomtriques.

t.vaira

(2011-2012)

57

Le framework Graphics View (2/4)

La classe QGraphicsScene fournit la scne pour l'architecture Graphics View. La scne a les responsabilits suivantes :

fournir une interface rapide pour grer un grand nombre d'lments, propager les vnements chaque lment, grer les tats des lments (telles que la slection et la gestion du focus) et fournir des fonctionnalits de rendu non transforme (principalement pour l'impression).

La classe QGraphicsView fournit la vue "widget" qui permet de visualiser le contenu d'une scne.

t.vaira

(2011-2012)

58

Le framework Graphics View (3/4)

La classe QGraphicsItem est la classe de base pour les lments graphiques dans une scne. Elle fournit plusieurs lments standard pour les formes typiques, telles que :

des rectangles (QGraphicsRectItem), des ellipses (QGraphicsEllipseItem) et des lments de texte (QGraphicsTextItem).

Mais les fonctionnalits les plus puissantes seront disponibles lorsque on crira un lment personnalis. Entre autres choses, QGraphicsItem supporte les fonctionnalits suivantes : les vnements souris et clavier, le glissez et dposez (drag and drop), le groupement d'lments, la dtection des collisions.
(2011-2012)

t.vaira

59

Le framework Graphics View (4/4)

La scne sert de conteneur pour les objets QGraphicsItem. La classe QGraphicsView fournit la vue "widget" qui permet de visualiser le contenu d'une scne.
#include #include #include #include <QApplication> <Q<raphic1&cene> <Q<raphic1Fect;tem> <Qgraphic1Nie%>

int main(int argc, char **argv) { QApplication app(argc, argv)! Q<raphic1&cene 1cene! Q<raphic1Fect;tem *rect $ 1cene5addFect(QFect9(B, B, -BB, -BB))! Q<raphic1Nie% vie%(>1cene)! vie%51ho%()! 6 return app5e#ec()!

t.vaira

(2011-2012)

60

Dessin 2D

En collaboration avec les classes QPaintDevice et QPaintEngine, QPainter est la base du systme de dessin de Qt. QPainter est la classe utilise pour effectuer les oprations de dessin. QPaintDevice reprsente un dispositif qui peut tre peint en utilisant un QPainter. QPaintEngine fournit le moteur de rendu et l'interface (abstraite) que QPainter utilise pour dessiner sur diffrents types de dispositifs suivant la plate-forme utilise.
(2011-2012)

t.vaira

61

QPainter (1/12)

La classe QPainter est la classe de base de dessin bas niveau sur les widgets et les autres dispositifs de dessins. QPainter fournit des fonctions hautement optimises : il peut tout dessiner des lignes simples des formes complexes. QPainter peut fonctionner sur n'importe quel objet qui hrite de la classe QPaintDevice. L'utilisation courante de QPainter est l'intrieur de la mthode paintEvent() d'un widget : construire, personnaliser (par exemple le pinceau), dessiner et dtruire l'objet QPainter aprs le dessin.

t.vaira

(2011-2012)

62

QPainter (2/12)

Un widget est "repeint" :

Lorsque une fentre passe au dessus Lorsque l'on dplace le composant ... Lorsque l'on le lui demande explicitement :

repaint() entrane un rafraichissement immdiat update() met une demande de rafrachissement en file d'attente

Dans tous les cas, cest la mthode paintEvent qui est appele : void paintIvent(Q7aintIvent* e)! Pour dessiner dans un widget, il faut donc redfinir QWidget::paintEvent().
(2011-2012)

t.vaira

63

QPainter : exemple 1 (3/12)


cla11 A8idget ' public Q8idget { public' A8idget( Q8idget *parent $ B ) ' Q8idget( parent ) {6 void paintIvent(Q7aintIvent* e) { Q8idget''paintIvent(e)! 22 e((ectue le comportement 1tandard Q7ainter painter(thi1)! 22 con1truire painter51et7en( Q7en(Qt''red, @) )! 22 per1onnali1er painter5dra%Fect( @D, -D, -@B, ZB )! 22 de11iner 6! 6 22 dQtruire

t.vaira

(2011-2012)

64

QPainter (4/12)

La classe QPainter fournit de nombreuses mthodes :


setPen( ) : lignes et contours setBrush( ) : remplissage setFont( ) : texte setTransform( ), etc. : transformations affines setClipRect/Path/Region( ) : clipping (dcoupage) setCompositionMode( ) : composition

Lignes et contours : drawPoint(), drawPoints(), drawLine(), drawLines(), drawRect(), drawRects(), drawArc(), drawEllipse(), drawPolygon(), drawPolyline(), etc et drawPath() pour des chemins complexes Remplissage : fillRect(), fillPath() Divers : drawText(), drawPixmap(), drawImage(), drawPicture()
(2011-2012)

t.vaira

65

QPainter (5/12)

Conjointement la classe Qpainter, on utilise de nombreuses autres classes utiles :


Entiers : QPoint, QLine, QRect, QPolygon Flottants : QPointF, QLineF, ... Chemin complexe : QPainterPath Zone daffichage : QRegion Stylo (trait) : QPen Pinceau (remplissage) : QBrush Couleur : QColor

t.vaira

(2011-2012)

66

QPainter : exemple 2 (6/12)


cla11 A8idget ' public Q8idget { public' A8idget( Q8idget *parent $ B ) ' Q8idget( parent ) {6 void paintIvent(Q7aintIvent* e) { Q7ainter painter(thi1)! Q7en pen! pen51et&tAle(Qt''Ha1hHotLine)! pen51et8idth(Y)! pen51et.ru1h(Qt''green)! pen51etKap&tAle(Qt''FoundKap)! pen51etLoin&tAle(Qt''FoundLoin)! painter51et7en(pen)! painter5dra%Line( @D, -D, -CD, [D )! painter51et7en( Q7en(Qt''red, @) )! painter5dra%Fect( @D, -D, -@B, ZB )!

6!

t.vaira

(2011-2012)

67

QPainter : exemple 3 (7/12)


cla11 A8idget ' public Q8idget { public' A8idget( Q8idget *parent $ B ) ' Q8idget( parent ) {6 void paintIvent(Q7aintIvent* e) { Q7ainter painter(thi1)! Q.ru1h bru1h! bru1h51et&tAle(Qt''Kro117attern)! bru1h51etKolor(Qt''blue)! painter51et.ru1h( bru1h )! painter51et7en( Q7en(Qt''red, @) )! painter5dra%Fect( @D, -D, -@B, ZB )!

6!

t.vaira

(2011-2012)

68

QPainter : exemple 4 (8/12)


cla11 A8idget ' public Q8idget { public' A8idget( Q8idget *parent $ B ) ' Q8idget( parent ) {6 void paintIvent(Q7aintIvent* e) { Q7ainter painter(thi1)! 555 2*painter51et7en( Q7en(Qt''blac=, @) )! painter5dra%Illip1e(QFect(@B, -B, -YB, [B))! painter5dra%Fect(QFect(@B, -B, -YB, [B))!*2 QFegion QFegion QFegion QFegion r-(QFect(@B, -B, -YB, [B), QFegion''Illip1e)! r@(QFect(@B, -B, -YB, [B))! rY $ r-5inter1ected(r@)! rC $ r-5#ored(r@)!

22painter51etKlipFegion(rY)! painter51etKlipFegion(rC)! 555 6 6!

t.vaira

(2011-2012)

69

QPainter : exemple 5 (9/12)


cla11 A8idget ' public Q8idget { public' A8idget( Q8idget *parent $ B ) ' Q8idget( parent ) {6 void paintIvent(Q7aintIvent* e) { Q7ainter painter(thi1)! painter51et7en( Q7en(Qt''dar=Fed, @, Qt''Ha1hHotLine) )! painter5dra%Fect( @D, -D, -@B, ZB )! painter5tran1late(@D, -D)! painter5rotate( -D5B )! painter5tran1late(4@D, 4-D)! painter51et7en( Q7en(Qt''red, @) )! painter5dra%Fect( @D, -D, -@B, ZB )! 6 6!

t.vaira

(2011-2012)

70

QPainter : exemple 5b (10/12)


cla11 A8idget ' public Q%idget { QJ:.LIK" ?real rotationAngle! public' A8idget( Q8idget *parent $ B ) ' Q8idget( parent ) {6 void paintIvent(Q7aintIvent* e) { Q7ainter painter(thi1)! painter51etFender,int(Q7ainter''Antialia1ing)! painter51cale(%idth() 2 -BB5B, height() 2 -BB5B)! painter5tran1late(DB5B, DB5B)! painter5rotate(4rotationAngle)! painter5tran1late(4DB5B, 4DB5B)! painter51et7en( Q7en(Qt''red, @) )! painter5dra%Fect( @D, -D, DB, ZB )! 6 public 1lot1' void 1etFotationAngle(int degree1) { rotationAngle $ (?real)degree1! update()! 6

6!

t.vaira

(2011-2012)

71

QPainter : les images (11/12)

Qt fournit quatre classes de traitement des donnes d'image : QImage, QPixmap, les QBitmap et QPicture. QImage fournit une reprsentation d'image indpendante du matriel qui permet un accs direct aux pixels. QImage est conu et optimis pour les E/S. QPixmap est conu et optimis pour afficher les images sur l'cran.

QBitmap n'est qu'une classe de commodit qui hrite QPixmap.

QPicture est un dispositif permettant d'enregistrer des commandes d'un QPainter et de les rejouer. Ces 4 classes hritent de QPaintDevice et on peut donc dessiner dedans avec un QPainter. Elles possdent aussi les mthodes load() et save() d'accs aux fichiers (dont les principaux formats sont supports).
(2011-2012)

t.vaira

72

QPainter : exemple 6 (12/12)


cla11 A8idget ' public Q8idget { public' A8idget( Q8idget *parent $ B ) ' Q8idget( parent ) {6 void paintIvent(Q7aintIvent* e) { Q8idget''paintIvent(e)! Q7ainter painter(thi1)! QFect rect(B, B, -[B, CD)! Q7i#map pi#map! pi#map5load(+?t4logo5png+)! painter51et7en( Q7en(Qt''green, @)! painter5dra%"e#t(rect, Qt''AlignKenter, tr(+Qt bA\n3o=ia+))! painter5dra%7i#map(CD, DB, pi#map)!

6!

t.vaira

(2011-2012)

73

Gestionnaire d'vnements souris

Gestion des vnements sur un QWidget : Lorsqu'on presse un bouton void mou1e7re11Ivent(Q ou1eIvent* e)! Lorsqu'on relche un bouton void mou1eFelea1eIvent(Q ou1eIvent* e)! Lorsqu'on dplace la souris void mou1e oveIvent(Q ou1eIvent* e)! Lorsqu'on double-clique void mou1eHoubleKlic=Ivent(Q ou1eIvent*

e)!

Pour recevoir des vnements de la souris dans ses propres widgets, il suffit donc de rimplmenter ces gestionnaires d'vnements (event handler). La classe QMouseEvent contient les paramtres qui dcrivent un vnement de la souris : le bouton qui a dclench l'vnement, l'tat des autres boutons et la position de la souris.
(2011-2012)

t.vaira

74

Exemple 7 (1/2)

Le widget QLabel ne possde pas de signal clicked() (comme les QPushButton par exemple). On va donc le crer partir du gestionnaire mousePressEvent().
cla11 ALabel ' public QLabel { QJ:.LIK" 555 22 voir diapo 1uivante void mou1e7re11Ivent(Q ou1eIvent *e) { i((e4>button() $$ Qt''Le(t.utton) emit clic=ed()! 6 private 1lot1' void 1election() { Q e11age.o# m1g.o#! m1g.o#51et"e#t(Q&tring''(rom)t(*(+Nou1 aveE cli?uQ 1ur mon label S+))! m1g.o#5e#ec()! 6 1ignal1' void clic=ed()! 6!

t.vaira

(2011-2012)

75

Exemple 7 (2/2)
cla11 ALabel ' public Qlabel { QJ:.LIK" public' ALabel( QLabel *parent $ B ) ' QLabel( parent ) { Q7alette palette! palette51etKolor(Q7alette''8indo%, QKolor(QKolor(B,@DD,B)))! 1etAuto9ill.ac=ground(true)! 1et7alette(palette)! 1et9rame&tAle(Q9rame''7anel ] Q9rame''&un=en)! 1et"e#t(+mon label+)! 1etAlignment(Qt''Align,Kenter ] Qt''AlignNKenter)! connect(thi1,&;<3AL(clic=ed()),thi1,&L:"(1election()))! 22 clic bouton gauche QAction *?uitAction $ ne% QAction(tr(+I>#it+), thi1)! ?uitAction4>1et&hortcut(tr(+Ktrl^Q+))! connect(?uitAction,&;<3AL(triggered()),?App,&L:"(?uit()))! addAction(?uitAction)! 1etKonte#t enu7olicA(Qt''Action1Konte#t enu)! 22 clic bouton droit 6 6!

t.vaira

(2011-2012)

76

QPicture : exemple 8

QPicture est un dispositif permettant d'enregistrer des commandes d'un QPainter et de les rejouer.
Q7icture picture! Q7ainter painter! painter5begin(>picture)! painter51et7en( Q7en(Qt''red, @) )! painter5dra%Illip1e(@D, -B, -@B, [B)! painter5end()! picture51ave(+dra%ing5pic+)!

dra%ing5pic Q7icture picture! picture5load(+dra%ing5pic+)! Q7ainter painter! painter5begin(thi1)! painter5dra%7icture(B, B, picture)! painter5end()!

t.vaira

(2011-2012)

77

QImage : exemple 9

QImage fournit une reprsentation d'image indpendante du matriel qui permet un accs direct aux pixels.
#include <Q;mage> int main(int argc, char **argv) { Q;mage image(Y, Y, Q;mage''9ormatJF<.Y@)! QFgb value! value $ ?Fgb(B, B, @DD)! 22 B#BBBB99 (or(int i $ B! i < Y! i^^) image51et7i#el(B, i, value)! value $ ?Fgb(@DD, @DD, @DD)! 22 blanc (or(int i $ B! i < Y! i^^) image51et7i#el(-, i, value)! value $ ?Fgb(@DD, B, B)! (or(int i $ B! i < Y! i^^) image51et7i#el(@, i, value)! image51ave(+(rance5png+, +73<+)! 6 return B!

t.vaira

(2011-2012)

78

Le glisser-dposer (1/11)

Le "glisser-dposer" (drag & drop) est un mcanisme visuel simple qui permet aux utilisateurs de transfrer des informations entre et au sein des applications. glisser-dposer est une forme de copier/couper/coller. Il y a 4 classes de base pour grer les vnements associs l'action de de glisserdposer :

Le

QDragEnterEvent : vnement qui est envoy un widget lorsque l'action de glisser dbute QDragLeaveEvent : vnement qui est envoy un widget lorsque l'action de glisser se termine QDragMoveEvent : vnement qui est envoy quand une action de glisserdposer est en cours QDropEvent : vnement qui est envoy quand une action de glisser-dposer est termine
(2011-2012)

t.vaira

79

Le glisser-dposer (2/11)

Il y a par consquence 4 gestionnaires d'vnements associs :


void void void void

dragInterIvent(QHragInterIvent *event)! dragLeaveIvent(QHragLeaveIvent *event)! drag oveIvent(QHrag oveIvent *event)! dropIvent(QHropIvent *event)!

Pour dmarrer un glisser-dposer, il faut crer un objet QDrag et appeler sa fonction exec(). Les actions possibles sont : Qt''KopAAction : Copie les donnes vers la cible. Qt'' oveAction : Dplacer les donnes de la source vers la cible. Qt''Lin=Action : Crer un lien de la source vers la cible. N'importe quel type d'information peut tre transfr dans une opration de glisserdposer. Les applications concernes doivent tre en mesure d'indiquer l'autre quels sont les formats de donnes grs en utilisant des types MIME.
(2011-2012)

t.vaira

80

Le glisser-dposer (3/11)

Pour illustrer le mcanisme de base du glisser-dposer, on va prendre un exemple simple. L'application (exemple n10) va crer deux zones (QFrame) dans lesquelles seront places deux boutons. Les boutons peuvent tre glisss-dposs dans l'autre zone mais pas l'intrieur de sa zone d'origine. Si un bouton est gliss-dpos, un nouveau bouton de mme libell est cr et le bouton source est dtruit.

Situation initiale

Le bouton 1 de gauche en cours de glissage

Le bouton 1 a t dpos dans la zone de droite

t.vaira

(2011-2012)

81

Le glisser-dposer : exemple 10 (4/11)

On cre son propre widget bouton :


cla11 A7u1h.utton ' public Q7u1h.utton { QJ:.LIK" public' A7u1h.utton(Q&tring libelle, Q8idget *p$B)'Q7u1h.utton(libelle, p) { re1iEe(-@B, YB)! Q7alette palette! palette51etKolor(Q7alette''.utton, QKolor(-@[,-@[,-@[))! palette51etKolor(Q7alette''.utton"e#t, QKolor(Qt''%hite))! thi14>1et7alette(palette)! 6 void mou1e7re11Ivent(Q ou1eIvent *event)! void mou1e oveIvent(Q ou1eIvent *event)! Q7oint drag&tart7o1ition() { return Jdrag&tart7o1ition! 6 private' Q7oint Jdrag&tart7o1ition! 6!

t.vaira

(2011-2012)

82

Le glisser-dposer : exemple 10 (5/11)

Dans la plupart des cas, l'opration de glisser-dposer dmarre lorsqu'un bouton de la souris a t press et que le curseur a t dplac sur une certaine distance. En effet, certains widgets ont besoin de faire la distinction entre les clics de la souris et le glisser. Il faudra donc rimplmenter le gestionnaire d'vnement mousePressEvent() du widget pour pour enregistrer la position de dpart du glisser. Puis, il faudra rimplmenter mouseMoveEvent() pour dterminer si un glisser devrait commencer.

cla11 A7u1h.utton ' public Q7u1h.utton { QJ:.LIK" void mou1e7re11Ivent(Q ou1eIvent *event) { i((event4>button() $$ Qt''Le(t.utton) Jdrag&tart7o1ition $ event4>po1()! 6 6!

t.vaira

(2011-2012)

83

Le glisser-dposer : exemple 10 (6/11)

Il faudra rimplmenter mouseMoveEvent() pour dterminer si un glisser devrait commencer. On utilisera la fonction manhattanLength() pour obtenir une estimation approximative de la distance entre l'endroit o le clic de souris a eu lieu et la position actuelle du curseur.

Les objets QMimeData et QDrag crs par le widget source ne doivent pas tre supprims car ils void mou1e oveIvent(Q ou1eIvent *event) { seront dtruits par i( (S(event4>button1() > Qt''Le(t.utton)) return! Qt. i( ((event4>po1() 4 Jdrag&tart7o1ition)5manhattanLength()
< QApplication''1tartHragHi1tance()) return! QHrag *drag $ ne% QHrag(thi1)! Q imeHata *mimeHata $ ne% Q imeHata! mimeHata4>1et"e#t(thi14>te#t())! drag4>1et imeHata(mimeHata)! Qt''HropAction dropAction $ drag4>e#ec()! i((dropAction $$ Qt'' oveAction) clo1e()! 6

t.vaira

(2011-2012)

84

Le glisser-dposer : exemple 10 (7/11)

On cre sa propre frame qui contient deux boutons :


cla11 A9rame ' public Q9rame { QJ:.LIK" public' A9rame( Q8idget *parent $ B ) ' Q9rame( parent ) { 1et inimum&iEe(-[B, -*D)! 1et9rame&tAle(Q9rame''&un=en ] Q9rame''&tAled7anel)! 1etAcceptHrop1(true)! btn- $ ne% A7u1h.utton(+.outon -+, thi1)! btn-4>move(@D, -CD)! btn@ $ ne% A7u1h.utton(+.outon @+, thi1)! btn@4>move(@D, CD)! btn-4>1ho%()! btn@4>1ho%()! 6 void dragInterIvent(QHragInterIvent *event)M! void drag oveIvent(QHrag oveIvent *event)M! void dropIvent(QHropIvent *event)M! private' A7u1h.utton *btn-! A7u1h.utton *btn@!

6!

t.vaira

(2011-2012)

85

Le glisser-dposer : exemple 10 (8/11)

Le widget receveur devra accepter le dposer en appelant la mthode setAcceptDrops(true) et rimplmenter les gestionnaires d'vnements associs au glisser-dposer. Tout d'abord lorsque l'action de glisser dbute :
cla11 A9rame ' public Q9rame { QJ:.LIK" void dragInterIvent(QHragInterIvent *event) { i((event4>mimeHata()4>ha19ormat(+te#t2plain+) >> event4>propo1edAction() $$ Qt'' oveAction) { event4>accept7ropo1edAction()! 6 el1e { event4>ignore()! 6 6 6!

t.vaira

(2011-2012)

86

Le glisser-dposer : exemple 10 (9/11)

Ensuite, on traite le dplacement du "glisser" en vrifiant si on est dans la bonne zone de "dposer".
cla11 A9rame ' public Q9rame { QJ:.LIK" void drag oveIvent(QHrag oveIvent *event) { i((event4>mimeHata()4>ha19ormat(+te#t2plain+) >> event4>propo1edAction() $$ Qt'' oveAction) { A7u1h.utton *child.tn $ 1taticJca1t< A7u1h.utton*>(event4 >1ource())! i((thi1 $$ child.tn4>parent8idget()) event4>ignore()! el1e event4>accept7ropo1edAction()! 6 el1e event4>ignore()! 6 6!

t.vaira

(2011-2012)

87

Le glisser-dposer : exemple 10 (10/11)

On termine par grer le "dposer" en crant un nouveau bouton l'endroit o il a t pos en en rcuprant son libell dans les donnes transfres.
cla11 A9rame ' public Q9rame { QJ:.LIK" void dropIvent(QHropIvent *event) { i( (event4>mimeHata()4>ha19ormat(+te#t2plain+) >> event4>propo1edAction() $$ Qt'' oveAction) { A7u1h.utton *child.tn $ 1taticJca1t< A7u1h.utton*>(event4 >1ource())! i((thi1 S$ child.tn4>parent8idget()) { A7u1h.utton *ne%.tn $ ne% A7u1h.utton(event4>mimeHata()4 >te#t(), thi1)! ne%.tn4>move(event4>po1() 4 child.tn4>drag&tart7o1ition())! ne%.tn4>1ho%()! 6 event4>accept7ropo1edAction()! 6 el1e event4>ignore()! 6 6!

t.vaira

(2011-2012)

88

Le glisser-dposer : exemple 10 (11/11)

On peut aussi "glisser-dposer" un bouton de notre application vers une autre application. On utilise ici un exemple fourni par Qt : dropsite. Le bouton 1 a t dplac dans l'application dropsite qui a rcupr les donnes associes : c'est--dire son libell soit Bouton 1 . Documentation sur le "glisser-dposer" : http://qt-project.org/doc/qt-4.8/dnd.html

t.vaira

(2011-2012)

89

Vous aimerez peut-être aussi