很久很久以前,刚接触QT,发现UI拖控件真爽,做个计算器什么的,一下子就搭出来了!实现起来也很得心应手,后面做的界面越来越复杂后,特别是别人跟你提意见,需要修改的时候,绝望!打破布局各种不友好。
开始使用代码布局,代码new控件,修改的时候也比较好修改,而且可以实现动态布局!感觉缺点就是样式表没有UI这么友好,实时体现。

一、布局类

1
2
3
4
5
6
7
8
9
10
11
12
QLayoutItem
QLayout(和QObject)
QBoxLayout
QHBoxLayout 水平布局
QVBoxLayout 垂直布局
QGridLayout 栅栏布局
QFormLayout 表单布局
QGraphicsLayout
QStackedLayout 堆布局
QSpacerItem 空白占位(UI上的弹簧)
QWidgetItem
QWidgetItemV2

为什么个人不喜欢用QGridLayout呢?因为QGridLayout很容易被控制改变实际比例,导致出现和预设的比例不同。排问题好麻烦,推荐在行或者列使用相同的控件时使用。(有可能是我太菜了,使用不来)

QLayout

函数名 意义
QWidget *parentWidget() const; 返回布局依赖控件
void setContentsMargins(int left, int top, int right, int bottom); 布局的左上右下边距
void setContentsMargins(const QMargins &margins);
void getContentsMargins(int left, int top, int right, int bottom) const;
QMargins contentsMargins() const;
QRect contentsRect() const;
void addWidget(QWidget *w); 添加控件
virtual void addItem(QLayoutItem *) = 0;
void removeWidget(QWidget *w); 移除控件,不生效!下面会讲怎么从布局中去掉控件
void removeItem(QLayoutItem *);
void setEnabled(bool);
bool isEnabled() const;
void setMargin(int);
void setSpacing(int);
virtual QLayoutItem *itemAt(int index) const = 0;
virtual QLayoutItem *takeAt(int index) = 0;
virtual int indexOf(QWidget *) const;
virtual int count() const = 0;

QBoxLayout

函数名 意义
void addSpacing(int size); 添加指定大小的占位
void addStretch(int stretch = 0); 添加指定比例的占位
void addSpacerItem(QSpacerItem *spacerItem); 添加一个弹簧
void addWidget(QWidget *, int stretch = 0, Qt::Alignment alignment = 0); 添加一个布局
void addLayout(QLayout *layout, int stretch = 0); 添加一个布局
void addStrut(int);
//Limits the perpendicular dimension of the box (e.g. height if the box is LeftToRight) to a minimum of size. Other constraints may increase the limit.
void addItem(QLayoutItem *) Q_DECL_OVERRIDE; 继承自QLayoutItem 纯虚函数还有对应的insert插入操作
void setSpacing(int spacing); 设定控件之间的距离
bool setStretchFactor(QWidget *w, int stretch); 更改该控件的比例
bool setStretchFactor(QLayout *l, int stretch); 更改该布局的比例
void setStretch(int index, int stretch); 更改第index项的比例

QGridLayout

函数名 意义
void setHorizontalSpacing(int spacing); 控件间距
int horizontalSpacing() const;
void setVerticalSpacing(int spacing);
int verticalSpacing() const;
void setSpacing(int spacing);
int spacing() const;
void setRowStretch(int row, int stretch); 行列比例
void setColumnStretch(int column, int stretch);
int rowStretch(int row) const;
int columnStretch(int column) const;
int columnCount() const; 行列数量
int rowCount() const;
inline void addWidget(QWidget *w) { QLayout::addWidget(w); } 插入控件
void addWidget(QWidget *, int row, int column, Qt::Alignment = 0);
void addWidget(QWidget *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = 0);
void addLayout(QLayout *, int row, int column, Qt::Alignment = 0);
void addLayout(QLayout *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = 0);

QFormLayout

没用过,类似一个QHBoxLayout,固定一个QLabel和一个等待插入的控件。

QGraphicsLayout

没用过,给Graphics View使用。

QStackedLayout

跟QStackedWidget一样,方式不一样,QStackedLayout是多个Layout QStackedWidget是多个Widget

QSpacerItem

弹簧

1
2
3
4
5
6
7
QSpacerItem(int w, int h,
QSizePolicy::Policy hData = QSizePolicy::Minimum,
QSizePolicy::Policy vData = QSizePolicy::Minimum)
: width(w), height(h), sizeP(hData, vData) { }
void changeSize(int w, int h,
QSizePolicy::Policy hData = QSizePolicy::Minimum,
QSizePolicy::Policy vData = QSizePolicy::Minimum);

QWidgetItem

没用过

Normally, you don’t need to use this class directly. Qt’s built-in layout managers provide the following functions for manipulating widgets in layouts

二、布局遍历

1
2
3
4
for(int i=0;i<mlayout->count();i++){
QLabel *lab=qobject_cast<QLabel*>(mlayout.itemAt(i)->widget());
qDebug()<<lab->text();
}

三、清除布局

1
2
3
4
while(mlayout->count()){
mlayout->itemAt(0)->widget()->setParent(nullptr); //将父类设空既可 下面一句保留
//mlayout->removeWidget(mlayout->itemAt(0)->widget());
}

四、动态布局

动态布局借用清除布局,将layout里面的widget全部清空,然后重新添加需要的widget,视觉上面可以看到是界面可以动态变换

1
2
3
clearLayout(mlayout);
mlayout->addWidget(subWidget1,1);
mlayout->addwidget(subWidget2,2);

五、注意

设置布局前,控件应该设定好大小策略,限定大小的变化

1
2
3
4
5
6
7
8
9
10
11
   void QWidget::setSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Policy ver);
void setSizePolicy(QSizePolicy);
enum Policy {
Fixed = 0,
Minimum = GrowFlag,
Maximum = ShrinkFlag,
Preferred = GrowFlag | ShrinkFlag,
MinimumExpanding = GrowFlag | ExpandFlag,
Expanding = GrowFlag | ShrinkFlag | ExpandFlag,
Ignored = ShrinkFlag | GrowFlag | IgnoreFlag
};