How do I keep my screen contents centered and also have a scrollbar in QT?

52 Views Asked by At

I started learning QT but I'm having difficulty keeping a QVBoxLayout centered but also having the ScrollArea remain functional.

I've searched for a solution online and everyone keeps telling me that a ScrollArea should have a widget within it and not a layout but when I do that the ScrollArea starts functioning but the QVBoxLayout no longer stays in the center of the window.

Here's my mainwindow.cpp file's contents:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QMainWindow>
#include <QPushButton>
#include <QApplication>

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QScrollArea>
#include <QObject>
#include <QLabel>
#include <QLineEdit>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QScrollArea *scrollArea = new QScrollArea();
    QVBoxLayout *innerVerticalLayout = new QVBoxLayout;
    QVBoxLayout *verticalLayout = new QVBoxLayout;
    verticalLayout->setAlignment(Qt::AlignTop);
    QWidget *verticalLayoutWidgetContainer = new QWidget();
    verticalLayoutWidgetContainer->setLayout(verticalLayout);
    verticalLayoutWidgetContainer->setFixedWidth(1000);


    QHBoxLayout *horizontalLayout = new QHBoxLayout;
    horizontalLayout->setAlignment(Qt::AlignTop);
    QPushButton *leftButton = new QPushButton("Left Button");
    leftButton->setFixedWidth(100);
    QPushButton *rightButton = new QPushButton("Right Button");
    rightButton->setFixedWidth(100);
    horizontalLayout->addWidget(leftButton, 0, Qt::AlignLeft);
    horizontalLayout->addWidget(rightButton, 0, Qt::AlignRight);


    QHBoxLayout *horizontalLayout1 = new QHBoxLayout;
    horizontalLayout1->setAlignment(Qt::AlignTop);
    QPushButton *centerButton = new QPushButton("Center Button");
    centerButton->setFixedWidth(100);
    horizontalLayout1->addWidget(centerButton, 0, Qt::AlignHCenter);

    QHBoxLayout *horizontalLayout2 = new QHBoxLayout;
    horizontalLayout2->setAlignment(Qt::AlignTop);
    QPushButton *rightButton1 = new QPushButton("Right Button");
    rightButton1->setFixedWidth(100);
    horizontalLayout2->addWidget(rightButton1, 0, Qt::AlignRight);


    verticalLayout->addLayout(horizontalLayout, 0);
    verticalLayout->addLayout(horizontalLayout1, 0);
    verticalLayout->addLayout(horizontalLayout2, 0);

    innerVerticalLayout->addWidget(verticalLayoutWidgetContainer, 0, Qt::AlignHCenter | Qt::AlignTop);
    scrollArea->setLayout(innerVerticalLayout);
    this->setCentralWidget(scrollArea);  
}

MainWindow::~MainWindow()
{
 delete ui;
}

Edit: Adding links to show how the app works when I have a layout/widget in the ScrollArea and how I would like it to work.

Link 1: How the ScrollArea works with a layout in it. https://i.imgur.com/oJghW1O.mp4 The ScrollArea doesn't work but the layout behaves as I intended. It has a fixed width and stays in the center of it's container.

Link 2: How the ScrollArea behaves with a widget in it (I wrapped the layout in a widget). https://i.imgur.com/nMaVmdi.mp4 The ScrollArea works but the layout doesn't stay in the center anymore.

What I want is for the layout to stay in the center and the ScrollArea to work too.

Note the first video (Where the ScrollArea doesn't work) is the result of the code above.

The second video is achieved by wrapping the layout in a widget and then setting it as the widget of the ScrollArea:

- scrollArea->setLayout(innerVerticalLayout);

+ QWidget *innerVerticalLayoutWidgetContainer = new QWidget();
+ innerVerticalLayoutWidgetContainer->setLayout(innerVerticalLayout);
+ scrollArea->setWidget(innerVerticalLayoutWidgetContainer);

1

There are 1 best solutions below

0
Victor On

I think I fixed it. I subscribed to the resize event of the MainWindow and made the outermost layout's (Wrapped in a widget) width match the width of the MainWindow whenever the width of the main window became larger than the width of the centered layout like so:

void MainWindow::resizeEvent(QResizeEvent* event)
{
    if (this->width() > verticalLayoutWidgetContainer->width())
        innerVerticalLayoutWidgetContainer->setFixedWidth(this->width() - 2);
    QMainWindow::resizeEvent(event);
}

I added the -2 because the ScrollArea's horizontal bar would never disappear when the -2 wasn't there.