Arrière-plan translucide
Cet exemple montre comment créer une fenêtre ronde avec un arrière-plan translucide.

Les widgets dont l'arrière-plan est défini comme translucide seront transparents pour tous les pixels non peints, et l'arrière-plan transparaîtra à travers les pixels peints avec une opacité inférieure à 100 %. Les pixels qui ne sont pas peints du tout ne recevront pas non plus d'entrée de souris. Cela peut être utilisé pour personnaliser les formes des widgets de niveau supérieur. Sur la plupart des systèmes de gestion des fenêtres, le fait de définir certains indicateurs de fenêtre entraîne la désactivation de la décoration de la fenêtre (barre de titre, cadre de fenêtre, boutons), ce qui permet de créer des fenêtres de forme particulière. Dans cet exemple, nous utilisons cette fonctionnalité pour créer une fenêtre circulaire contenant une horloge analogique.
Comme la fenêtre de cet exemple ne comporte ni menu « File » (Fenêtre > Fermer) ni bouton de fermeture, nous proposons un menu contextuel comportant une entrée « Exit » (Fermer la fenêtre) afin de pouvoir fermer l’exemple. Cliquez avec le bouton droit de la souris sur la fenêtre pour ouvrir ce menu.
Définition de la classe ShapedClock
La classe ` ShapedClock ` s’appuie sur la classe ` AnalogClock ` définie dans l’exemple « Horloge analogique ». La définition complète de la classe est présentée ci-dessous :
class ShapedClock : public QWidget
{
Q_OBJECT
public:
ShapedClock(QWidget *parent = nullptr);
QSize sizeHint() const override;
protected:
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *event) override;
private:
QPoint dragPosition;
};L’implémentation de la méthode ` paintEvent()` dessine une horloge analogique sur un fond semi-transparent (le cadran). De plus, nous implémentons la méthode ` sizeHint()` afin de ne pas avoir à redimensionner explicitement le widget.
Comme la fenêtre contenant le widget d’horloge n’aura pas de barre de titre, nous fournissons des implémentations pour les méthodes ` mouseMoveEvent()` et ` mousePressEvent()` afin de permettre de faire glisser l’horloge sur l’écran. La variable ` dragPosition ` nous permet de garder une trace de l’endroit où l’utilisateur a cliqué en dernier sur le widget.
Implémentation de la classe ShapedClock
Le constructeur ShapedClock configure un minuteur et le relie au slot update() du widget. De plus, nous ajoutons une action au widget, qui sera automatiquement accessible via un menu contextuel lorsque l’on clique avec le bouton droit sur le widget.
ShapedClock::ShapedClock(QWidget *parent)
: QWidget(parent, Qt::FramelessWindowHint | Qt::WindowSystemMenuHint)
{
setAttribute(Qt::WA_TranslucentBackground);
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, QOverload<>::of(&ShapedClock::update));
timer->start(1000);
QAction *quitAction = new QAction(tr("E&xit"), this);
quitAction->setShortcut(tr("Ctrl+Q"));
connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
addAction(quitAction);
setContextMenuPolicy(Qt::ActionsContextMenu);
setToolTip(tr("Drag the clock with the left mouse button.\n"
"Use the right mouse button to open a context menu."));
setWindowTitle(tr("Shaped Analog Clock"));
}Nous demandons une fenêtre transparente en définissant l’attribut ` Qt::WA_TranslucentBackground ` du widget. Nous indiquons au gestionnaire de fenêtres que le widget ne doit pas être encadré en activant le drapeau ` Qt::FramelessWindowHint ` sur le widget. Par conséquent, nous devons fournir à l’utilisateur un moyen de déplacer l’horloge sur l’écran.
Les événements liés aux boutons de la souris sont transmis au gestionnaire ` mousePressEvent() ` :
void ShapedClock::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
dragPosition = event->globalPosition().toPoint() - frameGeometry().topLeft();
event->accept();
}
}Si le bouton gauche de la souris est enfoncé sur le widget, nous enregistrons le déplacement en coordonnées globales (à l'écran) entre la position en haut à gauche du cadre du widget (même lorsqu’il est masqué) et le point où le clic de souris a eu lieu. Ce déplacement sera utilisé si l’utilisateur déplace la souris tout en maintenant le bouton gauche enfoncé. Comme nous avons réagi à l’événement, nous l’acceptons en appelant sa fonction ` accept()`.

Le gestionnaire ` mouseMoveEvent() ` est appelé lorsque la souris est déplacée au-dessus du widget.
void ShapedClock::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
move(event->globalPosition().toPoint() - dragPosition);
event->accept();
}
}Si le bouton gauche est maintenu enfoncé pendant le déplacement de la souris, le coin supérieur gauche du widget est déplacé vers le point obtenu en soustrayant l’ dragPosition de la position actuelle du curseur en coordonnées globales. Si nous faisons glisser le widget, nous acceptons également l’événement.
La fonction ` paintEvent() ` est globalement identique à celle décrite dans l'exemple de l'horloge analogique. La seule différence est que nous utilisons ` QPainter::drawEllipse()` pour dessiner un cadran d'horloge rond. Nous réduisons l'opacité du peintre à 90 % et utilisons la couleur d'arrière-plan par défaut de la palette.
void ShapedClock::paintEvent(QPaintEvent *)
{
static const QPoint hourHand[4] = {
QPoint(5, 14),
QPoint(-5, 14),
QPoint(-4, -71),
QPoint(4, -71)
};
static const QPoint minuteHand[4] = {
QPoint(4, 14),
QPoint(-4, 14),
QPoint(-3, -89),
QPoint(3, -89)
};
static const QPoint secondsHand[4] = {
QPoint(1, 14),
QPoint(-1, 14),
QPoint(-1, -89),
QPoint(1, -89)
};
const QColor hourColor(palette().color(QPalette::Text));
const QColor minuteColor(palette().color(QPalette::Text));
const QColor secondsColor(palette().color(QPalette::Accent));
int side = qMin(width(), height());
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(width() / 2, height() / 2);
painter.scale(side / 200.0, side / 200.0);
painter.setPen(Qt::NoPen);
painter.setBrush(palette().window());
painter.setOpacity(0.9);
painter.drawEllipse(QPoint(0, 0), 98, 98);
painter.setOpacity(1.0);
QTime time = QTime::currentTime();
painter.setPen(Qt::NoPen);
painter.setBrush(hourColor);
{
QPainterStateGuard guard(&painter);
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter.drawConvexPolygon(hourHand, 4);
}
for (int i = 0; i < 12; ++i) {
painter.drawRect(73, -3, 16, 6);
painter.rotate(30.0);
}
painter.setBrush(minuteColor);
{
QPainterStateGuard guard(&painter);
painter.rotate(6.0 * time.minute());
painter.drawConvexPolygon(minuteHand, 4);
}
painter.setBrush(secondsColor);
{
QPainterStateGuard guard(&painter);
painter.rotate(6.0 * time.second());
painter.drawConvexPolygon(secondsHand, 4);
painter.drawEllipse(-3, -3, 6, 6);
painter.drawEllipse(-5, -68, 10, 10);
}
painter.setPen(minuteColor);
for (int j = 0; j < 60; ++j) {
painter.drawLine(92, 0, 96, 0);
painter.rotate(6.0);
}
}Enfin, nous implémentons la fonction ` sizeHint() ` pour le widget afin qu’il se voie attribuer une taille par défaut raisonnable lors de son premier affichage :
© 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.