精华内容
下载资源
问答
  • Qt之QDockWidget嵌套布局详解-实现Visual Studio布局 ...

    Qt之QDockWidget嵌套布局详解-实现Visual Studio布局

    概述

    许多工程软件,如Qt Creator,VS,matlab等,都是使用dock布局窗口,这样用户可以自定义界面,自由组合窗口。
    Qt的嵌套布局由QDockWidget完成,用Qt Creator拖界面得到的dock布置形式比较固定,不能得想要的任意组合形式,要得到如下图所示的效果,后续布局必须通过代码来完成。
    这里写图片描述
    下面说说如何实现完全自由的界面布局效果:

    QDockWidget在QMainWindow的布局函数

    要在QMainWindow里对dock进行布局,需要用到如下几个函数:

    • 添加dock函数
      此函数用于给dock指定位置,同时也可以更改dock的位置,此函数命名为addDockWidget有点容易误导,因为不仅仅有add的功能,还有chang的功能
    1. void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget)
    2. void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget, Qt::Orientation orientation)
    • splitDockWidget 分割dock窗口函数                                                                                                                                        

    此函数的功能是把两个dock进行左右或上下并排布置,做成一个类似QSplit的功能

    void QMainWindow::splitDockWidget(QDockWidget * first, QDockWidget * second, Qt::Orientation orientation)

     

    • tabifyDockWidget tab化窗口函数
      此函数的功能是把多个dock变成一个tab形式的窗体
    void QMainWindow::tabifyDockWidget(QDockWidget * first, QDockWidget * second)

     

    • 设置dock嵌套布局
      此函数是设置嵌套布局的关键
    void QMainWindow::setDockNestingEnabled(bool enabled)

     

    以上几个函数就能完成比较复杂的嵌套布局了。

    设置嵌套布局

    下面通过例子来讲解如何设置复杂的嵌套布局
    先用Qt Creator拖放9个dock进视图里,为了好区分,给每个dock设置一个背景颜色:

    这里写图片描述


    dock属性随便设置,保证都任意区域可以停靠即可
    由于这里不需要MainWindow的中间窗口,整个视图都由dock组成,因此先把QMainWindow的中间窗口部件去除:
    在MainWindow的构造函数加入如下语句,即可把MainWindow的中间窗口去除,这时整个MainWindow只有Dock组成

    1. QWidget* p = takeCentralWidget();
    2. if(p)
    3. delete p;

     

    编译出来的效果如图所示:

    这里写图片描述


    拖动dock可以发现,只能在两边进行组合,我想把dock放置到中间是无法实现的,这是由于为了简化dock的吸附,QMainWindow默认是把dock嵌套关闭的,需要我们手动设置,在MainWindow的构造函数里添加:

    setDockNestingEnabled(true);

     

    即可打开嵌套功能,这时编译出来的窗口能实现如下嵌套:

    这里写图片描述


    此时,整个窗口的布局将变得非常灵活且复杂,由于Qt Creator在ui编辑器中无法像编译出来的程序那样任意调整位置,因此需要手动对窗口进行设置。下面将介绍如何用代码设置复杂的dock
    为了方便,添加两个函数和一个成员变量:
    head:

    1. public:
    2. //移除并隐藏所有dock
    3. void removeAllDock();
    4. //显示dock窗口
    5. void showDock(const QList<int>& index = QList<int>());
    6. private:
    7. QList<QDockWidget*> m_docks;///< 记录所有dockWidget的指针

     

    CPP:

    1. MainWindow::MainWindow(QWidget *parent) :
    2. QMainWindow(parent),
    3. ui(new Ui::MainWindow)
    4. {
    5. ui->setupUi(this);
    6. //删除中央窗体
    7. QWidget* p = takeCentralWidget();
    8. if(p)
    9. delete p;
    10. //允许嵌套dock
    11. setDockNestingEnabled(true);
    12. //记录所有的dock指针
    13. m_docks.append(ui->dockWidget_1);
    14. m_docks.append(ui->dockWidget_2);
    15. m_docks.append(ui->dockWidget_3);
    16. m_docks.append(ui->dockWidget_4);
    17. m_docks.append(ui->dockWidget_5);
    18. m_docks.append(ui->dockWidget_6);
    19. m_docks.append(ui->dockWidget_7);
    20. m_docks.append(ui->dockWidget_8);
    21. m_docks.append(ui->dockWidget_9);
    22. }
    23. MainWindow::~MainWindow()
    24. {
    25. delete ui;
    26. }
    27. ///
    28. /// \brief 移除并隐藏所有的dock
    29. ///
    30. void MainWindow::removeAllDock()
    31. {
    32. for(int i=0;i<9;++i)
    33. {
    34. removeDockWidget(m_docks[i]);
    35. }
    36. }
    37. ///
    38. /// \brief 显示指定序号的dock
    39. /// \param index 指定序号,如果不指定,则会显示所有
    40. ///
    41. void MainWindow::showDock(const QList<int> &index)
    42. {
    43. if (index.isEmpty())
    44. {
    45. for(int i=0;i<9;++i)
    46. {
    47. m_docks[i]->show();
    48. }
    49. }
    50. else
    51. {
    52. foreach (int i, index) {
    53. m_docks[i]->show();
    54. }
    55. }
    56. }

    void removeAllDock();函数可以把所有的dock隐藏void showDock(const QList<int>& index = QList<int>())则可以显示指定的dock。
    下面先对需要用到的几个函数进行示范:

    addDockWidget

    addDockWidget函数用于给MainWindow添加dock窗体,指定添加的区域,如果想改变dock的位置,也可以使用此函数进行移动。

    1. void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget)
    2. void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget, Qt::Orientation orientation)

    如:

    1. addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    2. addDockWidget(Qt::RightDockWidgetArea,ui->dockWidget_2);
    3. addDockWidget(Qt::TopDockWidgetArea,ui->dockWidget_3);
    4. addDockWidget(Qt::BottomDockWidgetArea,ui->dockWidget_4);

    把4个dock按照上下左右布置,效果如下:

    这里写图片描述

    splitDockWidget

    splitDockWidget

    void QMainWindow::splitDockWidget(QDockWidget * first, QDockWidget * second, Qt::Orientation orientation)

     

    此函数可以把一个dock(QDockWidget * first)在其位置上进行嵌套,嵌套可以指定水平嵌套或者垂直嵌套,嵌套方向是从左到右,从上到下,也就是QDockWidget * first相对于QDockWidget * second永远在左边或者上边。
    如:

    1. removeAllDock();
    2. addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    3. splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
    4. splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    5. splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Horizontal);
    6. splitDockWidget(ui->dockWidget_4,ui->dockWidget_5,Qt::Horizontal);
    7. showDock(QList<int>()<< 0<<1<<2<<3<<4);

    得到如下效果:

    这里写图片描述


    若是:

    1. removeAllDock();
    2. addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    3. splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Vertical);
    4. splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Vertical);
    5. splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Vertical);
    6. splitDockWidget(ui->dockWidget_4,ui->dockWidget_5,Qt::Vertical);
    7. showDock(QList<int>()<< 0<<1<<2<<3<<4);

     

    那么效果变为:

    这里写图片描述


    此函数是实现嵌套布局的关键,首先指定基准,然后开始进行分割,即可得到比较复杂的布局。
    分割原则是:先水平,再竖直,从左到右,从上到下
    下面显示一个九宫格布局:

    这里写图片描述


    实现代码

    1. removeAllDock();
    2. //原则,先左右,再上下
    3. addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    4. splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
    5. splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    6. splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical);
    7. splitDockWidget(ui->dockWidget_2,ui->dockWidget_5,Qt::Vertical);
    8. splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical);
    9. splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Vertical);
    10. splitDockWidget(ui->dockWidget_5,ui->dockWidget_8,Qt::Vertical);
    11. splitDockWidget(ui->dockWidget_6,ui->dockWidget_9,Qt::Vertical);
    12. showDock();

    这里写图片描述


    实现代码:

    1. removeAllDock();
    2. //原则,先左右,再上下
    3. addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    4. splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
    5. splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    6. splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical);
    7. splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical);
    8. splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Vertical);
    9. splitDockWidget(ui->dockWidget_6,ui->dockWidget_9,Qt::Vertical);
    10. showDock(QList<int>()<< 0<<1<<2<<3<<5<<6<<8);

    这里写图片描述


    实现代码:

    1. removeAllDock();
    2. addDockWidget(Qt::TopDockWidgetArea,ui->dockWidget_1);
    3. addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_2);
    4. splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    5. splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Horizontal);
    6. splitDockWidget(ui->dockWidget_2,ui->dockWidget_5,Qt::Horizontal);
    7. splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Horizontal);
    8. splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Horizontal);
    9. showDock(QList<int>()<< 0<<1<<2<<3<<4<<5<<6);

    反正就是用splitDockWidgetaddDockWidget你想怎么布置就怎么布置。

    tabifyDockWidget

    此函数就是实现tab合并功能
    直接看看下面例子:

    这里写图片描述


    实现原理:

    1. removeAllDock();
    2. addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    3. splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
    4. splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    5. splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical);
    6. splitDockWidget(ui->dockWidget_2,ui->dockWidget_5,Qt::Vertical);
    7. splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical);
    8. tabifyDockWidget(ui->dockWidget_1,ui->dockWidget_7);
    9. tabifyDockWidget(ui->dockWidget_5,ui->dockWidget_8);
    10. tabifyDockWidget(ui->dockWidget_3,ui->dockWidget_9);
    11. showDock();
                                    <div class="more-toolbox">
                <div class="left-toolbox">
                    <ul class="toolbox-list">
                        
                        <li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#csdnc-thumbsup"></use>
                        </svg><span class="name">点赞</span>
                        <span class="count">3</span>
                        </a></li>
                        <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;popu_824&quot;}"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-csdnc-Collection-G"></use>
                        </svg><span class="name">收藏</span></a></li>
                        <li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-csdnc-fenxiang"></use>
                        </svg>分享</a></li>
                        <!--打赏开始-->
                                                <!--打赏结束-->
                                                <li class="tool-item tool-more">
                            <a>
                            <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
                            </a>
                            <ul class="more-box">
                                <li class="item"><a class="article-report">文章举报</a></li>
                            </ul>
                        </li>
                                            </ul>
                </div>
                            </div>
            <div class="person-messagebox">
                <div class="left-message"><a href="https://blog.csdn.net/Aidam_Bo">
                    <img src="https://profile.csdnimg.cn/F/A/6/3_aidam_bo" class="avatar_pic" username="Aidam_Bo">
                                            <img src="https://g.csdnimg.cn/static/user-reg-year/1x/3.png" class="user-years">
                                    </a></div>
                <div class="middle-message">
                                        <div class="title"><span class="tit"><a href="https://blog.csdn.net/Aidam_Bo" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" target="_blank">MANY_L</a></span>
                                            </div>
                    <div class="text"><span>发布了339 篇原创文章</span> · <span>获赞 99</span> · <span>访问量 10万+</span></div>
                </div>
                                <div class="right-message">
                                            <a href="https://im.csdn.net/im/main.html?userName=Aidam_Bo" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信
                        </a>
                                                            <a class="btn btn-sm attented bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">已关注</a>
                                    </div>
                            </div>
                    </div>
    </article>
    
    展开全文
  • QDockWidget嵌套布局详解-实现Visual Studio布局 标签: qt界面QDockWidge 2016-04-22 15:31 3109人阅读 评论(12) 收藏 举报 本文章已收录于: 分类: qt(17) 作者同类文章...

    QDockWidget嵌套布局详解-实现Visual Studio布局

    标签: qt界面QDockWidge
    3109人阅读 评论(12) 收藏 举报
    本文章已收录于:
    分类:

    概述

    许多工程软件,如Qt Creator,VS,matlab等,都是使用dock布局窗口,这样用户可以自定义界面,自由组合窗口。
    Qt的嵌套布局由QDockWidget完成,用Qt Creator拖界面得到的dock布置形式比较固定,不能得想要的任意组合形式,要得到如下图所示的效果,后续布局必须通过代码来完成。
    这里写图片描述
    ps:这是自己没事写的一个数据可视化软件
    下面说说如何实现完全自由的界面布局效果:

    QDockWidget在QMainWindow的布局函数

    要在QMainWindow里对dock进行布局,需要用到如下几个函数:

    • 添加dock函数
      此函数用于给dock指定位置,同时也可以更改dock的位置,此函数命名为addDockWidget有点容易误导,因为不仅仅有add的功能,还有chang的功能
    void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget)
    void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget, Qt::Orientation orientation)
    • 1
    • 分割dock窗口函数
      此函数的功能是把两个dock进行左右或上下并排布置,做成一个类似QSplit的功能
    void QMainWindow::splitDockWidget(QDockWidget * first, QDockWidget * second, Qt::Orientation orientation)
    • 1
    • tab化窗口函数
      此函数的功能是把多个dock变成一个tab形式的窗体
    void QMainWindow::tabifyDockWidget(QDockWidget * first, QDockWidget * second)
    • 1
    • 设置dock嵌套布局
      此函数是设置嵌套布局的关键
    void QMainWindow::setDockNestingEnabled(bool enabled)
    • 1

    以上几个函数就能完成比较复杂的嵌套布局了。

    设置嵌套布局

    下面通过例子来讲解如何设置复杂的嵌套布局
    先用Qt Creator拖放9个dock进视图里,为了好区分,给每个dock设置一个背景颜色:
    这里写图片描述
    dock属性随便设置,保证都任意区域可以停靠即可
    由于这里不需要MainWindow的中间窗口,整个视图都由dock组成,因此先把QMainWindow的中间窗口部件去除:
    在MainWindow的构造函数加入如下语句,即可把MainWindow的中间窗口去除,这时整个MainWindow只有Dock组成

    QWidget* p = takeCentralWidget();
        if(p)
            delete p;
    • 1

    编译出来的效果如图所示:
    这里写图片描述
    拖动dock可以发现,只能在两边进行组合,我想把dock放置到中间是无法实现的,这是由于为了简化dock的吸附,QMainWindow默认是把dock嵌套关闭的,需要我们手动设置,在MainWindow的构造函数里添加:

    setDockNestingEnabled(true);
    • 1

    即可打开嵌套功能,这时编译出来的窗口能实现如下嵌套:
    这里写图片描述
    此时,整个窗口的布局将变得非常灵活且复杂,由于Qt Creator在ui编辑器中无法像编译出来的程序那样任意调整位置,因此需要手动对窗口进行设置。下面将介绍如何用代码设置复杂的dock
    为了方便,添加两个函数和一个成员变量:
    head:

    public:
        //移除并隐藏所有dock
        void removeAllDock();
        //显示dock窗口
        void showDock(const QList<int>& index = QList<int>());
    private:
        QList<QDockWidget*> m_docks;///< 记录所有dockWidget的指针
    • 1

    CPP:

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        //删除中央窗体
        QWidget* p = takeCentralWidget();
        if(p)
            delete p;
        //允许嵌套dock
        setDockNestingEnabled(true);
        //记录所有的dock指针
        m_docks.append(ui->dockWidget_1);
        m_docks.append(ui->dockWidget_2);
        m_docks.append(ui->dockWidget_3);
        m_docks.append(ui->dockWidget_4);
        m_docks.append(ui->dockWidget_5);
        m_docks.append(ui->dockWidget_6);
        m_docks.append(ui->dockWidget_7);
        m_docks.append(ui->dockWidget_8);
        m_docks.append(ui->dockWidget_9);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    ///
    /// \brief 移除并隐藏所有的dock
    ///
    void MainWindow::removeAllDock()
    {
        for(int i=0;i<9;++i)
        {
            removeDockWidget(m_docks[i]);
        }
    }
    ///
    /// \brief 显示指定序号的dock
    /// \param index 指定序号,如果不指定,则会显示所有
    ///
    void MainWindow::showDock(const QList<int> &index)
    {
        if (index.isEmpty())
        {
            for(int i=0;i<9;++i)
            {
                m_docks[i]->show();
            }
        }
        else
        {
            foreach (int i, index) {
                m_docks[i]->show();
            }
        }
    }
    
    • 1

    void removeAllDock();函数可以把所有的dock隐藏void showDock(const QList<int>& index = QList<int>())则可以显示指定的dock。
    下面先对需要用到的几个函数进行示范:

    addDockWidget

    addDockWidget函数用于给MainWindow添加dock窗体,指定添加的区域,如果想改变dock的位置,也可以使用此函数进行移动。

    void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget)
    void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget, Qt::Orientation orientation)
    • 1

    如:

    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    addDockWidget(Qt::RightDockWidgetArea,ui->dockWidget_2);
    addDockWidget(Qt::TopDockWidgetArea,ui->dockWidget_3);
    addDockWidget(Qt::BottomDockWidgetArea,ui->dockWidget_4);
    • 1

    把4个dock按照上下左右布置,效果如下:
    这里写图片描述

    splitDockWidget

    splitDockWidget

    void QMainWindow::splitDockWidget(QDockWidget * first, QDockWidget * second, Qt::Orientation orientation)
    • 1

    此函数可以把一个dock(QDockWidget * first)在其位置上进行嵌套,嵌套可以指定水平嵌套或者垂直嵌套,嵌套方向是从左到右,从上到下,也就是QDockWidget * first相对于QDockWidget * second永远在左边或者上边。
    如:

    removeAllDock();
    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_4,ui->dockWidget_5,Qt::Horizontal);
    showDock(QList<int>()<< 0<<1<<2<<3<<4);
    • 1

    得到如下效果:
    这里写图片描述
    若是:

    removeAllDock();
    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Vertical);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Vertical);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Vertical);
    splitDockWidget(ui->dockWidget_4,ui->dockWidget_5,Qt::Vertical);
    showDock(QList<int>()<< 0<<1<<2<<3<<4);
    • 1

    那么效果变为:
    这里写图片描述
    此函数是实现嵌套布局的关键,首先指定基准,然后开始进行分割,即可得到比较复杂的布局。
    分割原则是:先水平,再竖直,从左到右,从上到下
    下面显示一个九宫格布局:
    这里写图片描述
    实现代码

    removeAllDock();
    //原则,先左右,再上下
    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_5,Qt::Vertical);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical);
    splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Vertical);
    splitDockWidget(ui->dockWidget_5,ui->dockWidget_8,Qt::Vertical);
    splitDockWidget(ui->dockWidget_6,ui->dockWidget_9,Qt::Vertical);
    showDock();
    • 1

    这里写图片描述
    实现代码:

    removeAllDock();
    //原则,先左右,再上下
    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical);
    splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Vertical);
    splitDockWidget(ui->dockWidget_6,ui->dockWidget_9,Qt::Vertical);
    showDock(QList<int>()<< 0<<1<<2<<3<<5<<6<<8);
    • 1

    这里写图片描述
    实现代码:

    removeAllDock();
    addDockWidget(Qt::TopDockWidgetArea,ui->dockWidget_1);
    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_2);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_5,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Horizontal);
    showDock(QList<int>()<< 0<<1<<2<<3<<4<<5<<6);
    • 1

    反正就是用splitDockWidgetaddDockWidget你想怎么布置就怎么布置。

    tabifyDockWidget

    此函数就是实现tab合并功能
    直接看看下面例子:
    这里写图片描述
    实现原理:

    removeAllDock();
    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_5,Qt::Vertical);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical);
    tabifyDockWidget(ui->dockWidget_1,ui->dockWidget_7);
    tabifyDockWidget(ui->dockWidget_5,ui->dockWidget_8);
    tabifyDockWidget(ui->dockWidget_3,ui->dockWidget_9);
    showDock();
    • 1

    代码:
    本例代码下载:本例代码免积分-

    展开全文
  • Qt的嵌套布局由QDockWidget完成,用Qt Creator拖界面得到的dock布置形式比较固定,不能得想要的任意组合形式,要得到如下图所示的效果,后续布局必须通过代码来完成。  ps:这是自己没事写的一个数据可视化软件  ...

    概述

    许多工程软件,如Qt Creator,VS,matlab等,都是使用dock布局窗口,这样用户可以自定义界面,自由组合窗口。 
    Qt的嵌套布局由QDockWidget完成,用Qt Creator拖界面得到的dock布置形式比较固定,不能得想要的任意组合形式,要得到如下图所示的效果,后续布局必须通过代码来完成。 
    这里写图片描述
    ps:这是自己没事写的一个数据可视化软件 
    下面说说如何实现完全自由的界面布局效果:

    QDockWidget在QMainWindow的布局函数

    要在QMainWindow里对dock进行布局,需要用到如下几个函数:

    • 添加dock函数 
      此函数用于给dock指定位置,同时也可以更改dock的位置,此函数命名为addDockWidget有点容易误导,因为不仅仅有add的功能,还有chang的功能
    void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget)
    void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget, Qt::Orientation orientation)
    • 分割dock窗口函数 
      此函数的功能是把两个dock进行左右或上下并排布置,做成一个类似QSplit的功能
    void QMainWindow::splitDockWidget(QDockWidget * first, QDockWidget * second, Qt::Orientation orientation)
    • tab化窗口函数 
      此函数的功能是把多个dock变成一个tab形式的窗体
    void QMainWindow::tabifyDockWidget(QDockWidget * first, QDockWidget * second)
    • 设置dock嵌套布局 
      此函数是设置嵌套布局的关键
    void QMainWindow::setDockNestingEnabled(bool enabled)

    以上几个函数就能完成比较复杂的嵌套布局了。

    设置嵌套布局

    下面通过例子来讲解如何设置复杂的嵌套布局 
    先用Qt Creator拖放9个dock进视图里,为了好区分,给每个dock设置一个背景颜色: 
    这里写图片描述 
    dock属性随便设置,保证都任意区域可以停靠即可 
    由于这里不需要MainWindow的中间窗口,整个视图都由dock组成,因此先把QMainWindow的中间窗口部件去除: 
    在MainWindow的构造函数加入如下语句,即可把MainWindow的中间窗口去除,这时整个MainWindow只有Dock组成

    QWidget* p = takeCentralWidget();
        if(p)
            delete p;

    编译出来的效果如图所示: 
    这里写图片描述 
    拖动dock可以发现,只能在两边进行组合,我想把dock放置到中间是无法实现的,这是由于为了简化dock的吸附,QMainWindow默认是把dock嵌套关闭的,需要我们手动设置,在MainWindow的构造函数里添加:

    setDockNestingEnabled(true);

    即可打开嵌套功能,这时编译出来的窗口能实现如下嵌套: 
    这里写图片描述 
    此时,整个窗口的布局将变得非常灵活且复杂,由于Qt Creator在ui编辑器中无法像编译出来的程序那样任意调整位置,因此需要手动对窗口进行设置。下面将介绍如何用代码设置复杂的dock 
    为了方便,添加两个函数和一个成员变量: 
    head:

    public:
        //移除并隐藏所有dock
        void removeAllDock();
        //显示dock窗口
        void showDock(const QList<int>& index = QList<int>());
    private:
        QList<QDockWidget*> m_docks;///< 记录所有dockWidget的指针

    CPP:

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        //删除中央窗体
        QWidget* p = takeCentralWidget();
        if(p)
            delete p;
        //允许嵌套dock
        setDockNestingEnabled(true);
        //记录所有的dock指针
        m_docks.append(ui->dockWidget_1);
        m_docks.append(ui->dockWidget_2);
        m_docks.append(ui->dockWidget_3);
        m_docks.append(ui->dockWidget_4);
        m_docks.append(ui->dockWidget_5);
        m_docks.append(ui->dockWidget_6);
        m_docks.append(ui->dockWidget_7);
        m_docks.append(ui->dockWidget_8);
        m_docks.append(ui->dockWidget_9);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    ///
    /// \brief 移除并隐藏所有的dock
    ///
    void MainWindow::removeAllDock()
    {
        for(int i=0;i<9;++i)
        {
            removeDockWidget(m_docks[i]);
        }
    }
    ///
    /// \brief 显示指定序号的dock
    /// \param index 指定序号,如果不指定,则会显示所有
    ///
    void MainWindow::showDock(const QList<int> &index)
    {
        if (index.isEmpty())
        {
            for(int i=0;i<9;++i)
            {
                m_docks[i]->show();
            }
        }
        else
        {
            foreach (int i, index) {
                m_docks[i]->show();
            }
        }
    }
    

    void removeAllDock();函数可以把所有的dock隐藏void showDock(const QList<int>& index = QList<int>())则可以显示指定的dock。 
    下面先对需要用到的几个函数进行示范:

    addDockWidget

    addDockWidget函数用于给MainWindow添加dock窗体,指定添加的区域,如果想改变dock的位置,也可以使用此函数进行移动。

    void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget)
    void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget, Qt::Orientation orientation)

    如:

    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    addDockWidget(Qt::RightDockWidgetArea,ui->dockWidget_2);
    addDockWidget(Qt::TopDockWidgetArea,ui->dockWidget_3);
    addDockWidget(Qt::BottomDockWidgetArea,ui->dockWidget_4);

    把4个dock按照上下左右布置,效果如下: 
    这里写图片描述

    splitDockWidget

    splitDockWidget

    void QMainWindow::splitDockWidget(QDockWidget * first, QDockWidget * second, Qt::Orientation orientation)

    此函数可以把一个dock(QDockWidget * first)在其位置上进行嵌套,嵌套可以指定水平嵌套或者垂直嵌套,嵌套方向是从左到右,从上到下,也就是QDockWidget * first相对于QDockWidget * second永远在左边或者上边。 
    如:

    removeAllDock();
    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_4,ui->dockWidget_5,Qt::Horizontal);
    showDock(QList<int>()<< 0<<1<<2<<3<<4);

    得到如下效果: 
    这里写图片描述 
    若是:

    removeAllDock();
    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Vertical);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Vertical);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Vertical);
    splitDockWidget(ui->dockWidget_4,ui->dockWidget_5,Qt::Vertical);
    showDock(QList<int>()<< 0<<1<<2<<3<<4);

    那么效果变为: 
    这里写图片描述 
    此函数是实现嵌套布局的关键,首先指定基准,然后开始进行分割,即可得到比较复杂的布局。 
    分割原则是:先水平,再竖直,从左到右,从上到下 
    下面显示一个九宫格布局: 
    这里写图片描述 
    实现代码

    removeAllDock();
    //原则,先左右,再上下
    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_5,Qt::Vertical);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical);
    splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Vertical);
    splitDockWidget(ui->dockWidget_5,ui->dockWidget_8,Qt::Vertical);
    splitDockWidget(ui->dockWidget_6,ui->dockWidget_9,Qt::Vertical);
    showDock();

    这里写图片描述 
    实现代码:

    removeAllDock();
    //原则,先左右,再上下
    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical);
    splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Vertical);
    splitDockWidget(ui->dockWidget_6,ui->dockWidget_9,Qt::Vertical);
    showDock(QList<int>()<< 0<<1<<2<<3<<5<<6<<8);

    这里写图片描述 
    实现代码:

    removeAllDock();
    addDockWidget(Qt::TopDockWidgetArea,ui->dockWidget_1);
    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_2);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_5,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Horizontal);
    showDock(QList<int>()<< 0<<1<<2<<3<<4<<5<<6);

    反正就是用splitDockWidgetaddDockWidget你想怎么布置就怎么布置。

    tabifyDockWidget

    此函数就是实现tab合并功能 
    直接看看下面例子: 
    这里写图片描述 
    实现原理:

    removeAllDock();
    addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
    splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical);
    splitDockWidget(ui->dockWidget_2,ui->dockWidget_5,Qt::Vertical);
    splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical);
    tabifyDockWidget(ui->dockWidget_1,ui->dockWidget_7);
    tabifyDockWidget(ui->dockWidget_5,ui->dockWidget_8);
    tabifyDockWidget(ui->dockWidget_3,ui->dockWidget_9);
    showDock();
    展开全文
  • QDockWidget多层嵌套布局示例

    热门讨论 2016-04-22 15:35:58
    千万别下载,csdn私自修改我设置的积分(还不能改回来),去https://github.com/czyt1988/czyBlog/tree/master/tech/QDockWidget_VSStudioMode,下载源码。具体可见:...

空空如也

空空如也

1 2 3 4
收藏数 66
精华内容 26
关键字:

qdockwidget嵌套