一个QSplitter是一个可以包含其他控件的控件,这些控件被一个分隔条隔开,托拽这个分隔条,可以改变splitter的子控件的大小。QSplitter控件经常做为布局管理器使用,给用户提供更多的界面控制。
QSplitter控件中的子控件总是按顺序自动并肩排列(或者上下排列)。相邻的控件之间有一个分隔条。下面是创建图6.7的窗体的代码:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTextEdit *editor1 = new QTextEdit;
QTextEdit *editor2 = new QTextEdit;
QTextEdit *editor3 = new QTextEdit;
QSplitter splitter(Qt::Horizontal);
splitter.addWidget(editor1);
splitter.addWidget(editor2);
splitter.addWidget(editor3);
...
splitter.show();
return app.exec();
}
Figure 6.7. The Splitter application
![](https://i-blog.csdnimg.cn/blog_migrate/dcf94299f69fb4a17254cb6963164e40.jpeg)
这个例子中的窗体有一个QSplitter控件,其中有三个水平排列的QTextEdit控件,与布局管理器不同,QSplitter不但可以排列子控件,还有一个可视的外观,QSplitter控件从QWidget继承,拥有QWidget所有的功能。
Figure 6.8. The Splitter application's widgets
![](https://i-blog.csdnimg.cn/blog_migrate/cffbdfd937d3ba1c24477fa51c65dc40.jpeg)
对QSplitter进行水平或者垂直嵌套可以实现更加复杂的布局。例如,图6-9所示的MailClient程序中,就是一个垂直方向的QSplitter控件中嵌套了一个水平方向的QSplitter控件。
Figure 6.9. The Mail Client application on Mac OS X
![](https://i-blog.csdnimg.cn/blog_migrate/bf04f4f4983d687c1085d1bda0b69b1d.jpeg)
下面的代码是MailClient程序的主窗口类构造函数代码:
MailClient::MailClient()
{
...
rightSplitter = new QSplitter(Qt::Vertical);
rightSplitter->addWidget(messagesTreeWidget);
rightSplitter->addWidget(textEdit);
rightSplitter->setStretchFactor(1, 1);
mainSplitter = new QSplitter(Qt::Horizontal);
mainSplitter->addWidget(foldersTreeWidget);
mainSplitter->addWidget(rightSplitter);
mainSplitter->setStretchFactor(1, 1);
setCentralWidget(mainSplitter);
setWindowTitle(tr("Mail Client"));
readSettings();
}
创建完我们所需要显示三个控件(messageTreeWidget,textEdit,foldersTreeWidget)后,我们创建一个垂直的QSplitter,
rightSplitter控件,把messageTreeWidget和textEdit控件加到rightSplitter中。然后创建一个水平的QSplitter,
mainSplitter控件,把rightSplitter和foldersTreeWidget加入到mainSplitter中。把
mainSplitter做为QMainWindow的中央控件。
当用户改变窗口的大小时, QSplitter通常给所有的子控件分配一样大的空间。在MailClient程序中,我们希望左边的文件树控件(foldersTreeWidget)和消息树控件(messageTreeWidget)保持它们的大小,把其他更多的空间都分配给QTextEdit。这由两次调用setStretchFactor()实现。第一个参数是0开始的子控件的索引值,第二个参数为我们设置的拉伸系数,缺省值为0。
Figure 6.10. The Mail Client's splitter indexing
![](https://i-blog.csdnimg.cn/blog_migrate/d6cc7b855e976ee2ed0551af8f66f1ee.jpeg)
第一次是调用rightSplitter的setStretchFactor(),把索引值为1的控件(textEdit)的拉伸系数设置为1,第二次是调用mainSplitter的setStretchFactor(),设置控件rightSplitter的拉伸系数为1。这样,textEdit控件就能够得到尽可能多余的空间。
当应用程序启动时,QSplitter根据子控件的初始尺寸或者sizeHint合理分配每一个子控件的大小。程序中,我们可以调用
QSplitter::setSizes()改变分隔条的位置。QSplitter还可以保存当前的状态,在程序下一次运行时恢复以前的状态。下面是writeSettings()函数,保存当前分隔条的状态:
void MailClient::writeSettings()
{
QSettings settings("Software Inc.", "Mail Client");
settings.beginGroup("mainWindow");
settings.setValue("size", size());
settings.setValue("mainSplitter", mainSplitter->saveState());
settings.setValue("rightSplitter", rightSplitter->saveState());
settings.endGroup();
}
下面是相应的readSettings()函数:
void MailClient::readSettings()
{
QSettings settings("Software Inc.", "Mail Client");
settings.beginGroup("mainWindow");
resize(settings.value("size", QSize(480, 360)).toSize());
mainSplitter->restoreState(
settings.value("mainSplitter").toByteArray());
rightSplitter->restoreState(
settings.value("rightSplitter").toByteArray());
settings.endGroup();
}
Qt Designer也支持QSplitter。把子控件放到合适的位置,把他们选中,选择菜单
Form|Lay out Horizontally in Splitter或者
Form|Lay out Verticallly in Splitter,所选择的子控件就被加入到QSplitter控件中。