63 votes

QVBoxLayout : Comment aligner verticalement les widgets en haut plutôt qu'au centre ?

Dans Qt, lorsque j'ajoute des widgets à ma disposition, ils sont centrés verticalement par défaut. Existe-t-il un moyen de "lister" les widgets de haut en bas au lieu de les centrer verticalement ?

57voto

coldfix Points 1041

Si vous avez un QVBoxLayout et que vous voulez que vos widgets de taille fixe soient empilés en haut, vous pouvez simplement ajouter un étirement vertical à la fin :

layout.addStretch()

Si vous avez plusieurs civières ou autres éléments d'étirement, vous pouvez spécifier un argument de facteur d'étirement entier qui définit leur rapport de taille.

Voir aussi addStretch y addSpacerItem .

Ajoutez deux layout.addStretch() avant et après avoir ajouté les widgets pour les centrer verticalement :

    layout.addStretch()
    layout.addWidget(self.message)
    layout.addWidget(self.userid_field)
    layout.addWidget(self.password_field)
    layout.addWidget(self.loginButton)
    layout.addStretch()

Je ne suis pas sûr que cela réponde à votre question initiale, mais c'est la réponse à celle que j'ai eue en cherchant sur Google et en arrivant sur cette page - elle pourrait donc être utile à d'autres.

55voto

Kunal Points 1943

Utiliser void QLayout::setAlignment ( Qt::Alignment alignment ) pour définir l'alignement en fonction de votre choix.

0 votes

Je ne pense pas que cela donne suffisamment d'informations. Pour commencer, cette méthode n'existe pas : elle est (dans PyQt5) setAlignment(QWidget *w, Qt::Alignment alignment) y setAlignment(QLayout *l, Qt::Alignment alignment) et mes premières expériences semblent montrer que l'utilisation de l'une ou l'autre de ces méthodes sur une QVBoxLayout ne permet pas simplement à ses composants ajoutés d'être alignés proprement au sommet ...

31voto

noisygecko Points 746

Je trouve cela un peu plus compliqué que de simplement utiliser layout.setAlignment() . Cela ne fonctionnait pas pour moi jusqu'à maintenant, lorsque j'ai compris que si vous avez des widgets en expansion pour lesquels vous avez défini une hauteur maximale, alors ce widget ne sera pas aligné comme vous le souhaitez.

Voici un exemple de code qui fait no aligner en haut les QTextBrowser() widget même si j'appelle layout.setAlignment(Qt.AlignTop) . Désolé qu'il soit en Python, mais il est assez facile à traduire en C++ (j'ai fait l'inverse plusieurs fois).

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class MyWidget(QWidget):
    """
    Create a widget that aligns its contents to the top.
    """

    def __init__(self, parent=None):

        QWidget.__init__(self, parent)

        layout = QVBoxLayout()

        label = QLabel('label:')
        layout.addWidget(label)

        info = QTextBrowser(self)
        info.setMinimumHeight(100)
        info.setMaximumHeight(200)
        layout.addWidget(info)        
        # Uncomment the next line to get this to align top.
#         layout.setAlignment(info, Qt.AlignTop)

        # Create a progress bar layout.
        button = QPushButton('Button 1')        
        layout.addWidget(button)        

        # This will align all the widgets to the top except
        # for the QTextBrowser() since it has a maximum size set.
        layout.setAlignment(Qt.AlignTop)

        self.setLayout(layout)

if __name__ == '__main__':

    import sys

    app = QApplication(sys.argv)

    widget = MyWidget()
    widget.show()
    widget.resize(QSize(900, 400))

    app.exec_()

Le texte suivant appelle explicitement layout.setAlignment(info, Qt.AlignTop) pour faire fonctionner le widget de texte en extension.

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class MyWidget(QWidget):
    """
    Create a widget that aligns its contents to the top.
    """

    def __init__(self, parent=None):

        QWidget.__init__(self, parent)

        layout = QVBoxLayout()

        label = QLabel('label:')
        layout.addWidget(label)

        info = QTextBrowser(self)
        info.setMinimumHeight(100)
        info.setMaximumHeight(200)
        layout.addWidget(info)        
        # Uncomment the next line to get this to align top.
        layout.setAlignment(info, Qt.AlignTop)

        # Create a progress bar layout.
        button = QPushButton('Button 1')        
        layout.addWidget(button)        

        # This will align all the widgets to the top except
        # for the QTextBrowser() since it has a maximum size set.
        layout.setAlignment(Qt.AlignTop)

        self.setLayout(layout)

if __name__ == '__main__':

    import sys

    app = QApplication(sys.argv)

    widget = MyWidget()
    widget.show()
    widget.resize(QSize(900, 400))

    app.exec_()

9voto

Starfight Points 176

Après comparaison entre les deux solutions, il semble que :

myLayout.setAlignment(Qt.AlignTop)

fonctionne pour plusieurs alignements de widgets mais :

myLayout.setAlignment(myWidget, Qt.AlignTop)

ne fonctionne que pour le premier widget que vous ajoutez à la mise en page. Après tout, la solution dépend aussi de la QSizePolicy de vos widgets.

0 votes

S'agit-il par hasard de PyQt4 ? Dans PyQt5, il n'y a pas de QLayout méthode setAlignment avec un paramètre : seule la deuxième solution existe.

2voto

JOE Points 105

Si vous utilisez QT creator, il vous suffit d'ajouter un "Vertical Spacers" au bas de votre widget.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X