Search code examples
c++qtlayoutqscrollarea

QScrollArea with dynamically resizing subWidgets


So I have something like the following layout in my Qt Application.

QScroll Area
   - QSrollArea's InternalWidget
        -QVBoxLayout
           -Layout 1
              - some items
              - QTableView
           -Layout 2
              - some items
              - QTableView

The contents of the QTableViews is changing dynamically, and what i want is that each table view to be as large as it has to be( without progressbars and without empty space ). I have written a function to calculate the appropriate size of a table. The problem is that when i dynamically resize one of the TableViews it goes behind the second view( and what should happen is that the whole second layout be moved bellow the first ). Furthermore when shrink the table view there is an empty space left between it and the second layout.

enter image description here

Here is the code when i arrange the widgets:

#include "Widget.h"

#include <QVBoxLayout>
#include <QLabel>
#include <QTableView>
#include <QStringBuilder>
#include <QHeaderView>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent),
      m_tableView1( 0 ),
      m_tableView2( 0 ),
      m_model1( 0 ),
      m_model2( 0 ),
      m_numberOfRowsEdit( 0 )
{
    this->resize( 300, 520 );

    QVBoxLayout* mainLayout = new QVBoxLayout( this );

    QScrollArea* mainArea = new QScrollArea();
    //mainArea->setWidgetResizable( true );

    QWidget* scrollAreaWidget = new QWidget;
    scrollAreaWidget->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Expanding );

    QVBoxLayout* scrollAreaWidgetLayout = new QVBoxLayout( scrollAreaWidget );
    scrollAreaWidgetLayout->setSizeConstraint( QLayout::SetMinAndMaxSize );

    QVBoxLayout* firstSubLayout = new QVBoxLayout;
    QLabel* label = new QLabel( "Label 1" );
    m_tableView1 = new QTableView;

    firstSubLayout->addWidget( label );
    firstSubLayout->addWidget( m_tableView1 );

    scrollAreaWidgetLayout->addLayout( firstSubLayout );

    QVBoxLayout* secondSubLayout = new QVBoxLayout;
    QLabel* label2 = new QLabel( "Label 2" );
    m_tableView2 = new QTableView;

    secondSubLayout->addWidget( label2 );
    secondSubLayout->addWidget( m_tableView2 );

    scrollAreaWidgetLayout->addLayout( secondSubLayout );

    mainArea->setWidget( scrollAreaWidget );
    mainLayout->addWidget( mainArea );

    // Utility for dynamically changing rows
    QHBoxLayout* hLayout = new QHBoxLayout;

    QLabel* numberOfRowsLabel = new QLabel( "Number of rows" );
    m_numberOfRowsEdit = new QLineEdit;
    QPushButton* numberOfRowsButton = new QPushButton( "Apply" );

    connect( numberOfRowsButton, SIGNAL(clicked()), SLOT(onApplyButtonPressed()) );

    hLayout->addWidget( numberOfRowsLabel );
    hLayout->addWidget( m_numberOfRowsEdit );
    hLayout->addWidget( numberOfRowsButton );

    m_model1 = new QStandardItemModel( this );
    m_tableView1->setModel( m_model1 );

    m_model2 = new QStandardItemModel( this );
    m_tableView2->setModel( m_model2 );

    mainLayout->addLayout( hLayout );
}

Widget::~Widget()
{
}

QSize Widget::calculateTableDesiredSize( QTableView* const table ) {...}

void Widget::onApplyButtonPressed()
{
    bool ok = false;
    const int rowCount = m_numberOfRowsEdit->text().toInt( &ok );
    if ( !ok )
    {
        return;
    }

    this->initModel( m_model1, rowCount );
}

// inits model with rowCount rows
void Widget::initModel( QStandardItemModel* const model, const int rowCount  )
void Widget::resizeTable( QTableView* const table )

Solution

  • You should use setFixedHeight() instead of resize() to set table height. Also you should addStretch() to scrollAreaWidgetLayout after all its items.