Exemple de curseurs
L'exemple des curseurs montre comment utiliser les différents types de curseurs disponibles dans Qt : QSlider, QScrollBar et QDial.
Qt Widgets fournit trois types de widgets de type curseur : QSlider, QScrollBar et QDial. Ils héritent tous de la plupart de leurs fonctionnalités de QAbstractSlider, et peuvent en théorie se remplacer les uns les autres dans une application puisque les différences ne concernent que leur aspect et leur convivialité. Cet exemple montre à quoi ils ressemblent, comment ils fonctionnent et comment leur comportement et leur apparence peuvent être manipulés par le biais de leurs propriétés.
L'exemple montre également comment les signaux et les slots peuvent être utilisés pour synchroniser le comportement de deux widgets ou plus, et comment surcharger resizeEvent() pour mettre en œuvre une mise en page réactive.

Capture d'écran de l'exemple Sliders
L'exemple Sliders se compose de deux classes :
SlidersGroupest un widget personnalisé. Il combine un QSlider, un QScrollBar et un QDial.Windowest le widget principal qui combine un QGroupBox et un SlidersGroup. La classe QGroupBox contient plusieurs widgets qui contrôlent le comportement des widgets de type curseur.
Nous examinerons d'abord la classe Window, puis la classe SlidersGroup.
Définition de la classe Window
class Window : public QWidget { Q_OBJECT public: Window(QWidget *parent = nullptr); private: void createControls(const QString &title); void resizeEvent(QResizeEvent *e); SlidersGroup *slidersGroup; QGroupBox *controlsGroup; QLabel *minimumLabel; QLabel *maximumLabel; QLabel *valueLabel; QCheckBox *invertedAppearance; QCheckBox *invertedKeyBindings; QSpinBox *minimumSpinBox; QSpinBox *maximumSpinBox; QSpinBox *valueSpinBox; QBoxLayout *layout; };
La classe Window hérite de la classe QWidget. Elle affiche les widgets de type curseur et permet à l'utilisateur de définir leurs valeurs minimale, maximale et actuelle, ainsi que de personnaliser leur apparence, leurs raccourcis clavier et leur orientation. Nous utilisons une fonction privée createControls() pour créer les widgets qui fournissent ces mécanismes de contrôle et pour les connecter aux widgets du curseur.
Mise en œuvre de la classe de fenêtre
Window::Window(QWidget *parent) : QWidget(parent) { slidersGroup = new SlidersGroup(tr("Sliders")); createControls(tr("Controls"));
Dans le constructeur, nous créons d'abord le widget SlidersGroup qui affiche les widgets du curseur. Avec createControls(), nous créons les widgets de contrôle et les connectons aux curseurs.
layout = new QBoxLayout(QBoxLayout::LeftToRight); layout->addWidget(controlsGroup); layout->addWidget(slidersGroup); setLayout(layout); minimumSpinBox->setValue(0); maximumSpinBox->setValue(20); valueSpinBox->setValue(5); setWindowTitle(tr("Sliders")); }
Nous plaçons les groupes de widgets de contrôle et les curseurs dans une disposition horizontale avant d'initialiser les valeurs minimale, maximale et actuelle. L'initialisation de la valeur actuelle se propagera aux widgets du curseur par le biais de la connexion que nous avons établie entre valueSpinBox et les widgets SlidersGroup. Les valeurs minimum et maximum se propagent à travers les connexions que nous avons créées avec createControls().
void Window::createControls(const QString &title) { controlsGroup = new QGroupBox(title); minimumLabel = new QLabel(tr("Minimum value:")); maximumLabel = new QLabel(tr("Maximum value:")); valueLabel = new QLabel(tr("Current value:")); invertedAppearance = new QCheckBox(tr("Inverted appearance")); invertedKeyBindings = new QCheckBox(tr("Inverted key bindings"));
Dans la fonction privée createControls(), nous laissons un QGroupBox (controlsGroup) afficher les widgets de contrôle. Une boîte de groupe peut fournir un cadre, un titre et un raccourci clavier, et affiche divers autres widgets à l'intérieur d'elle-même. Le groupe de widgets de contrôle est composé de deux cases à cocher et de trois boîtes de dialogue avec des étiquettes.
Après avoir créé les étiquettes, nous créons les deux cases à cocher. Les cases à cocher sont généralement utilisées pour représenter des fonctions d'une application qui peuvent être activées ou désactivées. Lorsque invertedAppearance est activé, les valeurs du curseur sont inversées. Le tableau ci-dessous montre l'apparence des différents widgets de type curseur :
| QSlider | QScrollBar | QDial | ||||
|---|---|---|---|---|---|---|
| Normal | Inversé | Normal | Inversé | Normal | Inversé | |
| Qt::Horizontal | De gauche à droite | De droite à gauche | Gauche à droite | De droite à gauche | Sens des aiguilles d'une montre | Dans le sens inverse des aiguilles d'une montre |
| Qt::Vertical | De bas en haut | De haut en bas | Du haut vers le bas | De bas en haut | Dans le sens des aiguilles d'une montre | Dans le sens inverse des aiguilles d'une montre |
Il est courant d'inverser l'apparence d'un curseur vertical QSlider. Un curseur vertical qui contrôle le volume, par exemple, ira typiquement de bas en haut (l'apparence non inversée), alors qu'un curseur vertical qui contrôle la position d'un objet sur l'écran peut aller de haut en bas, parce que les coordonnées de l'écran vont de haut en bas.
Lorsque l'option invertedKeyBindings est activée (ce qui correspond à la propriété QAbstractSlider::invertedControls ), les événements de roue et de touche du curseur sont inversés. Les liaisons de touches normales signifient que le défilement de la molette de la souris vers le haut ou l'utilisation de touches telles que "page up" augmentera la valeur actuelle du curseur vers son maximum. Inversé, les mêmes événements de roue et de touche déplaceront la valeur vers le minimum du curseur. Cela peut être utile si l'apparence d' un curseur est inversée : Certains utilisateurs peuvent s'attendre à ce que les touches continuent de fonctionner de la même manière sur la valeur, tandis que d'autres peuvent s'attendre à ce que PageUp signifie "vers le haut" à l'écran.
Notez que pour les barres de défilement horizontales et verticales, les touches sont inversées par défaut : PageDown augmente la valeur courante et PageUp la diminue.
minimumSpinBox = new QSpinBox; minimumSpinBox->setRange(-100, 100); minimumSpinBox->setSingleStep(1); maximumSpinBox = new QSpinBox; maximumSpinBox->setRange(-100, 100); maximumSpinBox->setSingleStep(1); valueSpinBox = new QSpinBox; valueSpinBox->setRange(-100, 100); valueSpinBox->setSingleStep(1);
Nous créons ensuite les boîtes de dialogue. QSpinBox permet à l'utilisateur de choisir une valeur en cliquant sur les boutons haut et bas ou en appuyant sur les touches Up et Down du clavier pour modifier la valeur actuellement affichée. L'utilisateur peut également saisir la valeur manuellement. Les boîtes à boutons contrôlent les valeurs minimales, maximales et actuelles pour les widgets QSlider, QScrollBar et QDial.
connect(slidersGroup, &SlidersGroup::valueChanged, valueSpinBox, &QSpinBox::setValue); connect(valueSpinBox, &QSpinBox::valueChanged, slidersGroup, &SlidersGroup::setValue); connect(minimumSpinBox, &QSpinBox::valueChanged, slidersGroup, &SlidersGroup::setMinimum); connect(maximumSpinBox, &QSpinBox::valueChanged, slidersGroup, &SlidersGroup::setMaximum); connect(invertedAppearance, &QCheckBox::toggled, slidersGroup, &SlidersGroup::invertAppearance); connect(invertedKeyBindings, &QCheckBox::toggled, slidersGroup, &SlidersGroup::invertKeyBindings); QGridLayout *controlsLayout = new QGridLayout; controlsLayout->addWidget(minimumLabel, 0, 0); controlsLayout->addWidget(maximumLabel, 1, 0); controlsLayout->addWidget(valueLabel, 2, 0); controlsLayout->addWidget(minimumSpinBox, 0, 1); controlsLayout->addWidget(maximumSpinBox, 1, 1); controlsLayout->addWidget(valueSpinBox, 2, 1); controlsLayout->addWidget(invertedAppearance, 0, 2); controlsLayout->addWidget(invertedKeyBindings, 1, 2); controlsGroup->setLayout(controlsLayout); }
Nous connectons ensuite slidersGroup et valueSpinBox l'un à l'autre, de sorte que les widgets du curseur et le widget de contrôle se comportent de manière synchronisée lorsque la valeur actuelle de l'un d'entre eux change. Le signal valueChanged() est émis avec la nouvelle valeur comme argument. Le slot setValue() fixe la valeur actuelle du widget à la nouvelle valeur et émet valueChanged() si la nouvelle valeur est différente de l'ancienne.
Nous synchronisons le comportement des widgets de contrôle et des widgets de curseur par le biais de leurs signaux et de leurs slots. Nous connectons chaque widget de contrôle au groupe horizontal et vertical de widgets de curseur. Nous connectons également orientationCombo à QStackedWidget, afin que la bonne "page" soit affichée. Enfin, nous disposons les widgets de contrôle dans un QGridLayout à l'intérieur du cadre controlsGroup.
void Window::resizeEvent(QResizeEvent *) { if (width() == 0 || height() == 0) return; const double aspectRatio = double(width()) / double(height()); if (aspectRatio < 1.0) { layout->setDirection(QBoxLayout::TopToBottom); slidersGroup->setOrientation(Qt::Horizontal); } else if (aspectRatio > 1.0) { layout->setDirection(QBoxLayout::LeftToRight); slidersGroup->setOrientation(Qt::Vertical); } }
Enfin, nous remplaçons resizeEvent() de QWidget. Nous évitons de diviser par zéro et calculons le rapport hauteur/largeur du widget. Si la fenêtre a un format portrait, nous définissons la disposition de manière à organiser les groupes de widgets de contrôle et les curseurs verticalement, et nous donnons aux curseurs une orientation horizontale. Si la fenêtre est au format paysage, nous modifions la disposition pour afficher les curseurs et les widgets de contrôle côte à côte, et nous donnons aux curseurs une orientation verticale.
Définition de la classe SlidersGroup
class SlidersGroup : public QGroupBox { Q_OBJECT public: SlidersGroup(const QString &title, QWidget *parent = nullptr); signals: void valueChanged(int value); public slots: void setValue(int value); void setMinimum(int value); void setMaximum(int value); void invertAppearance(bool invert); void invertKeyBindings(bool invert); void setOrientation(Qt::Orientation orientation); private: QSlider *slider; QScrollBar *scrollBar; QDial *dial; QBoxLayout *slidersLayout; };
La classe SlidersGroup hérite de QGroupBox. Elle fournit un cadre et un titre, et contient une QSlider, une QScrollBar et une QDial.
Nous fournissons un signal valueChanged() et un slot public setValue() avec des fonctionnalités équivalentes à celles de QAbstractSlider et QSpinBox. En outre, nous implémentons plusieurs autres slots publics pour définir les valeurs minimale et maximale, et inverser l'apparence des widgets du curseur ainsi que les liaisons de touches, et définir l'orientation.
Mise en œuvre de la classe SlidersGroup
SlidersGroup::SlidersGroup(const QString &title, QWidget *parent) : QGroupBox(title, parent) { slider = new QSlider; slider->setFocusPolicy(Qt::StrongFocus); slider->setTickPosition(QSlider::TicksBothSides); slider->setTickInterval(10); slider->setSingleStep(1); scrollBar = new QScrollBar; scrollBar->setFocusPolicy(Qt::StrongFocus); dial = new QDial; dial->setFocusPolicy(Qt::StrongFocus);
Nous commençons par créer les widgets de type curseur avec les propriétés appropriées. En particulier, nous définissons la politique de focalisation pour chaque widget. Qt::FocusPolicy est un type d'énumération qui définit les différentes politiques qu'un widget peut avoir en ce qui concerne l'acquisition de la focalisation du clavier. La politique Qt::StrongFocus signifie que le widget accepte le focus à la fois par tabulation et par clic.
connect(slider, &QSlider::valueChanged, scrollBar, &QScrollBar::setValue); connect(scrollBar, &QScrollBar::valueChanged, dial, &QDial::setValue); connect(dial, &QDial::valueChanged, slider, &QSlider::setValue); connect(dial, &QDial::valueChanged, this, &SlidersGroup::valueChanged);
Nous connectons ensuite les widgets entre eux, afin qu'ils restent synchronisés lorsque la valeur courante de l'un d'entre eux change.
Nous connectons le signal valueChanged() de dial au signal SlidersGroup de valueChanged(), afin d'informer les autres widgets de l'application (c'est-à-dire les widgets de contrôle) de la valeur modifiée.
slidersLayout = new QBoxLayout(QBoxLayout::LeftToRight); slidersLayout->addWidget(slider); slidersLayout->addWidget(scrollBar); slidersLayout->addWidget(dial); setLayout(slidersLayout); }
Enfin, nous créons la disposition des widgets du curseur dans le cadre. Nous commençons par une disposition horizontale des curseurs.
void SlidersGroup::setValue(int value) { slider->setValue(value); }
Le slot setValue() définit la valeur du widget QSlider. Il n'est pas nécessaire d'appeler explicitement setValue() sur les widgets QScrollBar et QDial, puisque QSlider émettra le signal valueChanged() lorsque sa valeur changera, ce qui déclenchera un effet domino.
void SlidersGroup::setMinimum(int value) { slider->setMinimum(value); scrollBar->setMinimum(value); dial->setMinimum(value); } void SlidersGroup::setMaximum(int value) { slider->setMaximum(value); scrollBar->setMaximum(value); dial->setMaximum(value); }
Les emplacements setMinimum() et setMaximum() sont utilisés par la classe Window pour définir la portée des widgets QSlider, QScrollBar et QDial.
void SlidersGroup::invertAppearance(bool invert) { slider->setInvertedAppearance(invert); scrollBar->setInvertedAppearance(invert); dial->setInvertedAppearance(invert); } void SlidersGroup::invertKeyBindings(bool invert) { slider->setInvertedControls(invert); scrollBar->setInvertedControls(invert); dial->setInvertedControls(invert); }
Les emplacements invertAppearance() et invertKeyBindings() contrôlent les propriétés invertedAppearance et invertedControls des widgets enfants.
void SlidersGroup::setOrientation(Qt::Orientation orientation) { slidersLayout->setDirection(orientation == Qt::Horizontal ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight); scrollBar->setOrientation(orientation); slider->setOrientation(orientation); }
Le slot setOrientation() contrôle la direction de la mise en page et l'orientation des curseurs. Dans un groupe horizontal, les curseurs ont une orientation horizontale et sont disposés les uns sur les autres. Dans un groupe vertical, les curseurs ont une orientation verticale et sont disposés les uns à côté des autres.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.