Académique Documents
Professionnel Documents
Culture Documents
Cours QT
Cours QT
Notiondefentre
Utilisationdesclasses:QWidget,QDialogetQMainWindow
Leslayouts
Botededialoguemodaleetnonmodale
LesapplicationSDIetMDI
Utilisationdesclasses:QAction,QMenu,QToolBar,QDockWidgetet
QStatusBar
Graphiqueetdessin2D:leframeworkGraphicsViewetQPainter
QPictureetQImage
Lagestiond'vnementsourisetleglisserdposer(drag&drop)
t.vaira
(2011-2012)
InterfaceUtilisateurGraphique
t.vaira
(2011-2012)
LesexemplesdeQt
Touslesexemplesdececourssontdisponiblesl'adressesuivante:
http://tvaira.free.fr/dev/qt/exemplesqt.zip
LadocumentationdeQtfournitdenombreuxexemples(plusde400),
notamment:
http://developer.qt.nokia.com/doc/exampleswidgets.html
http://developer.qt.nokia.com/doc/dialogsstandarddialogs.html
http://developer.qt.nokia.com/doc/examplesmainwindow.html
http://developer.qt.nokia.com/doc/widgetswindowflags.html
http://developer.qt.nokia.com/doc/exampleslayouts.html
t.vaira
(2011-2012)
LaclasseQWidget
LaclasseQWidget:
hritedeQObject
estlaclassemredetoutesles
classesservantraliserdes
interfacesgraphiques
Leswidgets:
t.vaira
(2011-2012)
sontcapabledese"peindre"
sontcapablederecevoirlesvnementssouris,clavier
sontleslmentsdebasedesinterfacesgraphiques
sonttousrectangulaires
ilssontordonnssuivantlaxez(gestiondelaprofondeur)
ilspeuventavoirunwidgetparent
4
Notiondefentre
Unwidgetquin'estpasincorpordansunwidgetparentestappelunefentre.
Habituellement,lesfentresontuncadreetunebarredetitre,maisilestgalement
possibledecrerdesfentressansdcorationenutilisantdespropritsspcifiques
(windowflags).
DansQt,QMainWindowetlesdiffrentessousclassesdeQDialogsontlestypes
defentreslespluscourantes.
t.vaira
(2011-2012)
Leswidgets
IlexistebeaucoupdesousclassesdeQWidgetquifournissentunerelle
fonctionnalit,tellequeQLabel,QPushButton,QListWidgetetQTabWidget.
Leswidgetsquinesontpasdesfentressontdeswidgetsenfants,affichsdansleur
widgetparent.LaplupartdeswidgetsdansQtsontprincipalementutilesentantque
widgetsenfants.
Parexemple,ilestpossibled'afficherunboutonentantquefentredehautniveau,
maisonprfregnralementmettrelesboutonsl'intrieurd'autreswidgets,tels
queQDialog.
t.vaira
(2011-2012)
Widget:exemplen1
Unwidgetesttoujourscrcach,ilestdoncncessaired'appelerlamthode
show()pourl'afficher
#include <QApplication>
#include <QLabel>
int main( int argc, char* argv[] )
{
QApplication MonAppli( argc, argv );
QLabel *pMonTexte = new QLabel(
QString::fromUtf8("<H1><center>Bonjour
tous</center></H1>"), NULL);
pMonTexte->show();
}
t.vaira
return MonAppli.exec();
(2011-2012)
Widget:exemplen2
D'unemaniregnrale,leswidgetssonthirarchiquementincluslesunsdansles
autres.Leprincipalavantageestquesileparentestdplac,lesenfantslesontaussi.
Onajouteunboutonetlesdeuxlmentsserontinclusdansunmmewidget:
#include <QApplication>
#include <QLabel>
#include <QPushButton>
int main( int argc, char* argv[] ) {
QApplication MonAppli( argc, argv );
QWidget *pMaFenetre = new QWidget();
QLabel* pMonTexte = new QLabel("...", pMaFenetre);
QPushButton *pMonBouton = new
QPushButton("Quitter", pMaFenetre);
Widget parent
Widgets enfants
pMaFenetre->show();
}
return MonAppli.exec();
t.vaira
(2011-2012)
Widget:exemplen3
Pourrendreactiflebouton,onconnectelesignalclicked()misparl'objet
pMonBoutonauslotquit()del'objetMonAppli:
#include <QApplication>
#include <QLabel>
#include <QPushButton>
int main( int argc, char* argv[] ) {
QApplication MonAppli( argc, argv );
QWidget *pMaFenetre = new QWidget();
QLabel* pMonTexte = new QLabel("...",pMaFenetre);
QPushButton *pMonBouton = new
QPushButton("Quitter", pMaFenetre);
QObject::connect(pMonBouton, SIGNAL(clicked()),
&MonAppli, SLOT(quit()));
pMaFenetre->show();
return MonAppli.exec();
}
t.vaira
(2011-2012)
Si on clique sur le
bouton, on quitte
l'application.
Lesapplicationsdoiventse
terminerproprementenappelant
QApplication::quit().Cette
mthodeestappele
automatiquementlorsdela
fermeturedudernierwidget.
Widget:exemplen4
LessousclassesdeQWidgetpossdentdenombreusesmthodesquipermettent
d'agirsurl'aspectvisuel:
int main( int argc, char* argv[] ) {
QApplication MonAppli( argc, argv );
QWidget *pMaFenetre = new QWidget();
QLabel* pMonTexte = new QLabel("<h2><em>Bonjour
tous</em></h2>",pMaFenetre);
QPushButton *pMonBouton = new
QPushButton("Quitter",pMaFenetre);
pMonBouton->setGeometry(0,0,pMonTexte->width(),40);
pMonBouton->move(50, 50);
pMonBouton->resize(150, 50);
pMonBouton->setFont(QFont("Arial", 18, QFont::Bold));
QObject::connect(pMonBouton, SIGNAL(clicked()),
&MonAppli, SLOT(quit()));
pMaFenetre->show();
return MonAppli.exec();
}
t.vaira
(2011-2012)
10
Widget:exemplen5
LesfeuillesdestyleQt(QSS)sontunmcanismepuissantquipermetde
personnaliserl'apparencedeswidgets.
Lesconcepts,laterminologieetlasyntaxedesfeuillesdestyleQtsontfortement
inspirsparlesfeuillesdestyleencascade(CSS)utilisesenHTMLmaisadaptes
aumondedewidgets.
int main( int argc, char* argv[] ) {
QApplication MonAppli( argc, argv );
QWidget *pMaFenetre = new QWidget();
QFile file("qss/default.qss");
if(file.open(QFile::ReadOnly)) {
QString styleSheet = QLatin1String(file.readAll());
MonAppli.setStyleSheet(styleSheet);
}
...
pMonBouton->setStyleSheet("background-color:
green");
...
return MonAppli.exec();
}
t.vaira
(2011-2012)
11
Leslayouts(1/2)
Qtfournitunsystmededisposition(layout)pourl'organisationetle
positionnementautomatiquedeswidgetsenfantsdansunwidget.Cegestionnaire
deplacementpermetl'agencementfacileetlebonusagedel'espacedisponible.
QtinclutunensembledeclassesQxxxLayoutquisontutilisspourdcrirela
faondontleswidgetssontdispossdansl'interfaceutilisateurd'uneapplication.
TouteslessousclassesdeQWidgetpeuventutiliserleslayoutspourgrerleurs
enfants.QWidget::setLayout()appliqueunemiseenpageunwidget.
Lorsqu'unlayoutestdfinisurunwidgetdecettemanire,ilprendenchargeles
tchessuivantes:
Positionnementdeswidgetsenfants
Gestiondestailles(minimale,prfre)
Redimensionnement
Misejourautomatiquelorsquelecontenuchange
t.vaira
(2011-2012)
12
Leslayouts(2/2)
Quelqueslayouts:horizontal,vertical,grille,formulaire...
QHBoxLayout
QFormLayout
t.vaira
(2011-2012)
QGridLayout
QVBoxLayout
13
Widget:exemplen6(1/3)
OnpeutrutiliserleswidgetsdeQt:
Parhritage:extensiond'untypedewidget
Parcomposition:assemblagedewidgets
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
#include <QLCDNumber>
#include <QSlider>
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget( QWidget *parent = 0 );
};
private:
QLCDNumber *lcd;
QSlider *slider;
#endif
t.vaira
(2011-2012)
14
Widget:exemplen6(2/3)
Oninstanciedeuxobjetswidgets:labarreQSlideretl'affichageLCD
QLCDNumber.
Onconnecte:slider>valueChanged(int)(mthodedclencheuse)lcd>display(int)
(mthodedclenche)
#include <QVBoxLayout>
#include "mywidget.h"
MyWidget::MyWidget( QWidget *parent ) : QWidget( parent )
{
lcd = new QLCDNumber( this );
Iln'yapasdedeletecarle
slider = new QSlider( Qt::Horizontal, this );
widgetparentsechargerade
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(lcd);
ladestructiondeseswidgets
mainLayout->addWidget(slider);
enfants.
setLayout(mainLayout);
}
t.vaira
(2011-2012)
15
Widget:exemplen6(3/3)
Pourfinir,oninstancienotrenouveauwidgetetonl'affiche:
#include <QApplication>
#include "mywidget.h"
int main( int argc, char **argv )
{
QApplication a( argc, argv );
MyWidget w;
w.show();
}
t.vaira
return a.exec();
(2011-2012)
16
EncapsulationdeWidgets
ExempledewidgetsQtencapsulantd'autreswidgets:QGroupBox,
QTabWidget
t.vaira
(2011-2012)
17
Widget:exemplen7(1/3)
EnutilisantQStyleFactory::keys(),onobtientlalistedesstylesdisponibles:
#include <QApplication>
#include <QtGui>
#include <QDebug>
class MyDialog : public QDialog
{
Q_OBJECT
public:
MyDialog(QWidget *parent) : QDialog(parent)
{
QComboBox *styleComboBox = new QComboBox;
styleComboBox->addItems(QStyleFactory::keys());
qDebug() << QStyleFactory::keys();
QLabel *styleLabel = new QLabel(tr("&Style :"));
styleLabel->setBuddy(styleComboBox);
connect(styleComboBox, SIGNAL(activated(QString)),
this, SLOT(changeStyle(QString)));
t.vaira
(2011-2012)
18
Widget:exemplen7(2/3)
LaclasseQStyleestuneclassedebaseabstraitequiencapsulelelookandfeelde
l'interfacegraphique.QtcontientunensembledesousclassesQStylequimulentles
stylesdesdiffrentesplatesformesprisesenchargeparQt(QWindowsStyle,
QMacStyle,QMotifStyle,etc.)Pardfaut,cesmodlessontconstruitsdansla
bibliothqueQtGui.
Onpeutchangerpendantl'excutionlestyledel'applicationavecsetStyle():
...
private slots:
void changeStyle(const QString &styleName)
{
QApplication::setStyle(QStyleFactory::create(styleName));
QApplication::setPalette(QApplication::style()->standardPalette());
}
};
t.vaira
(2011-2012)
19
Widget:exemplen7(2/3)
LaclasseQStyleestuneclassedebaseabstraitequiencapsulelelookandfeelde
l'interfacegraphique.QtcontientunensembledesousclassesQStylequimulentles
stylesdesdiffrentesplatesformesprisesenchargeparQt(QWindowsStyle,
QMacStyle,QMotifStyle,etc.)Pardfaut,cesmodlessontconstruitsdansla
bibliothqueQtGui.
t.vaira
(2011-2012)
20
LaclasseQDialog
LaclasseQDialogestlaclassedebasedesfentresdedialogue.Ellehritede
QWidget.
Unefentrededialogue(oubotededialogue)estprincipalementutilisepourdes
tchesdecourtedureetdebrvescommunicationsavecl'utilisateur.
Unefentrededialogue(oubotededialogue):
peuttremodaleounonmodale.
peutfournirunevaleurderetour
peutavoirdesboutonspardfaut
peutaussiavoirunQSizeGrip
Exemple n3
(unepoignederedimensionnement)
danslecoininfrieurdroit
t.vaira
(2011-2012)
21
Botededialoguenonmodale
Unebotededialoguenonmodale(modelessdialog)estundialoguequi
fonctionneindpendammentdesautresfentresdelammeapplication.
Exemple:rechercherdutextedanslestraitementsdetexte
Unebotededialoguenonmodaleestafficheenutilisantshow()quiretournele
contrlel'appelantimmdiatement.
Remarque:silabotededialogueestvisuellementcache,ilsuffirad'appeler
successivementshow(),raise()etactivateWindow()pourlareplacersurledessus
delapile.
t.vaira
(2011-2012)
22
QDialog:exemplen1
Pourcrersaproprebotededialogue,ilsuffitdecreruneclassequihritede
QDialog.
#include <QApplication>
#include <QtGui>
class MyDialog : public QDialog
{
public:
MyDialog() {}
};
Bote de dialogue
non modale
t.vaira
return app.exec();
(2011-2012)
23
Botededialoguemodale
Unebotededialoguemodale(modaldialog)estundialoguequibloquel'entre
d'autresfentresvisiblesdelammeapplication.
Exemple:lesdialoguesquisontutilisspourdemanderunnomdefichierouqui
sontutilisspourdfinirlesprfrencesdel'applicationsontgnralementmodaux.
Remarque:lesdialoguespeuventtreapplicationmodale(pardfaut)oufentre
modale.
Lafaonlapluscommunepourafficherunebotededialoguemodaleestdefaire
appelsafonctionexec().Lorsquel'utilisateurfermelabotededialogue,exec()
fourniraunevaleurderetourutile.
Remarque:unealternativeestd'appelersetModal(true)ousetWindowModality(),
puisshow().Contrairementexec(),show()retournelecontrlel'appelant
immdiatement(voirQProgressDialog).
t.vaira
(2011-2012)
24
QDialog:exemplen2
Pourfabriquerunebotededialogue,ilsuffitdecreruneclassequihritede
QDialog.
#include <QApplication>
#include <QtGui>
class MyDialog : public QDialog
{
public:
MyDialog() {}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Bote de dialogue
modale
MyDialog myDialog;
}
t.vaira
return myDialog.exec();
(2011-2012)
25
LesbotesdedialogueQt(1/2)
Qtfournituncertainnombredebotededialogueprtesl'emploi:
LaclasseQInputDialogfournitundialoguesimplepourobtenirunevaleurunique
del'utilisateur.Lavaleurd'entrepeuttreunechane,unnumroouunlment
d'uneliste(getText,getInt,getDouble,getItem).Unetiquette(Label)doittre
placeafindeprciserl'utilisateurcequ'ildoitentrer.
LaclasseQColorDialogfournitundialoguepourlaspcificationdescouleurs.Cela
permetauxutilisateursdechoisirlescouleurs(getColor).Parexemple,vouspourriez
l'utiliserdansunprogrammededessinpourpermettrel'utilisateurdedfinirla
couleurdupinceau.
LaclasseQFontDialogfournitunwidgetdedialoguedeslectiond'unepolice
(getFont).
t.vaira
(2011-2012)
26
LesbotesdedialogueQt(2/2)
LaclasseQFileDialogfournitunebotededialoguequipermetauxutilisateursde
slectionnerdesfichiersoudesrpertoires.Ellepermetdeparcourirlesystmede
fichiersafindeslectionnerunouplusieursfichiersouunrpertoire
(getExistingDirectory,getOpenFileName,getOpenFileNames,getSaveFileName).
LaclasseQMessageBoxfournitundialoguemodalpourinformerl'utilisateurou
pourdemanderl'utilisateurunequestionetrecevoirunerponse.Ellefournit
aussiquatretypesprdfinis:QMessageBox::critical(),
QMessageBox::information(),QMessageBox::question(),
QMessageBox::warning()
LaclasseQErrorMessagefournitunebotededialoguequiafficheunmessage
d'erreur(showMessage()).
Exemple:http://developer.qt.nokia.com/doc/qt4.8/dialogsstandarddialogs.html
t.vaira
(2011-2012)
27
QDialog:exemplen4(1/6)
Cetexemplemontrel'utilisationdequelquesbotesdedialogueQt:
#include <QApplication>
#include <QtGui>
class MyDialog : public Qdialog {
Q_OBJECT
public:
MyDialog() {
QPushButton *modalButton1 = new QPushButton("Modale : QInputDialog");
QPushButton *modalButton2 = new QPushButton("Modale : QColorDialog");
QPushButton *nomodalButton = new QPushButton("Non modale :
QErrorMessage");
QPushButton *closeButton = new QPushButton("&Fermer");
errorMessageDialog = new QErrorMessage(this);
connect(modalButton1, SIGNAL(clicked()), this, SLOT(setItem()));
connect(modalButton2, SIGNAL(clicked()), this, SLOT(setColor()));
connect(nomodalButton, SIGNAL(clicked()), this, SLOT(showMessage()));
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
...
setWindowTitle(tr("Modale ou non modale"));
}
private :
QErrorMessage *errorMessageDialog;
t.vaira
(2011-2012)
28
QDialog:exemplen4(2/6)
UtilisationdelaclasseQInputDialogquifournitundialoguesimplepourobtenir
unevaleuruniquedel'utilisateur.Icilavaleurd'entreestunlmentd'uneliste
(getItem).Lavaleurderetour(l'lmentchoisi)estaffichenutilisantlaclasse
QMessageBox.
...
private slots:
void setItem()
{
QStringList items;
items << QString::fromUtf8("Printemps") << QString::fromUtf8("t") <<
QString::fromUtf8("Automne") << QString::fromUtf8("Hiver");
bool ok;
QString item = QInputDialog::getItem(this, "QInputDialog::getItem()",
"Dans quelle saison sommes-nous ?", items, 0, false, &ok);
if (ok && !item.isEmpty())
QMessageBox::information(this, QString::fromUtf8("Rponse"), item);
}
...
t.vaira
(2011-2012)
29
QDialog:exemplen4(3/6)
UtilisationdelaclasseQColorDialogquifournitundialoguepourlaspcification
descouleurs.Celapermeticil'utilisateurdechoisirlacouleurdefond
(getColor)pourl'application.
...
void setColor()
{
QColor color =
QColorDialog::getColor(Qt::green, this);
if (color.isValid())
{
this->setPalette(QPalette(color));
this->setAutoFillBackground(true);
}
}
...
t.vaira
(2011-2012)
30
QDialog:exemplen4(4/6)
UtilisationdelaclasseQErrorMessagequifournitunebotededialogueaffichant
unmessaged'erreur(showMessage()).C'estunexempleaussidebotededialogue
nonmodale.
};
void showMessage()
{
errorMessageDialog->showMessage("bla bla bla ...");
}
t.vaira
(2011-2012)
31
QDialog:exemplen4(5/6)
Danscetexemple,lamacroQ_OBJECTestncessairedsqu'undispositifpropre
Qtestutilis(iciprivateslot).L'outilmocpermetl'implmentationdeces
mcanismes.
Sivousfournissezvosclassessouslaformedefichiersspars:dclaration(.h)et
dfinition(.cpp)alorslemocseraappelautomatiquement.Ilgnreraunfichier
moc_nomclasse.cpppartirdevotrefichiernomclasse.h.Lefichiersera
ensuiteautomatiquementcompiletligrceauMakefilegnrparqmake.
ExempledergleprsentedansunMakefilepourQt:
moc_mywidget.cpp: mywidget.h
moc $(DEFINES) $(INCPATH) mywidget.h -o moc_mywidget.cpp
moc_mywidget.o: moc_mywidget.cpp
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_mywidget.o moc_mywidget.cpp
t.vaira
(2011-2012)
32
QDialog:exemplen4(6/6)
Pourcertainsexemplesducours,l'ensembleduprogrammeestfournidansunseul
fichierparsoucidesimplicitdelecture.Ilfautalorsappelerl'outilmoc
manuellementpourgnrerunfichiermoc_MyDialog.hqu'ilfautensuiteinclure:
moc MyDialog.cpp -o moc_MyDialog.h
...
#include "moc_MyDialog.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyDialog myDialog;
myDialog.show();
}
t.vaira
(2011-2012)
return app.exec();
33
LaclasseQMainWindow
LaclasseQMainWindowoffreunefentred'applicationprincipale.
Unefentreprincipalefournituncadrepourlaconstructiondel'interfaceutilisateur
d'uneapplication.
QMainWindowasapropremiseenpage
laquellevouspouvezajouterQToolBars,
QDockWidgets,unQMenuBar,etun
QStatusBar.Letracaunezonecentrale
quipeuttreoccupeparn'importe
queltypedewidget.
Lewidgetcentralseragnralementunwidget
standarddeQtcommeunQTextEditouun
QGraphicsView.Leswidgetspersonnalisspeuventgalementtreutilisspourdes
applicationsavances.OndfinitlewidgetcentralavecsetCentralWidget().
t.vaira
(2011-2012)
34
QMainWindow:exemplen1
Pourcrersapropreapplicationprincipale,ilsuffitdecreruneclassequihritede
QMainWindowetdel'afficheravecshow():
#include <QApplication>
#include <QtGui>
class MyMainWindow : public QMainWindow
{
public:
MyMainWindow() {}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyMainWindow myMainWindow;
myMainWindow.show();
}
return app.exec();
t.vaira
(2011-2012)
35
QMainWindow:exemplen2
LewidgetcentralseragnralementunwidgetstandarddeQtcommeunQTextEdit
ouunQGraphicsView.Leswidgetspersonnalisspeuventgalementtreutiliss
pourdesapplicationsavances.Ondfinitlewidgetcentralavec
setCentralWidget():
#include <QApplication>
#include <QtGui>
class MyMainWindow : public QmainWindow {
public:
MyMainWindow() {
QWidget *centralWidget = new QWidget;
setCentralWidget(centralWidget);
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MyMainWindow myMainWindow;
myMainWindow.show();
return app.exec();
}
t.vaira
(2011-2012)
36
QMainWindow:exemplen3
Commeonl'avuprcdemment,onpeutmaintenantajouterd'autreswidgetsdansce
widgetprincipal:
#include <QApplication>
#include <QtGui>
class MyMainWindow : public QmainWindow {
public:
MyMainWindow() {
QWidget *centralWidget = new QWidget;
};
t.vaira
(2011-2012)
37
SDIouMDI
Lafentreprincipaleasoituneinterfaceunique(SDIpourSingleDocument
Interface)oumultiples(MDIpourMultipleDocumentInterface).Pourcrerdes
applicationsMDIdansQt,onutiliseraunQMdiAreacommewidgetcentral.
t.vaira
(2011-2012)
38
QMainWindow:exemplen4
LewidgetQMdiAreaestutiliscommelewidgetcentraldeQMainWindowpour
crerdesapplicationsMDI:
#include <QApplication>
#include <QtGui>
class MyMainWindow : public QMainWindow
{
public:
MyMainWindow()
{
QMdiArea *mdiArea = new QMdiArea;
setCentralWidget(mdiArea);
}
};
t.vaira
(2011-2012)
39
QMainWindow:exemplen5
LessousfentresdeQMdiAreasontdes
instancesdeQMdiSubWindow.Ellessont
ajoutesunezoneMDIavecaddSubWindow().
#include <QApplication>
#include <QtGui>
class MyMainWindow : public QMainWindow {
public:
MyMainWindow() {
QMdiArea *mdiArea = new QMdiArea;
QTextEdit *textEdit1 = new QTextEdit;
QTextEdit *textEdit2 = new QTextEdit;
QMdiSubWindow *mdiSubWindow1 = mdiArea->addSubWindow(textEdit1);
QMdiSubWindow *mdiSubWindow2 = mdiArea->addSubWindow(textEdit2);
};
t.vaira
// ou: QMdiArea::SubWindowView
mdiArea->setViewMode(QMdiArea::TabbedView);
setCentralWidget(mdiArea);
(2011-2012)
40
LaclasseQAction
LaclasseQActionfournituneinterfaceabstraitepourdcrireuneaction(=
commande)quipeuttreinsredansleswidgets.
Dansdenombreusesapplications,descommandescommunespeuventtre
invoquesviadesmenus,boutons,etdesraccourcisclavier.Puisquel'utilisateur
s'attendcequechaquecommandesoitexcutedelammemanire,
indpendammentdel'interfaceutilisateurutilise,ilestutiledereprsenterchaque
commandecommeuneaction.
Lesactionspeuventtreajoutsaux
menusetbarresd'outils,etseront
automatiquementsynchronises.
t.vaira
(2011-2012)
41
LaclasseQMenu
LaclasseQMenufournitunwidgetpouruneutilisationdanslesbarresdemenus
etlesmenuscontextuels.Unmenucontextuelestunmenuquis'affichelorsqu'on
faitunclicdroitsurunwidget.
Unwidgetmenuestunmenudeslection.Ilpeuttresoitunmenudroulantdans
unebarredemenuouunmenucontextuelautonome.Lesmenusdroulantssont
indiquesparlabarredemenulorsquel'utilisateurcliquesurl'lmentconcernou
appuiesurlatouchederaccourcispcifi.
QtimplmentedonclesmenusavecQMenuetQMainWindowlesgardedansun
QMenuBar.OnutiliseQMenuBar::addMenu()pourinsrerunmenudansune
barredemenu.
LaclasseQMenuBarfournitunebarredemenu
horizontale.Unebarredemenusecompose
d'unelisted'lmentsdemenudroulant.
t.vaira
(2011-2012)
42
QMainWindow:exemplen6
Onpeutajouterdenouveauxmenuslabarredemenusdelafentreprincipaleen
appelantmenuBar()quiretournelaQMenuBardelafentre,puisajoutezunmenu
avecQMenuBar::addMenu():
#include <QApplication>
#include <QtGui>
class MyMainWindow : public QMainWindow
{
public:
MyMainWindow()
{
QMenu *fileMenu = new QMenu(tr("&Fichier"), this);
menuBar()->addMenu(fileMenu);
QMenu *editMenu = new QMenu(QString::fromUtf8("&dition"), this);
menuBar()->addMenu(editMenu);
};
t.vaira
(2011-2012)
43
QMainWindow:exemplen7
OnpeutsoitcreruneinstancedeQActionpuisl'ajouteravecaddAction()soit
crerlaQActiondirectementenutilisantaddAction():
class MyMainWindow : public QmainWindow {
public:
MyMainWindow() {
QMenu *fileMenu = new QMenu(tr("&Fichier"),this);
menuBar()->addMenu(fileMenu);
fileMenu->addAction(tr("&Quitter"), qApp, SLOT(quit()),
QKeySequence::Quit);
...
QMenu *helpMenu = new QMenu(tr("Aid&e"), this);
menuBar()->addMenu(helpMenu);
QAction *actionHelp = new QAction(QString::fromUtf8(" propos de
Qt"), this);
helpMenu->addAction(actionHelp);
actionHelp->setShortcut(QKeySequence(Qt::Key_F1)); //ou :
//actionHelp->setShortcut(QKeySequence(QKeySequence::HelpContents));
connect(actionHelp, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
}
};
t.vaira
(2011-2012)
44
QMainWindow:exemplen8(1/4)
OnpeutajouterunQMenuunQmenuavecaddMenu()pourcrerunsous
menu:
t.vaira
(2011-2012)
45
QMainWindow:exemplen8(2/4)
Uneactionpeutavoir2tats(active,dsactive)enutilisantsetCheckable():
t.vaira
(2011-2012)
46
QMainWindow:exemplen8(3/4)
Chaqueactiond'unmenuoud'unebarre
d'outilspeutavoiruneicneQIcon.
class MyMainWindow : public QMainWindow {
public:
MyMainWindow() {
...
QMenu *helpMenu = new QMenu(tr("Aid&e"), this);
menuBar()->addMenu(helpMenu);
QAction *actionHelp = new QAction(QIcon("help.png"),
QString::fromUtf8(" propos de Qt"), this);
helpMenu->addAction(actionHelp);
actionHelp->setShortcut(QKeySequence(QKeySequence::HelpContents));
//actionHelp->setIcon(QIcon(":/help.png"));
connect(actionHelp, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
...
<!DOCTYPE RCC><RCC version="1.0">
<qresource><file>help.png</file></qresource>
</RCC>
t.vaira
(2011-2012)
47
QMainWindow:exemplen8(4/4)
OnpeutaussiutiliserunfichierressourcedeQt(.qrc)pourrfrencerl'imagede
l'icne.L'outilrccestalorsutilispourincorporerlesressourcesdansl'application
Qtaucoursduprocessusdeconstruction.rccgnreunfichierC++partirdes
donnesspcifiesdanslefichier.qrc.
...
actionHelp->setIcon(QIcon(":/help.png"));
...
exemple8.qrc
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file>help.png</file>
</qresource>
</RCC>
t.vaira
(2011-2012)
48
LaclasseQToolBar
LaclasseQToolBarfournitunebarred'outilsquicontientunensemblede
contrles(gnralementdesicnes)etsituesouslesmenus.
Pourajouterunebarred'outils,ondoittoutd'abordappelerlamthode
addToolBar()deQMainWindow.
AvecQt,labarred'outilsutilisedesactionspourconstruirechacundeslmentsde
celleci.Lesboutonsdelabarred'outilssontdoncinsrsenajoutantdesactionset
enutilisantaddAction()ouinsertAction().
LesboutonspeuventtresparsenutilisantaddSeparator()ouinsertSeparator().
Maisonpeutaussiinsrerunwidget(commeQSpinBox,QDoubleSpinBoxou
QComboBox)l'aidedeaddWidget()ouinsertWidget().
Quandunboutondelabarreest
enfonce,ilmetlesignal
actionTriggered().
t.vaira
(2011-2012)
49
QMainWindow:exemplen9
class MyMainWindow : public QmainWindow {
public: MyMainWindow() {
QMenu *fileMenu = new QMenu(tr("&Fichier"), this);
menuBar()->addMenu(fileMenu);
QAction *actionNouveau = new QAction(QIcon(":/images/new.png"),
tr("&Nouveau"), this);
actionNouveau->setShortcuts(QKeySequence::New);
fileMenu->addAction(actionNouveau);
fileMenu->addSeparator();
QAction *actionQuit = fileMenu->addAction(tr("&Quitter"), qApp,
SLOT(quit()), QKeySequence::Quit);
actionQuit->setIcon(QIcon(":/images/quit.png"));
QToolBar *fileToolBar = addToolBar("Fichier");
//fileToolBar->setMovable(false);
//fileToolBar->setFloatable(false);
fileToolBar->addAction(actionNouveau);
fileToolBar->addAction(actionQuit);
fileToolBar->addSeparator();
QFontComboBox *fontComboBox = new QFontComboBox;
fileToolBar->addWidget(fontComboBox);
}};
t.vaira
(2011-2012)
50
LaclasseQDockWidget
LaclasseQDockWidgetfournitunwidgetquipeuttreancrdansune
QMainWindowou"flotter"commeunefentredehautniveausurlebureau.
QDockWidgetfournitleconceptdedockwindows(palettesd'outilsoudefentres
d'utilit).Cesdockwindowssontdesfentressecondaires(ouminifentres)placs
danslazoneautourduwidgetcentrald'uneQMainWindow.
Beaucoupd'applicationsconnuesles
utilisent:QtDesigner,OpenOffice,
Photoshop,Code::Blocks,...
t.vaira
(2011-2012)
51
QMainWindow:exemplen10
Onpeutplacersespropreswidgetsdansunefentredockable:
class MyMainWindow : public QMainWindow {
public:
MyMainWindow() { ...
QDockWidget *dockWidget = new QDockWidget("Dock", this);
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
QWidget *dockContenu = new QWidget;
dockWidget->setWidget(dockContenu);
QVBoxLayout *dockLayout = new QVBoxLayout;
QFileSystemModel *model = new
QFileSystemModel;
model->setRootPath(QDir::currentPath());
QTreeView *vueArbre = new QTreeView;
vueArbre->setModel(model);
dockLayout->addWidget(vueArbre);
QPushButton *pushButton = new
QPushButton("Nouveau");
dockLayout->addWidget(pushButton);
dockContenu->setLayout(dockLayout);
...
t.vaira
(2011-2012)
52
LaclasseQStatusBar
LaclasseQStatusBarfournitunebarrehorizontaleappropriepourlaprsentation
desinformationsd'tat.QStatusBarpermetd'afficherdiffrentstypesd'indicateurs.
Unebarred'tatpeutaffichertroistypesdemessagesdiffrents:
temporaire:affichbrivement.Exemple:utilispourafficherlestextes
explicatifsdelabarred'outilsoudesentresdemenu.
normal:affichtoutletemps,saufquandunmessagetemporaireestaffich.
Exemple:utilispourafficherlapageetlenumrodelignedansuntraitementde
texte.
permanent:jamaiscach.Exemple:utilispourdesindicationsdemode
importantcommeleverrouillagedesmajuscules.
Labarred'tatpeuttrercuprl'aidedeQMainWindow::statusBar()etremplac
l'aidede
QMainWindow::setStatusBar().
t.vaira
(2011-2012)
53
QMainWindow:exemplen11
OnutilisezshowMessage()pourafficherunmessagetemporaire.Poursupprimerun
messagetemporaire,ilfautappelerclearMessage(),oufixerunelimitedetemps
lorsdel'appelshowMessage().
class MyMainWindow
: public QMainWindow
{
public:
MyMainWindow() {
...
QStatusBar *barreEtat = statusBar();
QProgressBar *progression = new QProgressBar;
barreEtat->addPermanentWidget(progression);
barreEtat->showMessage(QString::fromUtf8("Je suis la barre d'tat"),
2000);
...
t.vaira
(2011-2012)
54
QMainWindow:exemplen12
#include <QApplication>
#include <QtGui>
#include <QtWebKit>
class MyMainWindow : public QmainWindow {
public:
MyMainWindow() {
QWidget *centralWidget = new QWidget;
QToolBar *urlToolBar = addToolBar("URL");
QLineEdit *urlEdit = new QLineEdit;
QLabel *label = new QLabel(tr("Adresse :"));
urlToolBar->addWidget(label);
urlToolBar->addWidget(urlEdit);
webView = new QWebView;
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(webView);
centralWidget->setLayout(layout);
webView->load(QUrl("http://www.google.fr/"));
setCentralWidget(webView);
}
private:
QWebView *webView;
};
t.vaira
(2011-2012)
55
Graphique2D
Deuxapprochespourdessineren2DdansQt:
unmodlefonctionnelbassurQPainter
unmodleobjetbassurleframeworkGraphicsView
t.vaira
(2011-2012)
56
LeframeworkGraphicsView(1/4)
LeframeworkGraphicsViewsedcomposeen3partiesessentielles:
Lascne
Lavue
Leslmentsgraphiques
L'architectureGraphicsViewoffreuneapprochebasesurlepatternmodle
vue.Plusieursvuespeuventobserverunescneuniqueconstitued'lments
dediffrentesformesgomtriques.
t.vaira
(2011-2012)
57
LeframeworkGraphicsView(2/4)
LaclasseQGraphicsScenefournitlascnepourl'architectureGraphics
View.Lascnealesresponsabilitssuivantes:
fourniruneinterfacerapidepourgrerungrandnombred'lments,
propagerlesvnementschaquelment,
grerlestatsdeslments(tellesquelaslectionetlagestiondufocus)
etfournirdesfonctionnalitsderendunontransforme(principalement
pourl'impression).
LaclasseQGraphicsViewfournitlavue"widget"quipermetdevisualiserle
contenud'unescne.
t.vaira
(2011-2012)
58
LeframeworkGraphicsView(3/4)
LaclasseQGraphicsItemestlaclassedebasepourleslmentsgraphiques
dansunescne.
Ellefournitplusieurslmentsstandardpourlesformestypiques,tellesque:
desrectangles(QGraphicsRectItem),
desellipses(QGraphicsEllipseItem)et
deslmentsdetexte(QGraphicsTextItem).
Maislesfonctionnalitslespluspuissantesserontdisponibleslorsqueon
criraunlmentpersonnalis.
Entreautreschoses,QGraphicsItemsupportelesfonctionnalitssuivantes:
lesvnementssourisetclavier,leglissezetdposez(draganddrop),le
groupementd'lments,ladtectiondescollisions.
t.vaira
(2011-2012)
59
LeframeworkGraphicsView(4/4)
LascnesertdeconteneurpourlesobjetsQGraphicsItem.Laclasse
QGraphicsViewfournitlavue"widget"quipermetdevisualiserlecontenud'une
scne.
#include
#include
#include
#include
<QApplication>
<QGraphicsScene>
<QGraphicsRectItem>
<QgraphicsView>
return app.exec();
t.vaira
(2011-2012)
60
Dessin2D
EncollaborationaveclesclassesQPaintDevice
etQPaintEngine,QPainterestlabasedu
systmededessindeQt.
QPainterestlaclasseutilisepoureffectuer
lesoprationsdedessin.
QPaintDevicereprsenteundispositif
quipeuttrepeintenutilisant
unQPainter.
QPaintEnginefournitlemoteurderendu
etl'interface(abstraite)queQPainter
utilisepourdessinersurdiffrentstypesde
dispositifssuivantlaplateformeutilise.
t.vaira
(2011-2012)
61
QPainter(1/12)
LaclasseQPainterestlaclassedebasededessinbasniveausurleswidgetset
lesautresdispositifsdedessins.
QPainterfournitdesfonctionshautementoptimises:ilpeuttoutdessinerdes
lignessimplesdesformescomplexes.
QPainterpeutfonctionnersurn'importequelobjetquihritedelaclasse
QPaintDevice.
L'utilisationcourantedeQPainterestl'intrieurdelamthodepaintEvent()
d'unwidget:construire,personnaliser(parexemplelepinceau),dessineret
dtruirel'objetQPainteraprsledessin.
t.vaira
(2011-2012)
62
QPainter(2/12)
Unwidgetest"repeint":
Lorsqueunefentrepasseaudessus
Lorsquel'ondplacelecomposant
...
Lorsquel'onleluidemandeexplicitement:
repaint()entraneunrafraichissementimmdiat
update()metunedemandederafrachissementenfiled'attente
Danstouslescas,cestlamthodepaintEventquiestappele:
void paintEvent(QPaintEvent* e);
Pourdessinerdansunwidget,ilfautdoncredfinirQWidget::paintEvent().
t.vaira
(2011-2012)
63
QPainter:exemple1(3/12)
class MyWidget : public QWidget
{
public:
MyWidget( QWidget *parent = 0 ) : QWidget( parent ) {}
void paintEvent(QPaintEvent* e)
{
QWidget::paintEvent(e); // effectue le comportement standard
QPainter painter(this); // construire
painter.setPen( QPen(Qt::red, 2) ); // personnaliser
painter.drawRect( 25, 15, 120, 60 ); // dessiner
};
} // dtruire
t.vaira
(2011-2012)
64
QPainter(4/12)
LaclasseQPainterfournitdenombreusesmthodes:
setPen():lignesetcontours
setBrush():remplissage
setFont():texte
setTransform(),etc.:transformationsaffines
setClipRect/Path/Region():clipping(dcoupage)
setCompositionMode():composition
Lignesetcontours:drawPoint(),drawPoints(),drawLine(),drawLines(),
drawRect(),drawRects(),drawArc(),drawEllipse(),drawPolygon(),
drawPolyline(),etcetdrawPath()pourdescheminscomplexes
Remplissage:fillRect(),fillPath()
Divers:drawText(),drawPixmap(),drawImage(),drawPicture()
t.vaira
(2011-2012)
65
QPainter(5/12)
ConjointementlaclasseQpainter,onutilisedenombreusesautresclasses
utiles:
Entiers:QPoint,QLine,QRect,QPolygon
Flottants:QPointF,QLineF,...
Chemincomplexe:QPainterPath
Zonedaffichage:QRegion
Stylo(trait):QPen
Pinceau(remplissage):QBrush
Couleur:QColor
t.vaira
(2011-2012)
66
QPainter:exemple2(6/12)
class MyWidget : public QWidget
{
public:
MyWidget( QWidget *parent = 0 ) : QWidget( parent ) {}
void paintEvent(QPaintEvent* e)
{
QPainter painter(this);
QPen pen;
pen.setStyle(Qt::DashDotLine);
pen.setWidth(3);
pen.setBrush(Qt::green);
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin);
};
t.vaira
painter.setPen(pen);
painter.drawLine( 25, 15, 145, 75 );
painter.setPen( QPen(Qt::red, 2) );
painter.drawRect( 25, 15, 120, 60 );
(2011-2012)
67
QPainter:exemple3(7/12)
class MyWidget : public QWidget
{
public:
MyWidget( QWidget *parent = 0 ) : QWidget( parent ) {}
void paintEvent(QPaintEvent* e)
{
QPainter painter(this);
QBrush brush;
brush.setStyle(Qt::CrossPattern);
brush.setColor(Qt::blue);
};
t.vaira
painter.setBrush( brush );
painter.setPen( QPen(Qt::red, 2) );
painter.drawRect( 25, 15, 120, 60 );
(2011-2012)
68
QPainter:exemple4(8/12)
class MyWidget : public QWidget
{
public:
MyWidget( QWidget *parent = 0 ) : QWidget( parent ) {}
void paintEvent(QPaintEvent* e)
{
QPainter painter(this);
...
/*painter.setPen( QPen(Qt::black, 2) );
painter.drawEllipse(QRect(20, 10, 130, 70));
painter.drawRect(QRect(20, 10, 130, 70));*/
QRegion
QRegion
QRegion
QRegion
//painter.setClipRegion(r3);
painter.setClipRegion(r4);
...
}
};
t.vaira
(2011-2012)
69
QPainter:exemple5(9/12)
class MyWidget : public QWidget
{
public:
MyWidget( QWidget *parent = 0 ) : QWidget( parent ) {}
void paintEvent(QPaintEvent* e)
{
QPainter painter(this);
painter.setPen( QPen(Qt::darkRed, 2, Qt::DashDotLine) );
painter.drawRect( 25, 15, 120, 60 );
painter.translate(25, 15);
painter.rotate( 15.0 );
painter.translate(-25, -15);
painter.setPen( QPen(Qt::red, 2) );
painter.drawRect( 25, 15, 120, 60 );
}
};
t.vaira
(2011-2012)
70
QPainter:exemple5b(10/12)
class MyWidget : public Qwidget {
Q_OBJECT
qreal rotationAngle;
};
public:
MyWidget( QWidget *parent = 0 ) : QWidget( parent ) {}
void paintEvent(QPaintEvent* e) {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.scale(width() / 100.0, height() / 100.0);
painter.translate(50.0, 50.0);
painter.rotate(-rotationAngle);
painter.translate(-50.0, -50.0);
painter.setPen( QPen(Qt::red, 2) );
painter.drawRect( 25, 15, 50, 60 );
}
public slots:
void setRotationAngle(int degrees) {
rotationAngle = (qreal)degrees;
update();
}
t.vaira
(2011-2012)
71
QPainter:lesimages(11/12)
Qtfournitquatreclassesdetraitementdesdonnesd'image:QImage,
QPixmap,lesQBitmapetQPicture.
QImagefournitunereprsentationd'imageindpendantedumatrielqui
permetunaccsdirectauxpixels.QImageestconuetoptimispourles
E/S.
QPixmapestconuetoptimispourafficherlesimagessurl'cran.
QBitmapn'estqu'uneclassedecommoditquihriteQPixmap.
QPictureestundispositifpermettantd'enregistrerdescommandesd'un
QPainteretdelesrejouer.
Ces4classeshritentdeQPaintDeviceetonpeutdoncdessinerdedansavec
unQPainter.
Ellespossdentaussilesmthodesload()etsave()d'accsauxfichiers(dont
lesprincipauxformatssontsupports).
t.vaira
(2011-2012)
72
QPainter:exemple6(12/12)
class MyWidget : public QWidget
{
public:
MyWidget( QWidget *parent = 0 ) : QWidget( parent ) {}
void paintEvent(QPaintEvent* e)
{
QWidget::paintEvent(e);
QPainter painter(this);
QRect rect(0, 0, 170, 45);
QPixmap pixmap;
pixmap.load("qt-logo.png");
};
t.vaira
(2011-2012)
73
Gestionnaired'vnementssouris
GestiondesvnementssurunQWidget:
Lorsqu'onpresseunbouton
void mousePressEvent(QMouseEvent* e);
Lorsqu'onrelcheunbouton void mouseReleaseEvent(QMouseEvent* e);
Lorsqu'ondplacelasouris
void mouseMoveEvent(QMouseEvent* e);
Lorsqu'ondoubleclique
void mouseDoubleClickEvent(QMouseEvent*
e);
Pourrecevoirdesvnementsdelasourisdanssespropreswidgets,ilsuffit
doncderimplmentercesgestionnairesd'vnements(eventhandler).
LaclasseQMouseEventcontientlesparamtresquidcriventunvnement
delasouris:leboutonquiadclenchl'vnement,l'tatdesautresboutons
etlapositiondelasouris.
t.vaira
(2011-2012)
74
Exemple7(1/2)
LewidgetQLabelnepossdepasdesignalclicked()(commelesQPushButtonpar
exemple).OnvadonclecrerpartirdugestionnairemousePressEvent().
class MyLabel : public QLabel
{
Q_OBJECT
... // voir diapo suivante
void mousePressEvent(QMouseEvent *e)
{
if(e->button() == Qt::LeftButton)
emit clicked();
}
private slots:
void selection() {
QMessageBox msgBox;
msgBox.setText(QString::fromUtf8("Vous avez cliqu sur mon label !"));
msgBox.exec();
}
signals:
void clicked();
};
t.vaira
(2011-2012)
75
Exemple7(2/2)
class MyLabel : public Qlabel {
Q_OBJECT
public:
MyLabel( QLabel *parent = 0 ) : QLabel( parent ) {
QPalette palette;
palette.setColor(QPalette::Window,
QColor(QColor(0,255,0)));
setAutoFillBackground(true);
setPalette(palette);
setFrameStyle(QFrame::Panel | QFrame::Sunken);
setText("mon label");
setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
connect(this,SIGNAL(clicked()),this,SLOT(selection())); // clic bouton
gauche
QAction *quitAction = new QAction(tr("E&xit"), this);
quitAction->setShortcut(tr("Ctrl+Q"));
connect(quitAction,SIGNAL(triggered()),qApp,SLOT(quit()));
addAction(quitAction);
setContextMenuPolicy(Qt::ActionsContextMenu); // clic bouton droit
}
};
t.vaira
(2011-2012)
76
QPicture:exemple8
QPictureestundispositifpermettantd'enregistrerdescommandesd'un
QPainteretdelesrejouer.
QPicture picture;
QPainter painter;
painter.begin(&picture);
painter.setPen( QPen(Qt::red, 2) );
painter.drawEllipse(25, 10, 120, 70);
painter.end();
picture.save("drawing.pic");
drawing.pic
QPicture picture;
picture.load("drawing.pic");
QPainter painter;
painter.begin(this);
painter.drawPicture(0, 0, picture);
painter.end();
t.vaira
(2011-2012)
77
QImage:exemple9
QImagefournitunereprsentationd'imageindpendantedumatrielqui
permetunaccsdirectauxpixels.
#include <QImage>
int main(int argc, char **argv) {
QImage image(3, 3, QImage::Format_RGB32);
QRgb value;
value = qRgb(0, 0, 255); // 0x0000FF
for(int i = 0; i < 3; i++)
image.setPixel(0, i, value);
value = qRgb(255, 255, 255); // blanc
for(int i = 0; i < 3; i++)
image.setPixel(1, i, value);
value = qRgb(255, 0, 0);
for(int i = 0; i < 3; i++)
image.setPixel(2, i, value);
image.save("france.png", "PNG");
}
return 0;
t.vaira
(2011-2012)
78
Leglisserdposer(1/11)
Le"glisserdposer"(drag&drop)estunmcanismevisuel
simplequipermetauxutilisateursdetransfrerdes
informationsentreetauseindesapplications.Le
glisserdposerestuneformedecopier/couper/coller.
Ilya4classesdebasepourgrerlesvnementsassocisl'actiondedeglisser
dposer:
QDragEnterEvent:vnementquiestenvoyunwidgetlorsquel'actionde
glisserdbute
QDragLeaveEvent:vnementquiestenvoyunwidgetlorsquel'actionde
glissersetermine
QDragMoveEvent:vnementquiestenvoyquanduneactiondeglisser
dposerestencours
QDropEvent:vnementquiestenvoyquanduneactiondeglisserdposerest
termine
t.vaira
(2011-2012)
79
Leglisserdposer(2/11)
Ilyaparconsquence4gestionnairesd'vnementsassocis:
void
void
void
void
dragEnterEvent(QDragEnterEvent *event);
dragLeaveEvent(QDragLeaveEvent *event);
dragMoveEvent(QDragMoveEvent *event);
dropEvent(QDropEvent *event);
Pourdmarrerunglisserdposer,ilfautcrerunobjetQDragetappelersafonction
exec().
Lesactionspossiblessont:
Qt::CopyAction:Copielesdonnesverslacible.
Qt::MoveAction:Dplacerlesdonnesdelasourceverslacible.
Qt::LinkAction:Crerunliendelasourceverslacible.
N'importequeltyped'informationpeuttretransfrdansuneoprationdeglisser
dposer.Lesapplicationsconcernesdoiventtreenmesured'indiquerl'autrequels
sontlesformatsdedonnesgrsenutilisantdestypesMIME.
t.vaira
(2011-2012)
80
Leglisserdposer(3/11)
Pourillustrerlemcanismedebaseduglisserdposer,onvaprendreunexemple
simple.
L'application(exemplen10)vacrerdeuxzones(QFrame)danslesquellesseront
placesdeuxboutons.Lesboutonspeuventtreglisssdpossdansl'autrezone
maispasl'intrieurdesazoned'origine.Siunboutonestglissdpos,un
nouveauboutondemmelibellestcretleboutonsourceestdtruit.
Situation initiale
t.vaira
(2011-2012)
Le bouton 1 de gauche
en cours de glissage
Le bouton 1 a t dpos
dans la zone de droite
81
Leglisserdposer:exemple10(4/11)
Oncresonproprewidgetbouton:
class MyPushButton : public QPushButton {
Q_OBJECT
public:
MyPushButton(QString libelle, QWidget *p=0):QPushButton(libelle, p)
{
resize(120, 30);
QPalette palette;
palette.setColor(QPalette::Button, QColor(127,127,127));
palette.setColor(QPalette::ButtonText, QColor(Qt::white));
this->setPalette(palette);
}
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
QPoint dragStartPosition() {
return _dragStartPosition;
}
private:
QPoint _dragStartPosition;
};
t.vaira
(2011-2012)
82
Leglisserdposer:exemple10(5/11)
Danslaplupartdescas,l'oprationdeglisserdposerdmarrelorsqu'unboutondela
sourisatpressetquelecurseuratdplacsurunecertainedistance.Eneffet,
certainswidgetsontbesoindefaireladistinctionentrelesclicsdelasourisetle
glisser.
Ilfaudradoncrimplmenterlegestionnaired'vnementmousePressEvent()du
widgetpourpourenregistrerlapositiondedpartduglisser.Puis,ilfaudra
rimplmentermouseMoveEvent()pourdterminersiunglisserdevraitcommencer.
t.vaira
(2011-2012)
83
Leglisserdposer:exemple10(6/11)
IlfaudrarimplmentermouseMoveEvent()pourdterminersiunglisserdevrait
commencer.OnutiliseralafonctionmanhattanLength()pourobteniruneestimation
approximativedeladistanceentrel'endroitoleclicdesourisaeulieuetlaposition
actuelleducurseur.
LesobjetsQMimeDataetQDragcrsparlewidgetsourcenedoiventpastre
supprimscarils
void
mouseMoveEvent(QMouseEvent *event)
{ serontdtruitspar
if (!(event->buttons() & Qt::LeftButton)) return;
Qt.
if ((event->pos() - _dragStartPosition).manhattanLength()
t.vaira
(2011-2012)
84
Leglisserdposer:exemple10(7/11)
Oncresapropreframequicontientdeuxboutons:
class MyFrame : public QFrame {
Q_OBJECT
public:
MyFrame( QWidget *parent = 0 ) : QFrame( parent ) {
setMinimumSize(170, 185);
setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
setAcceptDrops(true);
btn1 = new MyPushButton("Bouton 1", this);
btn1->move(25, 145);
btn2 = new MyPushButton("Bouton 2", this);
btn2->move(25, 45);
btn1->show(); btn2->show();
}
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
};
private:
MyPushButton *btn1;
MyPushButton *btn2;
t.vaira
(2011-2012)
85
Leglisserdposer:exemple10(8/11)
Lewidgetreceveurdevraaccepterledposerenappelantlamthode
setAcceptDrops(true)etrimplmenterlesgestionnairesd'vnementsassocisau
glisserdposer.
Toutd'abordlorsquel'actiondeglisserdbute:
class MyFrame : public QFrame {
Q_OBJECT
void dragEnterEvent(QDragEnterEvent *event)
{
if(event->mimeData()->hasFormat("text/plain") &&
event->proposedAction() == Qt::MoveAction)
{
event->acceptProposedAction();
}
else
{
event->ignore();
}
}
};
t.vaira
(2011-2012)
86
Leglisserdposer:exemple10(9/11)
Ensuite,ontraiteledplacementdu"glisser"envrifiantsionestdanslabonne
zonede"dposer".
class MyFrame : public QFrame {
Q_OBJECT
void dragMoveEvent(QDragMoveEvent *event)
{
if(event->mimeData()->hasFormat("text/plain") &&
event->proposedAction() == Qt::MoveAction)
{
MyPushButton *childBtn = static_cast<MyPushButton*>(event>source());
if(this == childBtn->parentWidget())
event->ignore();
else event->acceptProposedAction();
}
else
event->ignore();
}
};
t.vaira
(2011-2012)
87
Leglisserdposer:exemple10(10/11)
Onterminepargrerle"dposer"encrantunnouveauboutonl'endroitoilat
posenenrcuprantsonlibelldanslesdonnestransfres.
class MyFrame : public QFrame {
Q_OBJECT
void dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat("text/plain") &&
event->proposedAction() == Qt::MoveAction) {
MyPushButton *childBtn = static_cast<MyPushButton*>(event>source());
if(this != childBtn->parentWidget()) {
MyPushButton *newBtn = new MyPushButton(event->mimeData()>text(), this);
newBtn->move(event->pos() - childBtn->dragStartPosition());
newBtn->show();
}
event->acceptProposedAction();
}
else event->ignore();
}
};
t.vaira
(2011-2012)
88
Leglisserdposer:exemple10(11/11)
Onpeutaussi"glisserdposer"unboutondenotreapplicationversuneautre
application.OnutiliseiciunexemplefourniparQt:dropsite.
Lebouton1atdplac
dansl'applicationdropsite
quiarcuprlesdonnes
associes:c'estdireson
libellsoitBouton1.
Documentationsurle"glisserdposer":
http://qtproject.org/doc/qt4.8/dnd.html
t.vaira
(2011-2012)
89