`
wx1569110409
  • 浏览: 18621 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

概述

许多工程软件,如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();

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

转载于:https://my.oschina.net/2nmjeSMen3/blog/674359

分享到:
评论

相关推荐

    visual studio 2008 CSSDEMO使用之演示程序

    **Visual Studio 2008 CSSDEMO演示程序详解** 在Web开发领域,Visual Studio 2008作为一款强大的集成开发环境(IDE),为开发者提供了丰富的工具和功能,其中包括对ASP.NET网页设计的支持。本篇文章将深入探讨如何...

    Microsoft Visual Studio 2008快捷键大全

    《Microsoft Visual Studio 2008 快捷键详解与高效开发指南》 Microsoft Visual Studio 2008(简称VS)是微软公司推出的一款强大的集成开发环境,它提供了丰富的功能和工具,使得开发者能够更高效地编写和调试代码...

    Microsoft Visual Studio快捷键

    ### Microsoft Visual Studio 快捷键详解 #### 一、文本编辑与管理 **1. 插入新行** - **Ctrl+Enter**:在光标所在行上方插入新行。 - **Ctrl+Shift+Enter**:在光标所在行下方插入新行。 这两种操作非常适合在...

    吐血推荐珍藏的Visual Studio Code插件(推荐)

    Visual Studio Code(VSC)是一款深受开发者喜爱的轻量级代码编辑器,它拥有丰富的插件生态,能够极大地提升开发者的生产力。以下是一些被高度推荐的VSC插件及其功能详解: 1. **Material Theme**:这款插件提供了...

    Visual_Studio_2005课件5

    ### Visual Studio 2005课程精粹:复合赋值操作符与Switch语句 #### 复合赋值操作符:提升代码效率与可读性的利器 复合赋值操作符,作为C#语言中的一个重要特性,旨在简化代码,提高编程效率。当我们需要对一个...

    IndentGuide_2012.rar

    《Visual Studio 2012 代码虚线对齐插件IndentGuide详解》 在编程过程中,代码的整洁与对齐对于提升代码可读性和维护性至关重要。Visual Studio作为Microsoft开发的一款强大的集成开发环境(IDE),提供了丰富的...

    LINQ学习手册

    - 支持嵌套母板页,便于构建复杂的网页布局。 - 强大的CSS编辑器集成,帮助开发者轻松管理和编辑样式表。 - **编程语言方面的改进和LINQ**: - C# 3.0引入了许多新特性,如隐式类型的局部变量、对象初始化器等,...

    linq学习文档

    #### 三、Visual Studio 2008新特性详解 - **多.NET Framework版本支持**:Visual Studio 2008支持.NET Framework 2.0/3.0 和 3.5,能够自动适应不同框架版本下的特性与工具箱。 - **ASP.NET AJAX**:ASP.NET AJAX ...

    101位雨昕6

    【知识点详解】 本实验主要涉及的是使用C语言编程来绘制用户输入的对号函数曲线,同时要求曲线的采样点用“*”表示。实验旨在加深对C语言的理解,熟悉Visual Studio的使用,并掌握条件语句、循环语句、数组等基础...

    VB.net教程与实训

    - **工具箱**:介绍Visual Studio.NET提供的工具箱,以及如何使用这些工具来快速构建界面。 - **调试技术**:讲解如何使用Visual Studio.NET内置的调试工具来查找和修复代码错误。 #### 二、基本控件与事件处理 ##...

    [Visual.C#.2008从入门到精通](高清扫描版)

    - **流程控制语句**:深入探讨各种流程控制语句的具体实现方式,例如嵌套if语句、switch-case结构等。 - **循环优化**:如何通过for-each循环等高级循环结构提高代码效率。 #### 面向对象编程深入 - **封装性**:...

    Reporting service

    - **SQL Server Data Tools (SSDT)**:集成在 Visual Studio 中的报表设计工具,用于创建和修改报表。 - **Report Builder**:轻量级报表设计工具,适合非专业开发人员使用。 - **报表类型**: - **表格式报表**...

    VS2019-Viasfora4.3

    Visual Studio 2019是Microsoft推出的强大集成开发环境(IDE),而Viasfora则是一款针对该IDE的第三方插件,旨在提升开发者的代码编辑体验和效率。Viasfora 4.3是该插件的一个版本,它为VS2019带来了丰富的增强功能...

    Crystal Reports联机帮助文档

    **Crystal Reports联机帮助文档详解** Crystal Reports是一款强大的报表设计工具,广泛应用于商业智能和数据分析领域。它允许用户从各种数据源(如数据库、Excel表格、XML文件等)设计和生成复杂的报告,提供了丰富...

    LINQ系列文章.pdf

    - **浏览.NET Framework库源码**:Visual Studio 2008提供了内置的调试器支持,可以在调试过程中查看.NET Framework的源码,帮助开发者更好地理解.NET类库的工作原理。 - **智能部署ClickOnce**:简化了应用程序的...

Global site tag (gtag.js) - Google Analytics