Programmation Qt/Les widgets

Un livre de Wikilivres.



Cette page présente certains widgets de Qt, ceux que vous utiliserez principalement.

Introduction[modifier | modifier le wikicode]

Tout 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éthode text() 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 | modifier le wikicode]

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[modifier | modifier le wikicode]

  • geometry : la méthode setGeometry() attend la taille du widget (L, l) et le positionnement du widget (x, y)
  • size : comme pour geometry, sauf que cette fois-ci, ce n'est que la taille qu'on attend
  • move : n'attend que le positionnement
  • height : la hauteur du widget
  • width : la largeur du widget

Propriétés utilisables uniquement avec les fenêtres[modifier | modifier le wikicode]

  • windowFlags : 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 objet QIcon 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[modifier | modifier le wikicode]

QLabel : afficher un texte ou une image[modifier | modifier le wikicode]

QLabel est un objet de Qt. Il permet d'afficher un texte ou une image.

Afficher du texte[modifier | modifier le wikicode]

QLabel avec pour valeur "Hello world !"
Un QLabel avec le texte "Hello world !"

Pour 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 | modifier le wikicode]

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 | modifier le wikicode]

QProgressBar de valeur 50%
Une QProgressBar, avec pour valeur 50%

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 | modifier le wikicode]

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 | modifier le wikicode]

Capture d'écran d'un QTableWidget.
Un QTableWidget affichant des projets Wikimedia.

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[modifier | modifier le wikicode]

Pour 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[modifier | modifier le wikicode]

Pour 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 | modifier le wikicode]

Un QListWidget est un widget pour liste. Il affiche automatiquement une barre de progression si besoin.

Les boutons[modifier | modifier le wikicode]

QPushButton : un bouton classique[modifier | modifier le wikicode]

Bouton de type classique
Un bouton classique, affichant le texte "Quitter"

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[modifier | modifier le wikicode]

  • clicked() : est envoyé quand on clique sur le bouton
  • pressed() : est envoyé tant que le bouton est pressée
  • released() : 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 | modifier le wikicode]

Deux QCheckBox
Deux QCheckBox, mis en place grâce à un layout.

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 | modifier le wikicode]

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 :

Plusieurs QRadioButton réunis dans un QGroupBox
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[modifier | modifier le wikicode]

Les champs sont des widgets où l’utilisateur entre une information.

QLineEdit : un champ de texte à une ligne[modifier | modifier le wikicode]

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 | modifier le wikicode]

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 | modifier le wikicode]

Image représentative d'un QSpinBox.
Un QSpinBox.

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[modifier | modifier le wikicode]

  • step : le pas de déplacement des nombres.
  • minimum : la valeur minimale
  • maximum : la valeur maximale
  • prefix : 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[modifier | modifier le wikicode]

Pour s'entraîner un peu, essayez de modifier la valeur d'un QProgressBar avec un QSpinBox.

QDoubleSpinBox : un champ de nombres non-entiers[modifier | modifier le wikicode]

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 | modifier le wikicode]

  • 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 | modifier le wikicode]

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[modifier | modifier le wikicode]

  • orientation : l'orientation du QSlider
  • value : la valeur du QSlider

Signaux[modifier | modifier le wikicode]

  • valueChanged(int) : est envoyé quand la valeur change, autrement dit quand on déplace le curseur

Exercice[modifier | modifier le wikicode]

Comme 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 | modifier le wikicode]

Un QDial de valeur 135 environ.
Un QDial d'une valeur d'environ 135.

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 | modifier le wikicode]

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[modifier | modifier le wikicode]

  • count : le nombre d'éléments dans la liste
  • currentId : 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 | modifier le wikicode]

QDateEdit pour avec format anglophone
Un QDateEdit avec pour format yyyy-MM-dd.

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 | modifier le wikicode]

QTimeEdit avec format européen
Un QTimeEdit avec pour format hh:mm:ss.

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 | modifier le wikicode]

QDateTimeEdit avec format de date anglophone et format d'heure européen
Un QDateTimeEdit avec pour format dd-MM-YYYY hh:mm:ss.

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 | modifier le wikicode]

QCalendarWidget de date minimale le 1er janvier 1970
Un QCalendarWidget avec pour valeur minimale le 1er janvier 1970.

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[modifier | modifier le wikicode]

Dans 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 bordure
  • QGroupBox : pour contenir une catégorie de widgets (souvent utilisés pour les QRadioButton)
  • QTabWidget : un conteneur d'onglets

QFrame : une bordure[modifier | modifier le wikicode]

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 | modifier le wikicode]

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 | modifier le wikicode]

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[modifier | modifier le wikicode]

Voici 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[modifier | modifier le wikicode]

Et 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 →.