Exemple de disposition des flux
Montre comment disposer les widgets en fonction de la taille des fenêtres.
Flow Layout met en œuvre une disposition qui gère différentes tailles de fenêtres. L'emplacement des widgets change en fonction de la largeur de la fenêtre de l'application.

La classe Flowlayout utilise principalement QLayout et QWidgetItem, tandis que la classe Window utilise QWidget et QLabel.
Pour plus d'informations, consultez la page Gestion des dispositions.
Exécution de l'exemple
Pour exécuter l'exemple à partir de Qt CreatorOuvrez le mode Welcome et sélectionnez l'exemple à partir de Examples. Pour plus d'informations, voir Qt Creator: Tutoriel : Construire et exécuter.
Définition de la classe FlowLayout
La classe FlowLayout hérite de QLayout. Il s'agit d'une classe de présentation personnalisée qui organise ses widgets enfants horizontalement et verticalement.
class FlowLayout : public QLayout { public: explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); ~FlowLayout(); void addItem(QLayoutItem *item) override; int horizontalSpacing() const; int verticalSpacing() const; Qt::Orientations expandingDirections() const override; bool hasHeightForWidth() const override; int heightForWidth(int) const override; int count() const override; QLayoutItem *itemAt(int index) const override; QSize minimumSize() const override; void setGeometry(const QRect &rect) override; QSize sizeHint() const override; QLayoutItem *takeAt(int index) override; private: int doLayout(const QRect &rect, bool testOnly) const; int smartSpacing(QStyle::PixelMetric pm) const; QList<QLayoutItem *> itemList; int m_hSpace; int m_vSpace; };
Nous réimplémentons les fonctions héritées de QLayout. Ces fonctions ajoutent des éléments à la disposition et gèrent leur orientation et leur géométrie.
Nous déclarons également deux méthodes privées, doLayout() et smartSpacing(). doLayout() dispose les éléments de la mise en page, tandis que la fonction smartSpacing() calcule l'espacement entre eux.
Mise en œuvre de la classe FlowLayout
Nous commençons par examiner le constructeur :
FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) { setContentsMargins(margin, margin, margin, margin); } FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) : m_hSpace(hSpacing), m_vSpace(vSpacing) { setContentsMargins(margin, margin, margin, margin); }
Dans le constructeur, nous appelons setContentsMargins() pour définir les marges gauche, supérieure, droite et inférieure. Par défaut, QLayout utilise les valeurs fournies par le style actuel (voir QStyle::PixelMetric).
FlowLayout::~FlowLayout() { QLayoutItem *item; while ((item = takeAt(0))) delete item; }
Dans cet exemple, nous réimplémentons addItem(), qui est une fonction virtuelle pure. Lors de l'utilisation de addItem(), la propriété des éléments de la mise en page est transférée à la mise en page, et c'est donc à la mise en page qu'il incombe de les supprimer.
void FlowLayout::addItem(QLayoutItem *item) { itemList.append(item); }
addItem() est implémentée pour ajouter des éléments à la mise en page.
int FlowLayout::horizontalSpacing() const { if (m_hSpace >= 0) { return m_hSpace; } else { return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); } } int FlowLayout::verticalSpacing() const { if (m_vSpace >= 0) { return m_vSpace; } else { return smartSpacing(QStyle::PM_LayoutVerticalSpacing); } }
Nous implémentons horizontalSpacing() et verticalSpacing() pour connaître l'espacement entre les widgets à l'intérieur de la disposition. Si la valeur est inférieure ou égale à 0, c'est cette valeur qui sera utilisée. Dans le cas contraire, smartSpacing() sera appelé pour calculer l'espacement.
int FlowLayout::count() const { return itemList.size(); } QLayoutItem *FlowLayout::itemAt(int index) const { return itemList.value(index); } QLayoutItem *FlowLayout::takeAt(int index) { if (index >= 0 && index < itemList.size()) return itemList.takeAt(index); return nullptr; }
Nous implémentons ensuite count() pour renvoyer le nombre d'éléments dans la présentation. Pour naviguer dans la liste des éléments, nous utilisons itemAt() et takeAt() pour supprimer et renvoyer des éléments de la liste. Si un élément est supprimé, les éléments restants seront renumérotés. Ces trois fonctions sont des fonctions virtuelles pures de QLayout.
Qt::Orientations FlowLayout::expandingDirections() const { return { }; }
expandingDirections() renvoie les Qt::Orientations dans lesquels la mise en page peut utiliser plus d'espace que son sizeHint().
bool FlowLayout::hasHeightForWidth() const { return true; } int FlowLayout::heightForWidth(int width) const { int height = doLayout(QRect(0, 0, width, 0), true); return height; }
Pour s'adapter aux widgets dont la hauteur dépend de la largeur, nous implémentons heightForWidth(). La fonction hasHeightForWidth() est utilisée pour tester cette dépendance, et heightForWidth() transmet la largeur à doLayout() qui, à son tour, utilise la largeur comme argument pour le rectangle de mise en page, c'est-à-dire les limites dans lesquelles les éléments sont disposés. Ce rect n'inclut pas la marge de mise en page().
void FlowLayout::setGeometry(const QRect &rect) { QLayout::setGeometry(rect); doLayout(rect, false); } QSize FlowLayout::sizeHint() const { return minimumSize(); } QSize FlowLayout::minimumSize() const { QSize size; for (const QLayoutItem *item : std::as_const(itemList)) size = size.expandedTo(item->minimumSize()); const QMargins margins = contentsMargins(); size += QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); return size; }
setGeometry() est normalement utilisée pour effectuer la mise en page proprement dite, c'est-à-dire pour calculer la géométrie des éléments de la mise en page. Dans cet exemple, il appelle doLayout() et transmet le rectangle de mise en page.
sizeHint() renvoie la taille préférée de la mise en page et minimumSize() renvoie la taille minimale de la mise en page.
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const { int left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); int x = effectiveRect.x(); int y = effectiveRect.y(); int lineHeight = 0;
doLayout() gère la mise en page si horizontalSpacing() ou verticalSpacing() ne renvoie pas la valeur par défaut. Il utilise getContentsMargins() pour calculer la zone disponible pour les éléments de la mise en page.
for (QLayoutItem *item : std::as_const(itemList)) { const QWidget *wid = item->widget(); int spaceX = horizontalSpacing(); if (spaceX == -1) spaceX = wid->style()->layoutSpacing( QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); int spaceY = verticalSpacing(); if (spaceY == -1) spaceY = wid->style()->layoutSpacing( QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
Il définit ensuite l'espacement approprié pour chaque widget de la mise en page, en fonction du style actuel.
int nextX = x + item->sizeHint().width() + spaceX; if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { x = effectiveRect.x(); y = y + lineHeight + spaceY; nextX = x + item->sizeHint().width() + spaceX; lineHeight = 0; } if (!testOnly) item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); x = nextX; lineHeight = qMax(lineHeight, item->sizeHint().height()); } return y + lineHeight - rect.y() + bottom; }
La position de chaque élément dans la mise en page est ensuite calculée en ajoutant la largeur des éléments et la hauteur de la ligne aux coordonnées x et y initiales. Cela nous permet de savoir si l'élément suivant tiendra sur la ligne actuelle ou s'il doit être déplacé vers la ligne suivante. Nous déterminons également la hauteur de la ligne actuelle en fonction de la hauteur du widget.
int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const { QObject *parent = this->parent(); if (!parent) { return -1; } else if (parent->isWidgetType()) { QWidget *pw = static_cast<QWidget *>(parent); return pw->style()->pixelMetric(pm, nullptr, pw); } else { return static_cast<QLayout *>(parent)->spacing(); } }
smartSpacing() est conçu pour obtenir l'espacement par défaut pour les mises en page de niveau supérieur ou les sous-mises en page. L'espacement par défaut des présentations de niveau supérieur, lorsque le parent est une page QWidget, sera déterminé en interrogeant le style. L'espacement par défaut des sous-mises en page, lorsque le parent est QLayout, est déterminé par l'interrogation de l'espacement de la mise en page parentale.
© 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.