将需要进行流式布局的元素存到QList集合中,利用QStringcrollArea + QGridLayout + 每当窗体大小改变时,重新计算QGridLayout每行能放几个元素,再将QList集合中元素addWidget()到QGridLayout内重新排列即可。
用于实现流式布局的容器
用于流式布局容器内的元素
将元素添加到集合中,对元素限定最大最小宽高,设置元素对象名称以便配置css样式
FlowLayoutTestUI::FlowLayoutTestUI(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
//ui.scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
//ui.scrollArea->setWidgetResizable(true);
int item_w = 240;
int item_h = 140;
FlowLayoutTestItem* item1 = new FlowLayoutTestItem(this);
item1->setObjectName("FlowLayoutTestItem1");
item1->Widget()->setObjectName("FlowLayoutTestItem1_Widget");
item1->PushButton()->setObjectName("FlowLayoutTestItem1_PushButton");
item1->setMaximumSize(QSize(item_w, item_h));
item1->setMinimumSize(QSize(item_w, item_h));
flItems.append(item1);
ui.gridLayout->addWidget(item1);
FlowLayoutTestItem* item2 = new FlowLayoutTestItem(this);
item2->setObjectName("FlowLayoutTestItem2");
item2->Widget()->setObjectName("FlowLayoutTestItem2_Widget");
item2->PushButton()->setObjectName("FlowLayoutTestItem2_PushButton");
item2->setMaximumSize(QSize(item_w, item_h));
item2->setMinimumSize(QSize(item_w, item_h));
flItems.append(item2);
ui.gridLayout->addWidget(item2);
//........
实现流式布局的方法
void FlowLayoutTestUI::SetFlowLayout(QScrollArea* scr, QGridLayout* gri, Qt::Alignment alig, QList<FlowLayoutTestItem*> items, int item_w)
{
int col_cnt =(scr->width() - scr->widget()->layout()->contentsMargins().left() - scr->widget()->layout()->contentsMargins().right() - gri->contentsMargins().left() - gri->contentsMargins().right()) / (item_w + gri->horizontalSpacing());
int row_cnt = 0;
if (!col_cnt) return;
if (!items.size()) return;
if (items.size() % col_cnt)
row_cnt = items.size() / col_cnt + 1;
else row_cnt = items.size() / col_cnt;
for (int i = 0; i < row_cnt; i++)
{
for (int j = 0; j < col_cnt; j++)
{
if (col_cnt * i + j < items.size())
gri->addWidget(items.at(col_cnt * i + j), i, j, alig);
}
//gri->setColumnStretch(i,1);
}
}
重写事件触发流式布局
void FlowLayoutTestUI::resizeEvent(QResizeEvent* event)
{
this->SetFlowLayout(ui.scrollArea, ui.gridLayout, Qt::AlignCenter, flItems, 240);
}
实现效果
使用官方源码实现
源码地址:https://doc.qt.io/qt-6/qtwidgets-layouts-flowlayout-example.html
FlowLayoutTest1UI::FlowLayoutTest1UI(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
int item_w = 240;
int item_h = 200;
FlowLayout* layout = new FlowLayout;
FlowLayoutTestItem* item1 = new FlowLayoutTestItem();
item1->setStyleSheet("background-color:rgb(34, 34, 37);border-radius: 10px;");
item1->setMaximumSize(QSize(item_w, item_h));
item1->setMinimumSize(QSize(item_w, item_h));
layout->addWidget(item1);
//...........
setLayout(layout);