QScrollArea & Vertical Scroll Bar - How To



  • Hello,

    I'm trying to make a dialog that becomes scroll-able if needed.
    So far I have this>
    alt text

    And, in my code>

    .h file
    private:
        Ui::AddProduct *ui;
        QPushButton *addbuton;
        QPushButton *deletebutton;
        QWidget *widget_2;
        QVBoxLayout *mainLayout;
        int counter;
    
    .cpp file
    AddProduct::AddProduct(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::AddProduct)
    {    
        ui->setupUi(this);
        mainLayout = new QVBoxLayout(this);
        ui->widget_2->setLayout(mainLayout);
        counter = 0;
    }
    
    void AddProduct::on_addbuton_clicked()
    {
        counter += 1;
        QHBoxLayout *top = new QHBoxLayout;
        QLabel *lblTest = new QLabel();
        lblTest->setText(QString("Test: %1").arg(counter));
        QLineEdit *txtTest = new QLineEdit();
    
        top->addWidget(lblTest);
        top->addWidget(txtTest);
    
        top->maximumSize();
    
        mainLayout->addLayout(top);
    }
    

    And, so far this works good. Each time I click on AddButton, new QLabel and QLineEdit appear at the center of the widget... After I click it once more, first duo moves up a bit, and then they share the widget. And so on.. I can add as much as I want of those duos. However, at one point it gets really crowded and I can't see anything written in those LineEdits.

    I would like there to be an option of some Vertical Scroll Bar appearing when its needed (when there is just enough of lines so they don't have to be minimized just yet), and when I click add once more, I want vertical ruler to show up and enable me to create even more.

    I have tried many different combinations with QScrollArea and QScrollBar but was nowhere near finding a good solution.

    Can anybody help please?

    Thanks.



  • The only one thing is missing - QScrollArea.

    Think about 2 different widgets:

    1. is dialog with only QScrollArea and buttons add, delete, ok and cancel in layout.
      Scroll are should be in place of the selected frame on your picture.

    2. is a widget where you are going to add your buttons. This widget you will be setting to scroll area
      scrollArea->setWidget( myWidget ); You can change this widget layout.

    Simple example of QScrollArea usage from documentation:

    QLabel *imageLabel = new QLabel;
    QImage image("happyguy.png");
    imageLabel->setPixmap(QPixmap::fromImage(image));

    scrollArea = new QScrollArea;
    scrollArea->setBackgroundRole(QPalette::Dark);
    scrollArea->setWidget(imageLabel);

    All you need is to replace QLAble with widget you are adding buttons to.



  • Hello and thanks for the fast reply.

    I have tried something in the manner of your proposal but it doesn't seem to work. I have changed my constructor to>

    AddProduct::AddProduct(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::AddProduct)
    {    
        ui->setupUi(this);
        QScrollArea *scrollArea = new QScrollArea;
        mainLayout = new QVBoxLayout(this);
        ui->widget_2->setLayout(mainLayout);
        scrollArea->setWidget(ui->widget_2);
        counter = 0;
    }
    

    But now, after I click the addbutton absolutely nothing happens.

    EDIT>
    Tried:

    AddProduct::AddProduct(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::AddProduct)
    {    
        ui->setupUi(this);
        mainLayout = new QVBoxLayout(this);
        ui->scrollArea->setLayout(mainLayout);  //defined in .h file, also exists in Designer
        counter = 0;
    }
    

    Still same 'overcrowding' problem.
    alt textalt textalt text



  • Scroll area as any other widget has to be in a layout.
    And you did not put it in any.

    More of that you removed ui->widget_2, from layout.
    by : scrollArea->setWidget(ui->widget_2);
    so you see nothing.

    You had to place scrollArea in the layout instead of ui->widget_2

    When you add buttons, you had to change widget layout of the widget which is set to scroll area with
    ui->scrollArea->setWidget(.... )

    If you used a wizard to place scroll area to ui, it would call this widget something like ui.scrollAreaWidgetContents



  • Thank you!

    I edited constructor to this:

    AddProduct::AddProduct(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::AddProduct)
    {    
        ui->setupUi(this);
        mainLayout = new QVBoxLayout(this);
        ui->scrollAreaWidgetContents->setLayout(mainLayout);
        counter = 0;
    }
    

    And it works perfectly!



  • Just one more question, if anybody knows...

    When I create a QLineEdit with this pushbutton I add it to QList<QLineEdit*> lineEdits;

    Then, i tried something like this>

    void AddProduct::on_deletebutton_clicked()
    {
        foreach (QLineEdit* txtText, lineEdits) {
            if(txtText->hasFocus())
                qDebug()<<"found focus";  //for testing purposes  
                //mainLayout->removeWidget(txtText);  //of of these 
                //txtText->deleteLater();                             //should work
        }
    }
    

    However if never gets called, and I don't know why because I definitely have keyboard focus on one of QLineEdit widgets before the pushbutton click.


  • Lifetime Qt Champion

    Hi,

    The focus changed when you clicked the button. What you can do is to keep track on the currently focused QLineEdit in a member variable so you can use it at deletion time. Or you could add a remove button besides your QLineEdit and use that to remove them.



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.