Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Placer un layout dans un scrollArea



  • Bonjour,

    J'essaie de placer des boutons (ou autres objets) dans un QScrollArea beaucoup plus grand que ma fenêtre.
    Mais j'aimerai aussi les réorganiser proprement avec un QVBoxLayout à l'intérieur du scrollArea.

    Mon code ne fonctionne pas. Pourriez-vous y jeter un coup d'oeil svp ?

    #include "mainwindow.h"
     
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        setFixedSize(1000,800);
        m_mainWidget = new QWidget(this);   // création du widget principal invisible supportant tous les autres éléments graphiques
        m_hLayout = new QHBoxLayout(this);  // Création d'un horizontal layout
     
     
        scrollArea = new QScrollArea(this); //scrollArea->setFixedSize(900,790);    // Création d'un ScrollArea
        scrollArea->setBackgroundRole(QPalette::LinkVisited);                       //
        scrollBar = new QScrollBar(this); scrollBar->setRange(1,2000);              // et d'une ScrollBar
     
     
        m_mainWidget->setLayout(m_hLayout); // le mainWidget sera d'abord organisé en colonnes (2 colonnes en fait... voir les 2 lignes suivantes)
        m_hLayout->addWidget(scrollArea);   // On place le ScrollArea dans la 1e cellule (colonne du horizontal layout)
        m_hLayout->addWidget(scrollBar);    // On place une ScrollBar dans la 2e cellule (colonne du horizontal layout)
     
     
     
        //m_vLayout = new QVBoxLayout(this);  // le scroll area contiendra un vertical layout
        //scrollArea->setLayout(m_vLayout);
     
     
     
        for (int i=0; i<365; i++) {
            QPushButton* btn = new QPushButton ("Sans nom",  scrollArea);
            list_btn.append(btn);
            list_btn[i]->setText(QString("bouton %1").arg(i));
            //m_vLayout->addWidget(btn);
            btn->move(10, 60*i);
        }
     
        setCentralWidget(m_mainWidget);
    }
     
    MainWindow::~MainWindow()
    {
     
    }
    

  • Lifetime Qt Champion

    Bonjour,
    En utilisant Google Translate, cela peut sembler étrange.

    Vous devez définir son widget de défilement.
    scrollArea->setWidgetResizable(true);
    scrollArea->setWidget(..)

    Voici un exemple qui crée une telle configuration.

       // setup scroll area
        auto scrollArea = new QScrollArea(centralWidget());
        scrollArea ->move(10, 10);
        scrollArea ->resize(400, 400); // you dont need this as you should put it in a layout in your widget
        scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
        scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
        scrollArea->setWidgetResizable(true);
        // set up its center widget as docs tells
        auto scrollAreaWidgetContents = new QWidget();
        auto verticalLayout = new QVBoxLayout(scrollAreaWidgetContents);
        verticalLayout->setSpacing(4);
        verticalLayout->setContentsMargins(4, 4, 4, 4);
        // setup the "row" handler widget using  a from layout
        auto rowHandlerwidget = new QWidget(scrollAreaWidgetContents);
        auto formLayout = new QFormLayout(rowHandlerwidget);
        formLayout->setSpacing(4);
        formLayout->setContentsMargins(1, 1, 1, 1);
        // add some "rows!
        for (int numRows = 0; numRows < 50; ++numRows) {
            auto label = new QLabel(rowHandlerwidget);
            label ->setText( "Im Setting:" + QString::number(numRows));
            formLayout->setWidget(numRows, QFormLayout::LabelRole, label);
            if ( numRows % 3 ) {
                auto lineEdit = new QLineEdit(rowHandlerwidget);
                formLayout->setWidget(numRows, QFormLayout::FieldRole, lineEdit);
            } else {
                auto combo = new QComboBox(rowHandlerwidget);
                 formLayout->setWidget(numRows, QFormLayout::FieldRole, combo);
            }
        }
        // assign row hander widget
        verticalLayout->addWidget(rowHandlerwidget);
        // assign scrollsbox widget
        scrollArea->setWidget(scrollAreaWidgetContents);
    

    alt text



  • Cette image c'est exactement ce que j'essaie de faire.

    Je viens de tester le code. Je l'ai mis dans la fonction MainWindow().
    Je n'ai aucune erreur, mais ma fenêtre est vide. Rien ne s'affiche dedans.

    Qu'est-ce que j'ai loupé ?


  • Lifetime Qt Champion

    Bonsoir,

    @mrjj said in Placer un layout dans un scrollArea:

    centralWidget()

    Est-ce qu'il y a un widget central ?
    Si non, il faut ajouter setCentralWidget(scrollArea);.



  • Tout à fait, c'était ça. Tout fonctionne.
    Etant débutant j'ai vraiment cherché partout depuis trois jours un code valide, et j'ai vu que je n'étais pas le seul à avoir cherché ce sujet.

    J'aimerais donc remettre le code complet proposé par mrjj, pour que d'autres puissent s'en inspirer.
    Super bout de code ! Merci.

    main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    
    #include <QScrollArea>
    #include <QFormLayout>
    #include <QVBoxLayout>
    #include <QLabel>
    #include <QLineEdit>
    #include <QComboBox>
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private:
        QScrollArea* scrollArea;
        QFormLayout* formLayout;
        QVBoxLayout* verticalLayout;
        QLabel* label;
        QLineEdit* lineEdit;
        QComboBox* combo;
    
    };
    
    #endif // MAINWINDOW_H
    
    

    mainwindow.cpp

    #include "mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        setFixedSize(1000,800);
    
        scrollArea = new QScrollArea(centralWidget());
        scrollArea ->move(10, 10);
        scrollArea ->resize(400, 400); // you dont need this as you should put it in a layout in your widget
        scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
        scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
        scrollArea->setBackgroundRole(QPalette::LinkVisited);
        scrollArea->setWidgetResizable(true);
    
        // set up its center widget as docs tells
        auto scrollAreaWidgetContents = new QWidget();
        verticalLayout = new QVBoxLayout(scrollAreaWidgetContents);
        verticalLayout->setSpacing(4);
        verticalLayout->setContentsMargins(4, 4, 4, 4);
    
        // setup the "row" handler widget using  a from layout
        auto rowHandlerwidget = new QWidget(scrollAreaWidgetContents);
    
        formLayout = new QFormLayout(rowHandlerwidget);
        formLayout->setSpacing(4);
        formLayout->setContentsMargins(1, 1, 1, 1);
    
        // add some "rows!
        for (int numRows = 0; numRows < 50; ++numRows) {
            label = new QLabel(rowHandlerwidget);
            label ->setText( "Im Setting:" + QString::number(numRows));
            formLayout->setWidget(numRows, QFormLayout::LabelRole, label);
            if ( numRows % 3 ) {
                lineEdit = new QLineEdit(rowHandlerwidget);
                formLayout->setWidget(numRows, QFormLayout::FieldRole, lineEdit);
            } else {
                combo = new QComboBox(rowHandlerwidget);
                formLayout->setWidget(numRows, QFormLayout::FieldRole, combo);
            }
        }
        // assign row hander widget
        verticalLayout->addWidget(rowHandlerwidget);
    
    
        // assign scrollsbox widget
        scrollArea->setWidget(scrollAreaWidgetContents);
    
        setCentralWidget(scrollArea);
    
    }
    
    
    
    MainWindow::~MainWindow()
    {
    
    }
    
    
    

  • Lifetime Qt Champion

    @Morgatte said in Placer un layout dans un scrollArea:

    scrollArea = new QScrollArea(centralWidget());

    centralWidget() n'est du coup pas utile puisque de toute façon un pointeur null est retourné.


Log in to reply