QSplitter

  看了《C++ Gui Programming With Qt 4 2nd》第六章"布局管理器"的第三节"Splitters", 并且做了里面的例子, 感觉怎么跟书里面的图像很不相同. 特别是那些分界线, 存在是存在, 但是跟背景一模一样, 书上也没说明怎么处理分界线(可能后面有讲,这个我就不清楚了).

    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();

       在main方法里面写上上述代码, 运行后(注意看分界线, 看不到吧):

       QSplitter_第1张图片

       书里面是:

       QSplitter_第2张图片

       分界线方面的差距挺大的呢? 我查了一下, 原来是一条分界线是一个QSplitterHandle 类对象.  通过下面的一些代码, 我们可以统一修改分界线的样式.

    mainSplitter->setStyleSheet("QSplitter::handle { background-color: black }"); //设置分界线的样式

    mainSplitter->setHandleWidth(20);      //设置分界线的宽度

       加了上述两行代码后的效果如下:

       QSplitter_第3张图片

      分界线的背景颜色变为"黑色", 并且宽度变得很大, 看来上述代码是起到作用了. 如果有很多条分界线, 我们希望只修改第一条的分界线, 怎么办呢?  请看下面的一行代码:

QSplitterHandle *handle = mainSplitter->handle(1); //注意不是从0 索引开始, 如果找不到分界线, 将返回NULL.

      通过上述代码, 我们可以取得B 和 A 之间的分界线. 值得注意的是, mainSplitter->handle(0) 是存在的, 但是无法对其进行处理. 为了验证我们是否真的获取B 和 A 之间的分界线的对象指针, 我们写上下面的代码:

    if(handle)
    {
        handle->setFixedWidth(1); 
    }

      效果如下:

      QSplitter_第4张图片

      我们把B 和 A 之间的分界线的宽度修改为1了. 如果你想让分界线失去拖动的功能, 你可以写上 handle->setDisabled(true); 使其无效. 上面的分界线明显偏向了B 那边, 并且离A 有点距离, 看来要做得完善点, 还要耗点功夫才行呢!

      对于B 和 A 来说, 他们的本身的大小相对于整个窗口来说, 都是很小的. 这样就存在着一些多余的空间, 这些空间可以给B, 也可以给A, 或者两个平分. 对于B 和 A 各自空间大小的控制, 是通过 QSplitter 的 setStretchFactor 方法, 该方法的声明:

      void setStretchFactor(int index, int stretch);

      第一个参数index 是子微件的索引值, 从0 开始. 这里的话, B 是0, A 是1; 第二个参数 stretch 是拉伸系数, int 类型, 下面主要对stretch 的数值进行说明.

      1.  mainSplitter->setStretchFactor(0, -2);

      效果如下,

      QSplitter_第5张图片

      B占据了所有多余的空间, 看来 stretch 的值如果为负整数, 那这个微件将占据最大的空间.

      2.     mainSplitter->setStretchFactor(0, -2);
              mainSplitter->setStretchFactor(1, -4);

      效果如下:

      QSplitter_第6张图片

      B 和 A 平分了空间, 看来stretch 如果是负整数就会尽可能的占据空间, 而不看负整数的大小, 把 -2 改为 -12, 结果一样的.

      3.     mainSplitter->setStretchFactor(0, 0);
              mainSplitter->setStretchFactor(1, 0);

       效果同第二.

       4.       mainSplitter->setStretchFactor(0, 0);  //可以把这段注释掉, 效果一样
                 mainSplitter->setStretchFactor(1, 1);

       效果如下:

       QSplitter_第7张图片

       5.     mainSplitter->setStretchFactor(0, 4);
               mainSplitter->setStretchFactor(1, 8);

       效果如下:

       QSplitter_第8张图片

       6.     mainSplitter->setStretchFactor(0, -4);
               mainSplitter->setStretchFactor(1, 8);

      效果如下,

      QSplitter_第9张图片

       从 1, 2 和 6 的测试效果可以看出, 拉伸系数为负整数的微件将占据最大的多余空间.

       从3, 4 和 5 的测试效果来看, 就算我们不设置 B 或 A 的拉伸系数stretch, 他们内部也应该存在着一个默认拉伸系数值0. stretch为 0 的微件, 将把最大多余空间让给stretch 为正整数的微件. 如果有



QSplitter就是一个可以包含一些其他窗口部件的部件。在切分窗口QSplitter中的这些窗口部件会通过切分条Splitter handle而分割开来。用户可以通过拖动这些分割条改变切分条中子窗口的大小。QSplitter中的子窗口部件将会自动按照创建时的顺序一个挨着一个的放在一起,并且以切分窗口分割条来分割相邻的窗口。下面是代码实例#include <QtGui>
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QTextEdit *editor1 = new QTextEdit;    //定于在splitter中的三个编辑框
    QTextEdit *editor2 = new QTextEdit;
    QTextEdit *editor3 = new QTextEdit;
    QSplitter splitter(Qt::Horizontal);        //定义一个切分窗口
   splitter.addWidget(editor1);               //将文件控件加入到切分框
    splitter.addWidget(editor2);
    splitter.addWidget(editor3);       
    editor1->setPlainText("Mon enfant, ma soeur,\n"
                          "Songe  la douceur\n"
                          "D'aller l-bas vivre ensemble,\n"
                          "Aimer  loisir,\n"
                          "Aimer et mourir\n"
                          "Au pays qui te ressemble.");
    editor2->setPlainText("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!");
    editor3->setPlainText("Mein Kind, meine Schwester,\n"
                          "denke an den Traum\n"
                          "dort hin(unter) zu gehen um zusammen\n"
                          "zu leben und in aller Ruhe zu lieben,\n"
                          "Zu lieben und zu sterben\n"
                          "in dem Land, das dir gleicht.");
    splitter.setWindowTitle(QObject::tr("Splitter"));          //设置标题
    splitter.show();
    return app.exec();

}

效果如下:

QSplitter_第10张图片

可以随意改变各个窗口大小:

QSplitter_第11张图片

另外下面演示下使用多个splitter进行水平或者垂直方向上的嵌套。本代码适用于《C++ GUI QT4》

mailclient.cpp. 其界面布局部分代码如下

//窗口布局
    rightSplitter = new QSplitter(Qt::Vertical);
    rightSplitter->addWidget(messagesTreeWidget);  //在右窗口中添加一个邮件列表
    rightSplitter->addWidget(textEdit);                         //显示文本邮件
    rightSplitter->setStretchFactor(1, 1);                      //保证textEdit伸展到多余的空间

    mainSplitter = new QSplitter(Qt::Horizontal);
    mainSplitter->addWidget(foldersTreeWidget);
    mainSplitter->addWidget(rightSplitter);
    mainSplitter->setStretchFactor(1, 1);                     //使用两个setStretchFactor保证了把多余的额外空间都留给textEdit
    setCentralWidget(mainSplitter);
    setWindowTitle(tr("Mail Client"));

效果如下图:

QSplitter_第12张图片

你可能感兴趣的:(QSplitter)