不知道自己是码农的二流码农!
分类: C/C++
2012-08-21 14:47:08
文档名称 |
Qt布局管理 |
创建时间 |
2012/8/21 |
修改时间 |
2012/8/22 |
创建人 |
Baifx |
简介(收获) |
Qt布局介绍、常用函数列举 |
1、Qt布局管理介绍
参见:
http://dev.10086.cn/cmdn/wiki/index.php?doc-view-6022.html
狭义的说,Qt的布局管理框架指的是以QLayoutItem/QLayout为基类的布局管理体系(应该说,对于QGraphicsSystem,还有以QGraphicsLayoutItem/QGraphicsLayout为基类的一系列相关子类)。
但是如果广义的说,布局就是管理控件的位置和尺寸的话,在QT中一共有三种方式:
绝对定位:在代码中调用QWidget::setGeometry()函数,对控件进行绝对定位;
手工定位:在resizeEvent等函数中,根据参数变化,撰写代码对控件进行定位;
使用布局管理器定位:使用QLayout类管理控件。
布局 VS 控件
在GTK中,Layout和Widget并没有截然分开,不存在单独的Layout类,每个控件都要自己负责管理自己的子控件的布局,只不过有些控件管理的多些,或者基本上专门用来管理布局,而有些则管理的少一些。
而在QT中,Layout和Widget是相对独立的类,但是Layout本身单独存在并没有意义,需要和Widget配合使用。而Widget本身不负责子控件的布局管理。你可以认为,Layout类其实只是一组预先撰写好的代码,在父控件尺寸变化时,根据预设参数和子控件的各种Geometry hint,管理控件的位置和尺寸。
不过,也有一些例外,比如QMainWindow类,就自己管理预设的子控件的布局。
一点内部逻辑——**Layout如何管理Widget层次关系**
首先是要通过QWidget::setLayout函数,将一个QLayout类设置为控件的布局管理器。这一步实际也将这个控件设置为QLayout类的父控件。
而后,通常通过QLayout::addWidget()等函数,将子widget添加到Layout类的布局管理体系中。但是,Layout本身并不是Widget的父控件,因为QWidget类的父控件只能是QWidget类,所以Layout将其管理的子控件的父控件重定向为自己的父控件。
另外,因为QWidget类本身并不是一个QLayoutItem,而Qlayout的管理又是以QLayoutItem为单位。所以,在addWidget的操作中,QLayout还会创建一个QLayoutItem的子类QWidgetItem类来对应的包装代理添加进来的子控件。QWidgetItem对象最终会将QLayout布局管理体系中的布局参数信息装换、设置到它所代理的QWidget对象上。
分组式(堆栈式)布局
QStackedLayout个人觉得叫分组布局有些歧义,还是直译堆栈布局比较合适。这个Layout类管理子控件的方式和其它QBoxLayout,QGridLayout等不太一样,比较特殊。QStackedLayout不侧重于子控件的位置管理,它所管理的子控件是叠加在一起的,主要控制哪个子控件位于最上层。可以通过设置参数,决定只有当前顶层控件可见(默认行为),还是所有子控件都可见(这样可以实现一些比如叠加显示的效果,当然,要最上层的控件有透明的区域)。另外,不管堆叠参数如何设置,QStackedLayout的父控件的内容都是可见的,只要当前显示的子控件有透明区域。
Qt中包含一系列布局管理类,用来描述Widgets如何在程序的UI中布局。这些layouts会自动地对Widgets放置或重设大小。
水平布局管理器(QHBoxLayout)可以把它所管理的控件以水平的顺序依次排开;
垂直布局管理器(QVBoxLayout)可以把它所管理的控件以垂直的顺序依次排开;
网格布局管理器(QGridLayout)可以以网格的形式,把它所管理的控件以一定矩阵排列;
窗体布局管理器(QFormLayout)可以以两列的形式排列控件。
Qt中布局管理类的继承关系如下图所示:
2、水平(垂直)布局管理。
水平布局管理器:QHBoxLayout,按照从左到右的顺序进行添加。
垂直布局管理器:QVBoxLayout,按照从上到下的顺序进行添加。
水平布局管理器和垂直布局管理器用法基本相同。这里以水平布局管理器为例来说明几个主要用法和函数。
QHBoxLayout::QHBoxLayout ()
Constructs a new horizontal box. You must add it to another layout.
QHBoxLayout::QHBoxLayout ( QWidget * parent )
Constructs a new top-level horizontal box with parent parent.
void QLayout::addWidget ( QWidget * w )
Adds widget w to this layout in a manner specific to the layout. This function uses addItem().
void QBoxLayout::addWidget ( * widget, int stretch = 0, alignment = 0 )
Adds widget to the end of this box layout, with a stretch factor of stretch and alignment alignment.
The stretch factor applies only in the of the , and is relative to the other boxes and widgets in this . Widgets and boxes with higher stretch factors grow more.
If the stretch factor is 0 and nothing else in the has a stretch factor greater than zero, the space is distributed according to the:sizePolicy() of each widget that's involved.
The alignment is specified by alignment. The default alignment is 0, which means that the widget fills the entire cell.
void QBoxLayout::addLayout ( * layout,int stretch = 0 )
Adds layout to the end of the box, with serial stretch factor stretch.
void QBoxLayout::addSpacing ( int size )
Adds a non-stretchable space (a ) with size size to the end of this box layout. provides default margin and spacing. This function adds additional space.
void QBoxLayout::addStretch ( int stretch = 0 )
Adds a stretchable space (a QSpacerItem) with zero minimum size and stretch factor stretch to the end of this box layout.
setSizeConstraint( SizeConstraint )
保证布局(窗体)大小不能改变!
void QBoxLayout::setSpacing ( int spacing )
Reimplements QLayout::setSpacing().
Sets the spacing property to spacing.
说明:spacing是针对于layout内部控件的间距,与控件的添加顺序无关(contentsMargins也一样,只和控件间的层次有关); 例如VBoxLayout, 则是当前子控件的纵向间距受spacing值的影响。所以你不可能在一个layout中实现三个以上控件的间距不相同。
void QBoxLayout::setStretch ( int index, int stretch )
Sets the stretch factor at position index. to stretch.
This function was introduced in Qt 4.5.
void QLayout::setMenuBar ( QWidget * widget )
Tells the geometry manager to place the menu bar widget at the top of parentWidget(), outside QWidget::contentsMargins(). All child widgets are placed below the bottom edge of the menu bar.
QWidget * QLayout::menuBar () const
Returns the menu bar set for this layout, or 0 if no menu bar is set.
3、网格布局管理。
网格布局管理器:QGridLayout,顾名思义就是将窗体分隔成行和列的网格来进行排列。通常可以使用函数addWidget()或者addLayout()来将被管理的widget或者layout添加到窗格中。也可以通过重载的函数addWidget()或者addLayout()的行和列跨度实现占据多个窗格。
参见:
QGridLayout::QGridLayout ( QWidget * parent )
Constructs a new QGridLayout with parent widget, parent.
The layout has one row and one column initially, and will expand when new items are inserted.
QGridLayout::QGridLayout ()
Constructs a new grid layout.
You must insert this grid into another layout.
You can insert widgets and layouts into this layout at any time, but laying out will not be performed before this is inserted into another layout.
void QGridLayout::addWidget ( QWidget * widget, int row, int column, Qt::Alignment alignment = 0 )
Adds the given widget to the cell grid at row, column. The top-left position is (0, 0) by default.
The alignment is specified by alignment. The default alignment is 0, which means that the widget fills the entire cell.
void QGridLayout::addWidget ( QWidget * widget, int fromRow, int fromColumn, int rowSpan, intcolumnSpan, Qt::Alignment alignment = 0 )
This is an overloaded function.
This version adds the given widget to the cell grid, spanning multiple rows/columns.
The cell will start at fromRow, fromColumn spanning rowSpanrows and columnSpan columns. The widget will have the given alignment.
If rowSpan and/or columnSpan is -1, then the widget will extend to the bottom and/or right edge, respectively.
//如果希望Widget或者Layout跨越几个行或者列,那么就要用这个函数。
void QGridLayout::addLayout ( QLayout * layout, int row, int column, Qt::Alignment alignment = 0 )
Places the layout at position (row, column) in the grid. The top-left position is (0, 0).
The alignment is specified by alignment. The default alignment is 0, which means that the widget fills the entire cell.
A non-zero alignment indicates that the layout should not grow to fill the available space but should be sized according to sizeHint().
layout becomes a child of the grid layout.
void QGridLayout::addLayout ( QLayout * layout, int row, int column, int rowSpan, intcolumnSpan, Qt::Alignment alignment = 0 )
This is an overloaded function.
This version adds the layout layout to the cell grid, spanning multiple rows/columns.
The cell will start at row, column spanning rowSpan rows andcolumnSpan columns.
If rowSpan and/or columnSpan is -1, then the layout will extend to the bottom and/or right edge, respectively.
void QGridLayout::setColumnMinimumWidth ( int column, int minSize )
Sets the minimum width of column column to minSize pixels.
//设置列的最小宽度,当窗口大小改变时列column宽度不能小于minSize。
void QGridLayout::setRowMinimumHeight ( int row, int minSize )
Sets the minimum height of row row to minSize pixels.
//设置行的最小高度,当窗口大小改变时行row高度不能小于minSize。
void setColumnStretch ( int column, int stretch )
Sets the stretch factor of column column to stretch. The first column is number 0.
The stretch factor is relative to the other columns in this grid. Columns with a higher stretch factor take more of the available space.
The default stretch factor is 0. If the stretch factor is 0 and no other column in this table can grow at all, the column may still grow.
An alternative approach is to add spacing using addItem() with a QSpacerItem.
//此函数一般是若干个一起使用,用以设置各列所占的空间比。第一个参数代表的列索引;第二个参数代表的空间比例值。
void QGridLayout::setRowStretch ( int row, int stretch )
Sets the stretch factor of row row to stretch. The first row is number 0.
The stretch factor is relative to the other rows in this grid. Rows with a higher stretch factor take more of the available space.
The default stretch factor is 0. If the stretch factor is 0 and no other row in this table can grow at all, the row may still grow.
void QGridLayout::setSpacing ( int spacing )
This function sets both the vertical and horizontal spacing to spacing.
//设置GridLayout内各个控件之间的间距,水平方向和垂直方向。
bool QObject::blockSignals ( bool block )
If block is true, signals emitted by this object are blocked (i.e., emitting a signal will not invoke anything connected to it). If block is false, no such blocking will occur.
The return value is the previous value of ().
Note that the () signal will be emitted even if the signals for this object have been blocked.
bool QLayout::setAlignment ( * w, alignment )
Sets the alignment for widget w to alignment and returns true if w is found in this layout (not including child layouts); otherwise returns false.
void QLayout::setAlignment ( alignment )
Sets the alignment of this item to alignment.
bool QLayout::setAlignment ( QLayout * l, alignment )
This is an overloaded function.
Sets the alignment for the layout l to alignment and returns true if l is found in this layout (not including child layouts); otherwise returns false.
==================================================================
QGridLayout用法举例:
layout->addWidget( widget, row, column, rowSpan, columnSpan );
layout->addWidget( widget, row, column, rowSpan, columnSpan );
( row, column ):控件占据左上角的单元格位置。
rowSpan:控件占据的行数。
columnSpan:控件占据的列数(不写默认为1)
==================================================================
控件随窗体伸缩
将布局与窗体建立联系:
layout = new QHBoxLayout( this );
或者this->setLayout( layout ); (this可以省略)
==================================================================
layout->addStretch(); //可伸缩空间
layout->setAlignment( Qt::AlignHCenter ); //布局内控件水平居中
layout->setSpacing( 10 ); //控件间隔为10
layout->setMargin( 10 ); //页边距为10
==================================================================