在阅读《C++ GUI Programming with Qt 4, 2nd Edition》第六章“布局管理器”的第三节“Splitters”时,我按照书中的示例进行了实践,但发现实际效果与书中描述有很大不同,尤其是在分界线方面。
书中提到的分界线在实际运行中几乎不可见,因为它们的颜色和背景色完全一致。书中并未详细说明如何处理分界线(可能在后续章节中有介绍)。
以下是我在 main 方法中编写的代码:
QSplitter *mainSplitter = new QSplitter(Qt::Horizontal); QLabel *label = new QLabel(QObject::tr("A")); QLabel *label2 = new QLabel(QObject::tr("B")); mainSplitter->addWidget(label2); mainSplitter->addWidget(label); mainSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); mainSplitter->show();
运行后,分界线几乎不可见:
而书中的效果是:
分界线的差异非常明显。经过查阅资料,我发现分界线实际上是由 QSplitterHandle 类对象表示的。通过以下代码可以修改分界线的样式:
mainSplitter->setStyleSheet("QSplitter::handle { background-color: black }"); // 设置分界线的样式 mainSplitter->setHandleWidth(20); // 设置分界线的宽度
添加上述代码后的效果如下:
分界线的背景颜色变为黑色,并且宽度显著增加,说明代码生效了。如果有多个分界线,我们可以通过以下代码单独修改某一条分界线的样式:
QSplitterHandle *handle = mainSplitter->handle(1); // 注意索引从1开始,如果找不到分界线,将返回NULL if (handle) { handle->setFixedWidth(1); }
效果如下:
可以看到,B 和 A 之间的分界线宽度被设置为1。如果想禁用分界线的拖动功能,可以使用 `handle->setDisabled(true);`。
对于 B 和 A 的大小控制,可以通过 QSplitter 的 `setStretchFactor` 方法实现。该方法的声明如下:
void setStretchFactor(int index, int stretch);
第一个参数 `index` 是子控件的索引值,从0开始。这里 B 是0,A 是1;第二个参数 `stretch` 是拉伸系数,类型为 int。以下是一些具体的测试案例:
1. `mainSplitter->setStretchFactor(0, -2);`
效果如下:
B 占据了所有多余的空间,说明拉伸系数为负整数的控件将占据最大的空间。
2. `mainSplitter->setStretchFactor(0, -2);`
`mainSplitter->setStretchFactor(1, -4);`
效果如下:
B 和 A 平分了空间,说明拉伸系数为负整数的控件会尽可能占据空间,而不考虑负整数的具体值。
3. `mainSplitter->setStretchFactor(0, 0);`
`mainSplitter->setStretchFactor(1, 0);`
效果同第2个案例。
4. `mainSplitter->setStretchFactor(0, 0);` // 可以注释掉,效果相同
`mainSplitter->setStretchFactor(1, 1);`
效果如下:
5. `mainSplitter->setStretchFactor(0, 4);`
`mainSplitter->setStretchFactor(1, 8);`
效果如下:
6. `mainSplitter->setStretchFactor(0, -4);`
`mainSplitter->setStretchFactor(1, 8);`
效果如下:
从第1、2和6个测试案例可以看出,拉伸系数为负整数的控件将占据最大的多余空间。从第3、4和5个测试案例可以看出,即使不设置某个控件的拉伸系数,其默认值也为0。拉伸系数为0的控件会将多余的空间让给拉伸系数为正整数的控件。