ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 11.5 分裂器布局 QSplitter 实质上是一个窗口部件,但同时它可以包含一些其他窗口部件。在切分窗口(splitter)中的这些窗口部件会通过切分条(splitter handle)而分隔开来。用户可以 通过拖动这些切分条来改变切分窗口中子窗口部件的尺寸。切分窗口常常可以用作布局管理 器的替代,从而可以把更多的控制权交给用户。 ### 11.5.1使用方法 大家知道,QSplitter 是一个容器类,Qt Designer 把分裂器对象视为可以容纳其它窗 口部件的布局。在 Qt Designer 中要使用分裂器布局也很容易,如图 11-27 所示,先选中 要布局的界面元素,然后选择工具栏上对应的按钮或者通过菜单项或者鼠标右键的上下文菜 单就可以完成。 ![](https://box.kancloud.cn/2016-01-22_56a1a15975755.png) 图 11-27 使用分裂器布局 QSplitter 类可以用来创建分裂器布局,继而实现切分窗口。 创建一个分裂器布局的一般步骤如下: 第 1 步,创建要使用的窗口部件。 第 2 步,创建分裂器布局的实例,就是 QSplitter 的实例。 第 3 步,使用 insertWidget()或者 addWidget()方法把第 1 步创建的窗口部件加入到 布局之中。 第 4 步,调用 QWidget::setLayou()方法把布局安装到窗体上。 注意,在使用分裂器布局之前,需要包含它的头文件声明: ``` #include <QSplitter> ``` ### 11.5.2 构造函数 QSplitter 类有两个构造函数的原型: ``` QSplitter::QSplitter ( Qt::Orientation orientation, QWidget * parent = 0 ) ``` 参数 orientation 指定了分裂器的方向是水平的还是垂直的, parent 指定了父窗口。一 个使用该型构造函数的代码示例如下: ``` QSplitter *splitterRight = new QSplitter(Qt::Vertical,splitterMain); ``` 该代码定义了一个垂直分裂器布局,并指定了它的父窗口为 splitterMain,后者也是一个分裂器布局。 ``` QSplitter::QSplitter ( QWidget * parent = 0 ) ``` 这个型别实质上是第一种构造函数的缺省变体,它默认创建一个水平的分裂器布局。 一个使用该型构造函数的代码示例如下: ``` QSplitter splitter(0); ``` 该代码定义了一个水平分裂器布局,并且采用程序上下文中的窗口作为父窗口。 这两种构造函数型我们都会经常用到,请读者朋友注意掌握。 ### 11.5.3 一些深入的话题 默认情况下,在分裂器布局中的窗口部件会尽可能的按照用户的意愿在它的最小大小 提示以及最小大小或者是最大大小之间调整。如果有需要,也可以调用 QSplitter 类的 setSizes()方法来为布局中每个窗口部件指定大小。而要获取分裂器布局内当前的各个窗口 部件的大小,可以使用 QSplitter 类的 sizes()方法。 如果你想保存分裂器布局的构造,可以使用 QSplitter 的 saveState()和 restoreState()方法。它们通常与 QSettings 类结合使用,保存设置的代码如下: ``` QSettings settings; settings.setValue("splitterSizes", splitter->saveState()); ``` 恢复设置的代码如下: ``` QSettings settings; splitter->restoreState(settings.value("splitterSizes").toByteArray()); ``` 同前面讲过的堆栈布局的情形类似,如果你想获取分裂器布局中的窗口部件的相关信息,可以通过调用 indexof()、widget()以及 count()等方法来实现。 当你调用 hide()方法隐藏了分裂器布局中的某个窗口部件时,它会在界面上消失掉, 并且它原先占有的空间将被其它的窗口部件所 “分享”。而一旦你调用 show()方法显示它 时,一切又会恢复原样。 分裂器布局也是经常使用的一种,它分为分裂器水平布局和分裂器垂直布局,这可以 通过设置分裂器布局的方向来确定,如 Qt::Horizontal 和 Qt::Vertical。使用它们时,界 面效果和使用常见的水平和垂直布局几乎没有区别,它的最明显特征是布局内的元素之间是 等间距的,而水平和垂直布局则不一定是这样。 ### 11.5.4 分裂器布局实例 在 QSplitter 中的子窗口部件将会自动按照创建时的顺序一个挨一个的(或者一个在 另外一个的下面)放在一起,并以切分窗口拖动条( splitter bar)来分隔相邻的窗口部 件。以下是用于创建如图 11-28 所示的分裂器水平布局的窗口的代码。完整的源代码见实 例 splitter。 ``` #include <QtGui> int main(int argc, char *argv[]) { QApplication app(argc, argv); QListWidget *listWidget = new QListWidget; QTreeWidget *treeWidget = new QTreeWidget; QTextEdit *editor = new QTextEdit; QSplitter splitter(Qt::Horizontal); splitter.addWidget(listWidget); splitter.addWidget(treeWidget); splitter.addWidget(editor); listWidget->addItem(QObject::tr("Inbox")); listWidget->addItem(QObject::tr("Outbox")); listWidget->addItem(QObject::tr("Sent")); listWidget->addItem(QObject::tr("Trash")); treeWidget->setColumnCount(1); QList<QTreeWidgetItem *> items; for (int i = 0; i < 10; ++i) items.append(new QTreeWidgetItem((QTreeWidget*)0, QStringList(QString("item:%1").arg(i)))); treeWidget->insertTopLevelItems(0, items); editor->setPlainText(QObject::tr("My child, my sister,\n" "think of the sweetness\n" "of going there to live together!\n" "To love at leisure,\n" "to love and to die\n" "in a country that is the image of you!")); splitter.setWindowTitle(QObject::tr("Splitter")); splitter.show(); return app.exec(); } ``` 把这段代码保存成一个.cpp 文件,如 splitter.cpp,并创建一个文件夹 splitter,把splitter.cpp 文件放入其中。依次运行 qmake –project,qmake splitter.pro,mingw32- make,即可生成可执行文件。程序的运行效果如图 11-28 所示。 ![](https://box.kancloud.cn/2016-01-22_56a1a159a06b0.png) 图 11-28 分裂器布局实例效果 该程序代码比较易懂,我们简要的讲解一下。 第 1 行,加入了程序中用到的头文件声明,这也包括了 QSplitter 类的声明在里面。 第 5-7 行定义了布局内用到的窗口部件。 第 8 行定义了一个分裂器水平布局。 第 9-11 行将窗口部件加入到分裂器布局之中。 第 12-15 行为 listWidget 添加一些项目。注意在这个程序中,由于 main()主函数并不 是属于某个 QObject 类的子类,所以不能直接使用 tr()函数,而需要静态调用它,即 QObject::tr()。 第 16 行设置 treeWidget 的列数为 1。 第 17 行声明一个链表对象 items。 第 18-19 行为 items 赋值。 第 20 行将 items 的值加入到 treeWidget 中。 第 21 行为 editor 设置文本。 第 22 行设置窗口标题。 第 23-24 行显示窗体。