Programmation Qt/Les widgets
Cette page présente certains widgets de Qt, ceux que vous utiliserez principalement.
Introduction
modifierTout d'abord, bienvenue dans ce nouveau chapitre. Avant de voir tous ces widgets, apprenons les choses essentielles :
- Pour créer un objet, nous avons deux possibilités :
QBlablabla *mon_blabla = new QBlablabla();
QBlabla mon_blablabla;
- En suite, les objets possèdent des propriétés. Exemple :
text
. Pour y accéder, on utilisera la méthodetext()
et pour modifier,setText()
. - Les objets créés avec la première méthode utilisent des pointeurs
->
et n'ont pas besoin de&
pour accesseurs. À l'inverse, ceux de la deuxième méthode utilisent des pointeurs.
et ont besoin de&
pour accesseurs.
QWidget
: le widget de base
modifier
QWidget
est LE widget de base. QWidget
hérite de QObject
. Quand on envoie un widget, tel qu'il soit, s'il n'a pas de widget parent, la fenêtre sera lancée et prendra la taille de celui-ci. Voici des propriétés pour les QWidget
.
Propriétés pour les widgets classiques comme pour les fenêtres
modifiergeometry
: la méthodesetGeometry()
attend la taille du widget (L, l) et le positionnement du widget (x, y)size
: comme pourgeometry
, sauf que cette fois-ci, ce n'est que la taille qu'on attendmove
: n'attend que le positionnementheight
: la hauteur du widgetwidth
: la largeur du widget
Propriétés utilisables uniquement avec les fenêtres
modifierwindowFlags
: le type de fenêtre. Pour une fenêtre de type "Outil", il faut écrire :setWindowFlags(Qt::Tools);
windowIcon
: l'icone de la fenêtre.setIcon()
attend un objetQIcon
qui attend lui-même le nom de l'image :setWindowIcon(QIcon("iconeLogiciel.png"));
windowTitle
: le titre de la fenêtre.setWindowTitle("Mon programme en Qt");
Les widgets afficheurs
modifierQLabel
: afficher un texte ou une image
modifier
QLabel
est un objet de Qt. Il permet d'afficher un texte ou une image.
Afficher du texte
modifierPour afficher du texte, il suffit d'écrire :
QLabel *m_texte = new QLabel(); // Création de l"objet
m_texte->setText("Hello world !"); // Définition du texte
La méthode à utiliser est donc setText()
. Pour récupérer ce texte, utilisez la méthode text()
.
Afficher une image
modifier
Pour afficher une image, utilisez la méthode setPixmap()
:
QLabel *m_image = new QLabel();
m_image->setPixmap(QPixmap("mon_image.png");
Vous pouvez utiliser la méthode pixmap()
qui vous renvoie un QPixmap
.
QProgressBar
: une barre de progression
modifier
Pour afficher une barre de progression, il faut écrire :
QProgressBar *m_progressbar = new QProgressBar(); /* Création de la barre de progression */
m_progressbar->setValue(50); /* Choix de la valeur de la barre → 50 % */
On remarque la présence de la méthode setValue()
, pour choisir la valeur de cet objet, et on en déduit qu'il faut utiliser value()
pour récupérer cette valeur. Pour les signaux, il y a valueChanged()
qui s'active quand la valeur change.
QLCDNumber
: un label pour nombre
modifier
Un QLCDNumber
est un label pour des nombres, mais dont l'écriture est type radio-réveil. On a la plupart des mêmes propriétés et signaux de QProgressBar
pour le QLCDNumber
.
QTableWidget
: un tableau
modifier
Un QTableWidget
est un widget pour afficher un tableau. Ce tableau a la particularité d'afficher automatiquement des barres de défilement.
QTableWidget *m_tableau = new QTableWidget(); /* Création de l'objet */
m_tableau->setRowCount(5); /* Définition du nombre de lignes */
m_tableau->setColumnCount(1); /* Définition du nombre de colonnes */
QTableWidgetItem *itemQt = new QTableWidgetItem(tr("Qt"), .arg(pow(row+1, column))); /* Création d'un objet QTableWidgetItem */
m_tableau->setItem(row, column, itemQt); /* Ajout de l'item */
On remarque que pour créer un item, on doit utiliser un objet spécialement créé pour cela, qui se nomme QTableWidgetItem
. Le fonctionnement est un peu étrange, mais on aura souvent à changer seulement le texte. Dans ce cas, ce n'était pas très intelligent d'utiliser un QTableWidget
car un QListView
était plus adapté.
Insérer les items
modifierPour insérer un item, vous créez votre classe QTableWidgetItem
, puis, avec la méthode setItem()
, vous l'insérez en précisant, la ligne, puis la colonne et enfin l'item. Vous pouvez aussi utiliser la méthode setIcon()
pour insérer une icône à l'item.
Donner des titres aux lignes et aux colonnes
modifierPour donner des titres aux lignes et aux colonnes, vous utilisez les méthodes setHorizontalHeaderItem()
pour les colonnes et setVerticalHeaderItem()
pour les lignes. Ces deux méthodes fonctionnent de la même façon : vous précisez le numéro de la colonne ou de la ligne, puis l'item qui sera inséré à cette place.
QListWidget
: une liste
modifier
Un QListWidget
est un widget pour liste. Il affiche automatiquement une barre de progression si besoin.
Les boutons
modifierQPushButton
: un bouton classique
modifier
QPushButton
est une classe de Qt permettant de créer un bouton de type classique.
QPushButton *m_pushbutton = new QPushButton();
m_pushbutton->setText("Quitter");
Signaux
modifierclicked()
: est envoyé quand on clique sur le boutonpressed()
: est envoyé tant que le bouton est presséereleased()
: est envoyé quand le bouton est relâché
Application :
connect(&m_pushbutton, SIGNAL(clicked()), qApp, SLOT(quit()));/* L'application quittera quand on cliquera sur le bouton */
Le QPushButton
possède aussi la méthode setMenu()
, qui permet de créer un bouton affichant un menu quand on clique dessus, en donnant une classe QMenu
que nous étudierons dans un chapitre ultérieur.
QCheckBox
: une case à cocher
modifier
La case à cocher est présente dans Qt sous la forme d'un QCheckBox
. Pour en créer une, il faut suivre le processus habituel :
QCheckBox *caseACocher = new QCheckBox(" J'aime Qt");
QRadioButton
: un bouton radio
modifier
Les boutons radio sont des groupes de boutons dont un seul de ceux-ci peut être coché. Pour en créer, cela change car il faut créer un objet de type QGroupBox
, pour définir quels boutons iront ensemble ("Je programme en Qt" et "J'habite à New York" ne feront pas parti du même objet QGroupBox
). Observons donc le protocole :
QGroupBox *qgroupbox = new QGroupBox("Votre language de programmation préféré :"); /* Création du QGroupBox */
QRadioButton *cPlusPlus = new QRadioButton("C++"); /* Création de l'option C++ ... */
QRadioButton *python = new QRadioButton("Python"); /*..., de l'option Python ... */
QRadioButton *php = new QRadioButton("PHP"); /*..., et de l'option PHP */
QVBoxLayout *layout = new QVBoxLayout(); /* Création du layout */
layout->addWidget(cPlusPlus);/* Ajout des QRadioButton */
layout->addWidget(python);
layout->addWidget(php);
qgroupbox->setLayout(layout); /* Définition du layout pour l'objet QGroupBox */
Les champs
modifierLes champs sont des widgets où l’utilisateur entre une information.
QLineEdit
: un champ de texte à une ligne
modifier
Pour créer un champ de texte à une ligne en Qt, il faut créer un objet de type QLineEdit
:
QLineEdit *m_lineEdit = new QLineEdit();
m_lineEdit->setPlaceholder("Ex: Qt");
QTextEdit
: un champ de texte multi-ligne
modifier
Pour créer un champ de texte multi-ligne en Qt, c'est un objet QTextEdit
qu'il faut créer :
QTextEdit *m_textedit = new QTextEdit();
QSpinBox
: un champ de nombres
modifier
Un QSpinBox
est un champ de texte pour nombres. Le protocole pour créer un objet de ce type est le suivant :
QSpinBox *m_spinbox = new QSpinBox();
Propriétés
modifierstep
: le pas de déplacement des nombres.minimum
: la valeur minimalemaximum
: la valeur maximaleprefix
: un préfixe (texte avant le nombre)suffix
: un suffixe (texte après le nombre)
Modifions les propriétés ci-dessus :
m_spinbox->setStep(2); /* On se déplacera de 2 en 2 */
m_spinbox->setMinimum(0); /* La valeur minimale sera de 0 */
m_spinbox->setMaximum(100); /* La valeur maximale sera de 100 */
Exercice
modifierPour s'entraîner un peu, essayez de modifier la valeur d'un QProgressBar
avec un QSpinBox
.
QDoubleSpinBox
: un champ de nombres non-entiers
modifier
Un QDoubleSpinBox
est un QSpinBox
à l'exception qu'il gère aussi les nombres non-entiers. Pour créer un objet de ce type, suivez le code suivant :
QDoubleSpinBox *m_doublespinbox = new QDoubleSpinBox(); /* Création de l'objet */
Propriétés
modifier- les mêmes que
QSpinBox
decimal
: le nombre de chiffres après la virgule
Modifions les propriétés :
m_doublespinbox->setMinimum(0);
m_doublespinbox->setDecimal(2); /* Il y aura deux chiffres après la virgule */
QSlider
: un curseur
modifier
En Qt, QSlider
est une classe permettant de créer un curseur. Voici comment créer un objet de ce type :
QSlider *m_slider = new QSlider();
Propriétés
modifierorientation
: l'orientation duQSlider
value
: la valeur duQSlider
Signaux
modifiervalueChanged(int)
: est envoyé quand la valeur change, autrement dit quand on déplace le curseur
Exercice
modifierComme plus haut dans cette page, vous pouvez contrôler un QProgressBar
, mais avec cette fois-ci un QSlider
.
QDial
: un curseur en forme de cercle
modifier
Le fonctionnement de QDial
est quasiment le même que pour QSlider
, cependant arrêtons-nous sur la méthode setValue(int)
:
QDial *dial = new QDial();
dial->setValue(135);
Le nombre que représente le widget est un nombre en degrés (et non en radians).
QComboBox
: une liste déroulante
modifier
Une liste déroulante, QComboBox
, est l'équivalent de boutons radios (QRadioButton
), à l'exception que celle-ci ne prend qu'une petite place même pour une grande liste.
QComboBox *m_combobox = new QComboBox(); /* Création de la liste */
m_combobox->addItem("Paris"); /* Ajout des options */
m_combobox->addItem("Tokyo");
m_combobox->addItem("Ottawa");
Propriétés
modifiercount
: le nombre d'éléments dans la listecurrentId
: l'id de l'élément sélectionnécurrentText
: le texte de l'élément sélectionnéeditable
: un booléen qui autorise ou non l'ajout de valeurs personnalisées. Si l'option est activée (elle ne l'est pas par défaut), les nouveaux éléments seront placés à la fin de la liste.
Maintenant, nous allons écrire un petit code :
QPushButton *boutonEnvoyer = new QPushButton("Envoyer !"); /* Création d'un bouton pour envoyer la valeur de la liste */
connect(boutonEnvoyer, SIGNAL(clicked()), this, SLOT(QMessageBox::information(this, "Capitale", ("Votre capitale est : " + m_combobox->currentText()))));
QComboBox
a quelques classes filles, comme QFontComboBox
, un liste déroulante pour les polices.
QDateEdit
: un champ pour date
modifier
Un QDateEdit
se comporte à peu près comme un QSpinBox
. Dans les propriétés, value
est remplacé par date
. On utilise aussi la propriété maximumDate
et minimumDate
. On remarque aussi dateFormat
, pour le format de la date qui signifie YYYY-MM-DD
, DD/MM/YYYY
, etc...
Allez, un essai !
QDateEdit *qdateedit = new QDateEdit();
qdateedit->setMinimumDate(QDate(1715, 9, 1)); /* Mort de Louis XIV le 1er septembre 1715 */
qdateedit->setMaximumDate(QDate(3000, 12, 31)) /* Notre programme pourra servir jusqu'au 29ème siècle */
qdateedit->setDisplayFormat(QString("yyyy-MM-dd")); /* Format anglophone */
qdateedit->setDisplayFormat(QString("dd/MM/yyyy")); /* Format européen */
Vous remarquerez que les dates sont un peu étendues. Mais pour vous, ce sera au format anglophone ou européen ? La réponse est : au format européen, car displayFormat
est prend le dernier format donné, et cela pareil pour toutes les propriétés.
QTimeEdit
: un champ pour temps
modifier
Un QTimeEdit
se comporte comme QDateEdit
. Sont remplacés les date
par time
.
QTimeEdit *qtimeedit = new QTimeEdit();
/* Horaires d'école */
qtimeedit->setMinimumTime(QTime(9, 30, 0)); /* Démarrage des cours à 09:30:00 */
qtimeedit->setMaximumTime(QTime(16, 0, 0)); /* Fin des cours à 16:00:00 */
qtimeedit->setDisplayFormat(QString("hh:mm:ss")); /* Heures:Minutes:Secondes */
QDateTimeEdit
: un champ qui combine date et temps
modifier
Comme indiqué dans le titre de cette section, l'objet QDateTimeEdit
est une classe de Qt qui combine un QDateEdit
et un QTimeEdit
. Vous avez donc les propriétés de chacune des classes.
QCalendarWidget
: un calendrier
modifier
Il se peut que vous n'aimiez pas la présentation de QDateEdit
. Qt y a pensé ! Une classe QCalendarWidget
est à notre disposition.
QCalendarWidget *m_calendar = new QCalendarWidget();
m_calendar->setMinimumDate(QDate(1970 /* Année*/, 1 /* Mois */, 1 /* Jour */));
m_calendar->setGridVisible(true); /* Affichons la grille */
Eh oui, c'est plutôt compliqué d'insérer une date minimale (setMinimumDate()
) ou maximale (setMaximumDate()
). Bien évidemment, c'est au format anglophone (YYYY-MM-DD
) et non au notre (DD/MM/YYYY
).
Les widgets conteneurs
modifierDans cette section, nous allons découvrir les widgets fait pour contenir. Car un QPushButton
peut contenir un QProgressBar
. Ah oui, ce n'est pas malin, mais cela nous prouve que Qt est flexible.
QFrame
: une bordureQGroupBox
: pour contenir une catégorie de widgets (souvent utilisés pour lesQRadioButton
)QTabWidget
: un conteneur d'onglets
QFrame
: une bordure
modifier
Le fonctionnement de QFrame
est très simple :
QFrame *m_frame = new QFrame();
m_frame->setFrameStyle(QFrame::StyledPanel | QFrame::Raised) /* Exemple de bordure */
Ensuite, pour les widgets enfants, un setLayout(monLayout);
qui contient lui-même des widgets. À noter que QLabel
hérite de QFrame
, donc pas besoin d'insérer un QLabel
dans un QFrame
, puisque le label a déjà la fonctionnalité de la bordure.
QGroupBox
: un conteneur pour une catégorie de widgets
modifier
QGroupBox *conteneur = new QGroupBox();
conteneur->setTitle("Mon conteneur");
QProgressBar *progressBar = new QProgressBar();
QPushButton *pushButton = new QPushButton("Coucou !");
/* Layout */
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(progressBar);
layout->addWidget(pushButton);
conteneur->setLayout(layout);
Vous pouvez aussi utiliser la propriété setAlignment()
pour choisir l'alignement du titre (par défaut, celui-ci se trouve à gauche). À noter qu'il existe un constructeur tel que :
QGroupBox *conteneur = new QGroupBox();
conteneur->setTitle("Mon conteneur");
/* = */
QGroupBox *conteneur = new QGroupBox("Mon conteneur");
QTabWidget
: un conteneur à onglets
modifier
Un QTabWidget
est un conteneur à onglets. Il ne peut y avoir qu'un seul widget par onglets. Heureusement, un widget peut en contenir un autre, autrement dit vous pouvez mettre un layout qui contient tous les widgets que vous voulez.
QTabWidget *onglets = new QTabWidget();
QWidget *pageAccueil = new QWidget();
QLabel *bienvenue = new QLabel("Bienvenue à tous");
QPushButton *boutonQuitter = new QPushButton("Quitter");
connect(boutonQuitter, SIGNAL(clicked()), qApp, SLOT(quit()));
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(bienvenue);
layout->addWidget(boutonQuitter);
pageAccueil->setLayout(layout);
QLabel *image = new QLabel();
image->setPixmap(QPixmap("monImage.png"));
onglets->addTab(pageAccueil, "Accueil");
onglets->addTab(image, "Image");
Ce code affiche :
- un onglet Accueil qui contient le texte de bienvenue et le bouton Quitter.
- un onglet Image qui contient une image
Vous pouvez aussi mettre des QTabWidget
dans des QTabWidget
:
QTabWidget *univers = new QTabWidget();
QTabWidget *systemeSolaire = new QTabWidget();
QWidget *pageSoleil = new QWidget();
QWidget *pageMercure = new QWidget();
QWidget *pageEtc = new QWidget();
systemeSolaire->addTab(pageSoleil, "Soleil");
systemeSolaire->addTab(pageMercure, "Mercure");
systemeSolaire->addTab(pageEtc, "...");
univers->addTab(systemeSolaire, "Système solaire")
Exercices
modifierVoici maintenant une liste d'exercices un peu plus complexes que ceux directement dans les sections appropriées, mais moins que par rapport à des TP :
- Un champ de texte et un bouton dont ce dernier lance une boîte de dialogue avec le texte entré par l'utilisateur (renseignez-vous auprès de
QMessageBox
). - Deux boutons qui permettent d'augmenter et de diminuer la taille de la fenêtre
- Des boutons radios et un label qui affiche l'option choisie (ex : un label "Acheter des frites/hamburgers/salades → options")
- Un champ de texte qui modifie la valeur d'une des options (valeur personnalisée)
Entraînez-vous !
Bilan
modifierEt bien, vous avez appris quelque chose d'essentiel. N'hésitez pas à relire et à pratiquer. Il est effectivement essentiel de pratiquer, car si vous allumez l'ordinateur à la fin de la lecture du livre, c'est très mauvais. Si quelque chose ne va pas, allez dans la page de discussion et posez la question. Notre prochaine étape est le positionnement des widgets. Si tout est bon, je vous invite au chapitre suivant →.