I would like to fill a QGridLayout
with QWidgets
. The QWidgets
need to appear in a top-left to top-right fashion and proceed to fill the down downwards after each row is filled with QWidgets
. An example of a similar and familiar GUI is how Apple sorts its apps on the iPhone or iPad's home screen. The apps go top-left to top-right and proceed to go downward after each row is filled.
Right now, whenever I add elements, they take up the entirety of the screen and/or aren't added next to each other.
This is example code of what I am doing
m_gridLayout = new QGridLayout(this);
this->setLayout(m_gridLayout);
m_gridLayout->addWidget(widgetToBeAdded, m_currentRow, m_currentColumn, Qt::AlignLeft);
I proceed to update m_currentColumn and m_currentRow as expected. After a certain amount of columns, I tell it to change to the next row, and nothing happens. I have confirmed through debugging that it is infact spitting out the correct rows and columns.)
Eventually, I will need to throw on a QScrollArea
so that one can scroll down the grid.
The size of each QWidget
will be the same. If I could get any help in regards to sorting the grid properly, it would be much appreciated.
EDIT: Using the answer below, I have managed to get my items to sort in the correct order. However, there is a large amount of space in between all elements in the vertical direction. This is not obviated by changing the verticalSpacing property, as I would think. Does anyone know how to proceed?
Write your own grid layout, something like this:
Header
#ifndef MY_GRID_LAYOUT_H
#define MY_GRID_LAYOUT_H
#include <QGridLayout>
class my_grid_layout : public QGridLayout
{
public:
my_grid_layout(QWidget *parent, int max_column_count );
~my_grid_layout();
void add_widget( QWidget* p_widget );
private:
int m_max_column_count;
};
#endif // MY_GRID_LAYOUT_H
Source
#include "my_grid_layout.h"
my_grid_layout::my_grid_layout(QWidget *parent, int max_column_count)
: QGridLayout(parent)
{
m_max_column_count = max_column_count;
}
my_grid_layout::~my_grid_layout()
{
}
void my_grid_layout::add_widget( QWidget* p_widget )
{
int current_row = 0;
int current_column = 0;
while( itemAtPosition(current_row, current_column) != 0 )
{
if( current_column == (m_max_column_count-1) )
{
current_column = 0;
++current_row;
}
else
{
++current_column;
}
}
QGridLayout::addWidget( p_widget, current_row, current_column );
}
Test in a main window
#include "test_1.h"
Test_1::Test_1(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
m_grid_layout = new my_grid_layout(this,4);
m_grid_layout->add_widget( new QPushButton( "Widget 0", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 1", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 2", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 3", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 4", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 5", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 6", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 7", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 8", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 9", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 10", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 11", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 12", this ) );
m_grid_layout->add_widget( new QPushButton( "Widget 13", this ) );
QWidget* central_widget = new QWidget(this);
central_widget->setLayout(m_grid_layout);
setCentralWidget(central_widget);
}
Test_1::~Test_1()
{
}
Result
While there is already an item at a certain position, switch to the next position in the grid layout, which has a maximum column count of 4 in my example. I just switch to next column until I reached the 4th column. Then I reset the column to 0 and switch to the next row. I do this as long as there is already an item. As soon as there is no item in that place, I put my widget there.
This is just a quick example, but maybe it's enough for you to work with.
You should enhance it by error handling, watch out for endless loop and such...