# Programmation Qt/Les widgets

* Avant-propos
* Introduction
* Développer pour Windows 64 bits
* Un premier programme
* Signaux et slots
* Projet Qt
* Classes et objets Qt
* Extensions du langage C++
* Utilisation de Qt Creator
** Créer un projet
* Les widgets
* Le positionnement des widgets
* La fenêtre principale
* TP : un éditeur de texte
* Traduire son programme
* Sauvegarder des données avec XML
* Sauvegarder des données avec SQL
* TP : un navigateur web
* Utilisation de Qt Designer
* Utiliser la documentation Qt
* Distribuer son programme
* Ressources
Annexes
* Avant-propos
* Introduction
* Développer pour Windows 64 bits
* Un premier programme
* Signaux et slots
* Projet Qt
* Classes et objets Qt
* Extensions du langage C++
* Utilisation de Qt Creator
** Créer un projet
* Les widgets
* Le positionnement des widgets
* La fenêtre principale
* TP : un éditeur de texte
* Traduire son programme
* Sauvegarder des données avec XML
* Sauvegarder des données avec SQL
* TP : un navigateur web
* Utilisation de Qt Designer
* Utiliser la documentation Qt
* Distribuer son programme
* Ressources
Annexes
[ Modifier le sommaire ]
Cette page présente certains widgets de Qt, ceux que vous utiliserez principalement.

## Introduction

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 :
* 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

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

* 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

* 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
### QLabel : afficher un texte ou une image

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

#### Afficher du texte

Pour afficher du texte, il suffit d'écrire :
La méthode à utiliser est donc setText. Pour récupérer ce texte, utilisez la méthode text.

#### Afficher une image

Pour afficher une image, utilisez la méthode setPixmap :
Vous pouvez utiliser la méthode pixmap qui vous renvoie un QPixmap.

### QProgressBar : une barre de progression

Pour afficher une barre de progression, il faut écrire :
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

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

Un QTableWidget est un widget pour afficher un tableau. Ce tableau a la particularité d'afficher automatiquement des barres de défilement.
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

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

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

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

## Les boutons
### QPushButton : un bouton classique

QPushButton est une classe de Qt permettant de créer un bouton de type classique.

#### Signaux

* 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 :
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

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 :

### QRadioButton : un bouton radio

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 :

## Les champs

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

### QLineEdit : un champ de texte à une ligne

Pour créer un champ de texte à une ligne en Qt, il faut créer un objet de type QLineEdit :

### QTextEdit : un champ de texte multi-ligne

Pour créer un champ de texte multi-ligne en Qt, c'est un objet QTextEdit qu'il faut créer :

### QSpinBox : un champ de nombres

Un QSpinBox est un champ de texte pour nombres. Le protocole pour créer un objet de ce type est le suivant :

#### Propriétés

* 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 :

#### Exercice

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

### QDoubleSpinBox : un champ de nombres non-entiers

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 :

#### Propriétés

* les mêmes que QSpinBox
* decimal : le nombre de chiffres après la virgule
Modifions les propriétés :

### QSlider : un curseur

En Qt, QSlider est une classe permettant de créer un curseur. Voici comment créer un objet de ce type :

#### Propriétés

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

#### Signaux

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

#### Exercice

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

Le fonctionnement de QDial est quasiment le même que pour QSlider, cependant arrêtons-nous sur la méthode setValue(int) :
Le nombre que représente le widget est un nombre en degrés (et non en radians).

### QComboBox : une liste déroulante

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.

#### Propriétés

* 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 :
QComboBox a quelques classes filles, comme QFontComboBox, un liste déroulante pour les polices.

### QDateEdit : un champ pour date

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 !
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

Un QTimeEdit se comporte comme QDateEdit. Sont remplacés les date par time.

### QDateTimeEdit : un champ qui combine date et temps

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

Il se peut que vous n'aimiez pas la présentation de QDateEdit. Qt y a pensé ! Une classe QCalendarWidget est à notre disposition.
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

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

Le fonctionnement de QFrame est très simple :
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

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 :

### QTabWidget : un conteneur à onglets

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.
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 :

## Exercices

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

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