替一个Widget设置布局有两种方法。
1layout 构造函数传递QWidget
QVBoxLayout* MainQVboxLayout=new QVBoxLayout(MainWidget);
2layout构造函数传递NULL,调用QWidget的setlayout设置布局
QVBoxLayout* MainQVboxLayout=new QVBoxLayout();
MainWidget->setLayout(MainQVboxLayout);
注意,当一个widget已经存在布局的时候。调用setLayout会失败,如果要设置,必须先通过Widget的 layout方法(
QLayout * | layout() const |
Q:得到layout指针,delete后就能重新设置,不需要其他操作怎么做的?
A:widget使用setLayout的时候会检查原有的值是否为NULL,如果不为NULL就失败,delete layout的时候,析构函数会将这个layout属于的widget的这个值设置为0。
所以delete以后又可以设置了
QLayout::~QLayout()
{
Q_D(QLayout);
if (d->topLevel && parent() && parent()->isWidgetType() &&
((QWidget*)parent())->layout() == this)
((QWidget*)parent())->d_func()->layout = 0; //这里设置了为0
}
Q:为什么MainWindow调用setLayout失败?
A:MainWindow是一个组合体,已经包含了默认的layout,要通过setcenterwidget来操作中间的一块区域。
V H BOXlayout
在一个layout里面添加另一个layout如下
FuncBarQHboxLayout=new QHBoxLayout();
MainQVboxLayout->addLayout(FuncBarQHboxLayout);
Q: delete MainQVboxLayout的时候 FuncBarQHboxLayout会被删除吗,还是需要自己处理?
A:不需要自己处理。删除MainQVboxLayout的时候会自动删除他add的layout
QBoxLayout::~QBoxLayout()
{
Q_D(QBoxLayout);
d->deleteAll(); //删除了这些layout
}
在H 或者V layout里面添加一个控件调用
layout->addWidget(xxx) 这个是依照次序添加的。从左到右,从上到下。
如果有些子类已经实现了一些spacer函数,比如Vbox Hbox,那么用添加spacer用addSpacerItem
一般不直接使用layout->addItem() addItem定义了如何添加,由子类实现,通常用layoutitem封装一个widget或者spacer,把不同的类对象变成layout可以识别的
统一layoutitem,laytouitem可以容纳很多东西
弹簧控件的构造和使用
SpacerItem(w,h,hPolicy,vPolicy)
w是优先的高度h是优先的宽度
hPolicy是水平方向上的策略
vPolicy是垂直方向上的策略。
如果是水平弹簧 那么hPolicy=expanding vPolicy=minimum
如果是垂直弹簧那么hPolicy=minimum vPolicy=expanding
GridLayout 添加控件和Spacer
添加控件用AddWidget
添加Spacer用AddItem
不管用哪个函数都要了解他的四个关键参数
row 控件起始单元格的行位置
column 控件起始单元格的列位置
rowspan 控件所占的行个数
columnspan 控件所占的列个数
例如 0 0 2 1就是该控件排放在0,0起始的位置,占2行1列。
例如 2 3 4 2就是该控件排放在2,3起始的位置,占4行2列。
同时需要设置控件的Policy。
布局还有一个重要的值。是伸缩因子Stretch
Stretch反应的是控件和控件之间的比例。比如
setStretch(0,1)第0个位置的伸缩因子为1
setStretch(1,2)第1个位置的伸缩因子为2
因此第二个控件的大小尽量为第一个的两倍。只能是尽量,因为还有其他的条件限制。比如maxsize,minsize,或者fixed策略minimal策略之类的。
另外一个是调控控件的间隔和边界部分
layout可以使用 setspacing设置控件之间的间隔。gridlayout使用 setverticalspacing或者sethorizontalspacing 来设置
layout通过使用setcontentmargins来设置四周留白的间隔。
部分 Widget 可以通过setcontentmargins来设置四周留白的间隔。setcontentmargins主要是为layout设计使用的。不是所有的Widget都可以使用,有部分是可以的比如Label这一类,具体是否有用要看这个控件的具体实现。比如comboBox就是不可以的。