UI布局引擎Layout 之 QGraphicsLinearLayout

时间:2023-02-03 09:58:42

QT 的Scene-View系统中的LinearLayout 相当于原来的 HBoxLayout 和 VBoxLayout,用来处理横行排版和竖向排版。

类继承图如下(由QT4.4版本引入):                UI布局引擎Layout 之 QGraphicsLinearLayout

QGraphicsLinearLayout处理Qt::Horizontal和Qt::Vertical两个方向的排版布局,默认为Qt::Horizontal,可以通过调用接口setOrientation(),并传递参数Qt::Vertical来构造垂直方向的QGraphicsLinderLayout。

通常用parent=NULL的方式在堆上构建 QGraphicsLInderLayout(也就是 QGraphicsLinearLayout * layout = new QGraphicsLinearLayout(NULL) ),

然后通过调用接口addItem()的方式增加wdiget 和 sub layout,完成创建后,在设置layout的方向以及调用QGraphicsWidget::setLayout()接口对构建的layout进行绑定。

可以通过接口addItem(), addStretch(), insertStretch(),  setStrethFactor() 给 layout 增加 widgets, layouts, stretches, 通过 setItemSpacing 给layout 设置 spacing,并且layout拥有item的所有权。在一些情况下,当 item 是从QGraphicsItem(或者QGraphicsWidget)多层继承过来的,这个时候再item的所有权会出现混乱的现象,因为item这个时候属于两个所有权层次体系。参考QGraphicsLayoutItem::setOwnedBylayout()相关文档,确认所有权问题的处理方式。通过接口count()和itemAt()可以遍历item, 通过removeAt 和 removeItem() 可以移除 layout 里面的 item, 这个时候只是剥离item 和 layout 的所有权关系,但并不销毁相关item。

link: QGraphicsLayoutItem::setOwnedBylayout() : 设置 一个layout 是否在析构的时候需要delete 当前item。

名词解释:

alignment            : 对齐方式

Stretch Factor     :伸展因子

orientation         :伸展方向

reimplemented    :重载实现

spaceing ,space   : 间隔, 占位



大小策略

QGraphicsLinearLayout尽量尊重每一个item自己的size hints 和 size policies,当 layout 拥有比填充完所有items 更多的空间的时候会 根据layout的针对当前item的alignment排列每一个item的,你也可以对每一个item调用setAlignment()设置对齐方式。默认情况下item是左上角对齐的。

item之间的空格策略

layout会在item之间分配一些空格。实际的空格大小依赖于layout当前所属的widget的style,通常的空格大小是4,你也可以通过调用接口setSpacing()来设置,如果想针对每一个Item设置独立的space,可以调用接口setItemSpacing()。

布局中的伸展策略


可以为每一个item设置一个伸展因子,控制当前item比其他的item获取更多的空间。默认情况下,两个同类型的widget,排列在一个linearLayout中将会获得同样大小的空间,但是,如果第一个widget设置伸展因子为1,第二个设置伸展因子为2,那么第一个widget会获得1/3的可用空间,而第二个widget会获得2/3的可用空间。

QGraphicsLinearLayout通过累加所有item的伸展因子,然后根据伸展因子的比例分配可用空间。对于所有item来说,默认的伸展因子是0,也就是意味着item没有设置伸展因子,这种情况下,和所有item设置伸展因子为1,效果上是一样的。伸展因子只对LineraLayout布局的延展方向有效。如果要控制item的两个方向,你可以考虑用QGraphicsGridLayout代替线性布局。

QGraphicsLinearLayout 对比其他布局


QGraphicsLinearLayout和QVBoxLayout,QHBoxLayout功能类似,只不过这里管理的是QGraphicsWidget和QGraphicsLayout,而不是QWidget和QLayout。



成员函数表:

void QGraphicsLinearLayout::addItem ( QGraphicsLayoutItem * item )
相当于调用 insertItem(-1, item).

void QGraphicsLinearLayout::addStretch ( int stretch = 1 )
相当于调用 insertStretch(-1, stretch).

Qt::Alignment QGraphicsLinearLayout::alignment ( QGraphicsLayoutItem * item ) const
返回 item的对齐方式. 默认是 Qt::AlignTop | Qt::AlignLeft.
对齐方式是在layout在填充完item后有剩余空间的时候用什么想对坐标系来设置item的坐标。
[一种对齐方式在逻辑上定义了一种想对坐标系]

int QGraphicsLinearLayout::count () const [virtual]
Reimplemented from QGraphicsLayout::count().

void QGraphicsLinearLayout::insertItem ( int index, QGraphicsLayoutItem * item )
在索引index处插入一个item,或者换种说法是在当前索引为index的item的前面插入一个新的item

void QGraphicsLinearLayout::insertStretch ( int index, int stretch = 1 )
在索引index处插入一个伸展因子(伸展占位),或者说是在当前索引为index的item签名插入伸展因子。
注意:这里的用于插入,是带有两层意思的,如果index指定的地方没有item则会生成空白item,并设置相应为的stretch,如果有item责直接设置相应为的stretch。[猜测,待考证]

void QGraphicsLinearLayout::invalidate () [virtual]
重载 QGraphicsLayout::invalidate().

QGraphicsLayoutItem * QGraphicsLinearLayout::itemAt ( int index ) const [virtual]
重载 QGraphicsLayout::itemAt().
从0递增,返回的item和视觉顺序是匹配的

qreal QGraphicsLinearLayout::itemSpacing ( int index ) const
返回索引为index的item 和索引为(index+1)的item之间的空格大小

Qt::Orientation QGraphicsLinearLayout::orientation () const
返回layout的伸展方向

void QGraphicsLinearLayout::removeAt ( int index ) [virtual]
重载实现 QGraphicsLayout::removeAt()
在布局层级树上移除item, 但并没有销毁item,
调用移除后,item的所有权转交给调用者。
注意:自定义的布局类尽量不要改变原有设计的行为意图,免得破坏原有设计者的结构依赖,导致不可预知问题

void QGraphicsLinearLayout::removeItem ( QGraphicsLayoutItem * item )
语义同 removeAt(int index)

void QGraphicsLinearLayout::setAlignment ( QGraphicsLayoutItem * item, Qt::Alignment alignment )
设置item的对齐方式,layout调用后,会导致布局失效,自动调用invalidated()

void QGraphicsLinearLayout::setGeometry ( const QRectF & rect ) [virtual]
重载实现 QGraphicsLayoutItem::setGeometry().

void QGraphicsLinearLayout::setItemSpacing ( int index, qreal spacing )
设置索引为index的item和索引为(index+1)的item之间的空格大小

void QGraphicsLinearLayout::setOrientation ( Qt::Orientation orientation )
设置layout的伸展方向,会自动调用 invalidated()

void QGraphicsLinearLayout::setSpacing ( qreal spacing )
设置layout的item间隔,space代表的是在layout伸展方向两个item之间的空格大小

void QGraphicsLinearLayout::setStretchFactor ( QGraphicsLayoutItem * item, int stretch )
设置item的伸展因子,如果layout中item的的stretch有变化,则会导致layout 的失效。设置stretch为0的话,就回移除相应item的伸展因子,在效果上等价于设置stetch为1。

QSizeF QGraphicsLinearLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const [virtual]
重载实现 QGraphicsLayoutItem::sizeHint().

qreal QGraphicsLinearLayout::spacing () const
返回layout的item间隔.

int QGraphicsLinearLayout::stretchFactor ( QGraphicsLayoutItem * item ) const
返回指定item的伸展因子。默认的伸展因子是0,也就是说没有为当前item设置过伸展因子

解析QT排版引擎:

UI布局引擎Layout 之 QGraphicsLinearLayout

先总体来看一下,Qt的布局类型,

总共三个种类,QGraphicsLinerLayout, QGraphicsGridLayout

(待续)