QSpacerItem和Qt布局

QSpacerItem

QSpacerItem就是Qt设计模式中的分隔条,有人可能说一个分隔条有什么可研究的,我之前也是这么想,没想到今天发现里面玄机还真是不少。

首先看最神奇的一个现象:不添加到布局的分隔条无法在设计模式中保存。

在窗口上拖两个分隔条,一横一竖。

然后保存

重新打开后,发现两个分隔条竟然不见了!既然保存后分隔条不见了,那么每次编译也就不会在ui_.h里产生QSpacerItem了,因为编译之前会保存。

最好不要给分隔条改名,也就是spacerName,虽然修改后在代码里仍可使用,但是不知为什么QSpacerItem类没有这个成员函数,所以不能在代码里改名只能在设计模式里改,不过一般也不会在C++里操作它。

QSpacerItem的基类QLayoutItem是个抽象类,有几个纯虚函数,提供的是QLayout能操作的抽象对象(abstract item)。我是这样理解抽象对象的:注意QLayoutItem没有基类,所以没有继承QWidget,而QWidget的所有子类都覆盖了函数paintEvent,实现了控件的形状,而QSpacerItem没有这样的绘图函数,因为它用于在布局中提供一个空白的空间

现在有一个分隔条Spacer_2,开始大小为QSize(40,20),添加到一个布局里然后拉伸布局,会发现其sizeHint始终是QSize(40,20),没有随布局的改变而改变,代码输出也是一样的结果。QWidget的子类都有sizesizeHint两个函数,后者叫建议尺寸,每个控件都有各自实现,可以看源码。但分隔条只有一个sizeHint,所以无法获得真实大小。

查看Qt源码:

QSize QSpacerItem::sizeHint() const
{
    return QSize(width, height);
}

width,height是私有成员变量,在初始化时赋值,这就清楚了,sizeHint返回的就是初始的大小我们无法获得改变布局后的分隔条大小。代码里改变大小用的是changeSize(),不过由于分隔条一般在设计模式里操作,这个函数用处不大。

布局

基于 QWidget 的控件都会继承 sizePolicy 属性( QSizePolicy 类型),这个属性包括两个大的方面内容:伸展因子 (Stretch Factor)和 伸展策略(Policy)

拉伸比例

用了布局这么久,发现原来有自定义拉伸比例的功能,如图所示:

之前经常发现布局很难达到自己想要的效果,其实最好的用法是布局+分隔条+伸缩比例,基本可以满足所有要求。

图中的横向布局采用的比例是1:2:3,也就是label、spacer、lineedit的宽度比是1:2:3,如果某一项是0,那么相应控件会保持建议尺寸。控件放入布局后,无法用代码获得其真实大小,但能在设计模式的geometry里看到,其中的几项都变成了灰色,无法编辑。

但是这里还是有个缺陷,就是上面提到的分隔条放入布局后无法获取实际大小,无论是代码里还是设计模式中都看不到,因为它只有个sizeHint返回建议大小。

其实控件自身也可以设置伸展因子,如果布局器和内部直属的控件都设置了伸展因子,那么布局器的设置会覆盖直属控件的伸展因子。因此不建议设置控件自己的伸展因子,而是通过布局器来设置。

最小和最大尺寸

控件时可以设置最小和最大尺寸的,如果给控件的最大尺寸比较小,窗口拉伸时会怎样,例如下图两个控件的最大尺寸是200X200。
拉伸前:

拉伸后:

拉伸时,会发现布局中多出来三个空白区,相当于加了分隔条。

如果两个控件的最小尺寸是200X200,那么窗口的拉伸就有了最小限制,窗口的最小宽度不能少于400,手动编辑不会成功。

猜你喜欢

转载自blog.csdn.net/yao5hed/article/details/81095997