说明:
由于Qt的官方文档内,对于QBoxLayout,QgridLayout,或者Qlayout,都找不到类似swapwidget的接口。最近项目中用到,特此记录一下
首先我这边直接继承QHBoxLayout。当然也可以直接QBoxLayout,构造函数传入垂直或水平方向即可。
以下是主要代码:
#ifndef TBOXLAYOUT_H
#define TBOXLAYOUT_H
#include <QObject>
#include <QBoxLayout>
#include <QWidget>
#include <QDebug>
class TBoxLayout : public QHBoxLayout
{
Q_OBJECT
public:
explicit TBoxLayout(QWidget *parent);
~TBoxLayout();
private:
public:
bool swapWidget(QWidget* w1,QWidget* w2);
bool swapWidget(int index1, int index2);
protected:
// void QDragEnterEvent
};
#endif // TBOXLAYOUT_H
没啥说的,就增加了swapwidget的函数,参数可以是QWidget指针,也可以是在Layout中的序号。
#include "tboxlayout.h"
TBoxLayout::TBoxLayout(QWidget *parent):
QHBoxLayout(parent)
{
}
TBoxLayout::~TBoxLayout()
{
}
bool TBoxLayout::swapWidget(QWidget *w1, QWidget *w2)
{
if(!w1 || !w2){
return false;
}
int idx1 = indexOf(w1);
int idx2 = indexOf(w2);
qDebug()<<"idx1"<<idx1<<"idx2"<<idx2;
if(idx1 <0 || idx2 <0){
return false;
}
int stren1 = stretch(idx1);
int stren2 = stretch(idx2);
removeWidget(w1);
QWidget* wid = new QWidget;
insertWidget(idx1,wid);
removeWidget(w2);
insertWidget(idx2,w1,stren1);
removeWidget(wid);
insertWidget(idx1,w2,stren2);
delete wid;
wid=Q_NULLPTR;
return true;
}
bool TBoxLayout::swapWidget(int index1, int index2)
{
if(index1<0 || index1 >=count() || index2<0 || index2 >=count()){
return false;
}
int stren1 = stretch(index1);
int stren2 = stretch(index2);
QWidget* w1 = takeAt(index1)->widget();
QWidget* wid = new QWidget;
insertWidget(index1,wid);
QWidget* w2 = takeAt(index2)->widget();
insertWidget(index2,w1,stren1);
removeWidget(wid);
insertWidget(index1,w2,stren2);
delete wid;
wid=Q_NULLPTR;
return true;
}
原理也很简单,new一个空白的widget来填补,防止remove后index发生改变。
使用也很简单:
mslayout = new TBoxLayout(this);
mslayout->addWidget(ui->frame);
mslayout->addWidget(ui->widget);
mslayout->addWidget(ui->widget_2);
ui->widget_par->setLayout(mslayout);
```cpp
void MainWindow::on_pushButton_clicked()
{
// emit sig_test();
// mslayout->swapWidget(ui->widget,ui->widget_2);
// mslayout->swapWidget(ui->frame,ui->widget_2);
mslayout->swapWidget(0,1);
}
简单测试一下,点击按钮,交换位置,效果如下: