基本使用

QDockWidget是一个可以停靠在QMainWindow内的窗口控件,它可以保持浮动状态或在指定位置作为子窗口附加到主窗口中。停靠窗口QDockWidget类是应用程序中经常用到的,设置停靠窗口的一般流程如下。

  • 创建一个QDockWidget对象的停靠窗体。
  • 设置此停靠窗体的属性,通常调用setFeatures()及setAllowedAreas()两种方法。
  • 新建一个要插入停靠窗体的控件,常用的有QListWidget和QTextEdit。
  • 将控件插入停靠窗体,调用QDockWidget的setWidget()方法。
  • 使用addDockWidget()方法在MainWindow中加入此停靠窗体。

这里使用Qt Designer ,随意拖拽添加QDockWidget到MainWindow任意区域可以停靠即可,在代码中对QDockWidget进行管理。Qt Designer无法任意调整位置,可以使用代码初始化QDockWidget布局。

布局相关

停靠特性

setFeatures()方法设置停靠窗体的特性,参数QDockWidget::DockWidgetFeatures指定停靠窗体的特性,包括以下几种参数。
① QDockWidget::DockWidgetClosable:停靠窗体可关闭。
② QDockWidget::DockWidgetMovable:停靠窗体可移动。
③ QDockWidget::DockWidgetFloatable:停靠窗体可浮动。
④ QDockWidget::AllDockWidgetFeatures:此参数表示拥有停靠窗体的所有特性。
⑤ QDockWidget::NoDockWidgetFeatures:不可移动、不可关闭、不可浮动。

停靠区域

setAllowedAreas()方法设置停靠窗体可停靠的区域,参数Qt::DockWidgetAreas指定了停靠窗体可停靠的区域,包括以下几种参数。
① Qt::LeftDockWidgetArea:可在主窗口的左侧停靠。
② Qt::RightDockWidgetArea:可在主窗口的右侧停靠。
③ Qt::TopDockWidgetArea:可在主窗口的顶端停靠。
④ Qt::BottomDockWidgetArea:可在主窗口的底部停靠。
⑤ Qt::AllDockWidgetArea:可在主窗口任意(以上四个)部位停靠。
⑥ Qt::NoDockWidgetArea:只可停靠在插入处。

添加dock

addDockWidget()方法用于添加dock,给dock指定位置,同时也可以更改dock的位置。

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

分割dock

splitDockWidget()方法用于分割dock窗口,是把两个dock进行左右或上下并排布置,做成一个类似QSplit的功能,分割原则是:水平从左到右,竖直从上到下。

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

dock tab化窗口

tabifyDockWidget()方法用于tab化窗口,把多个dock变成一个tab形式的窗体。

void QMainWindow::tabifyDockWidget(QDockWidget * first, QDockWidget * second)

初始化大小

靠左右布局的QDockWidget的高度是自适应的,宽度需要初始化设置,同理靠上下布局的高度需要初始化设置。使用splitDockWidget分割、tabifyDockWidget tab化窗口的QDockWidget的初始化大小与其依赖的QDockWidget(参数first)初始化大小一样。

void QMainWindow::resizeDocks(const QList<QDockWidget *> &docks, const QList<int> &sizes, Qt::Orientation orientation)

它的第一个参数是用来配置是哪个dock窗口需要调整大小;第二个参数是用来配置dock所占的像素大小,如果配置大于或者小于QMainWindow本身空间,Qt会根据所配置的像素大小的相对权重分配到dock中;第三个参数用来配置调整的方向,如果为Qt::Horizontal,调整dock宽度,Qt::Vertical调整dock高度,确定了停靠位置后resizeDocks才起作用。需要注意的是Qt官方文档上有注明这个方法在Qt5.6中引入,所以比Qt5.6低的版本并不能使用本方法。resizeDocks在多行或多列时初始化高宽无效问题!

使用setFeatures、setAllowedAreas、addDockWidget、splitDockWidget、tabifyDockWidget、resizeDocks可以满足基本的Dock布局了。

标题栏设置

去掉标题栏,但是不能拖动了。

QWidget *Widget = new QWidget;
ui->dockwidget_dockWidget_1->setTitleBarWidget(Widget);

自定义QWidget即可以自定义标题栏。

标题栏竖起

ui->dockwidget_dockWidget_6->setFeatures(QDockWidget::DockWidgetVerticalTitleBar);

其他问题

当使用tabifyDockWidgets进行tab化窗口时对Tabbar设置背景色时发现Tabbar上方有一行间隙。在QSS中使用qproperty-drawBase: 0;可以使得背景色填充到间隙中,但是发现Tabbar超过两个后其他的Tabbar不生效!!!

QTabBar {qproperty-drawBase: 0;background: rgb(45, 45, 45);
}

直接在代码中遍历Tabbar设置DrawBase属性可以解决Tabbar上方有一行间隙无法填充背景色问题。

Q_FOREACH (QTabBar *bar, this->findChildren<QTabBar *>())
{bar->setDrawBase(false);
}

当tab个数大于一定个数时,会出现如下图左侧白线所示,这个是Qt自带的,作用是点击回到第一个tab,但是显示不好看,这里隐藏掉

QTabBar::tear {width: 0px;border: none;
}

后续

  • 自定义标题栏。
  • 补充还原布局。

效果



相关代码

#include "dockwidget.h"
#include <QtCore/QtCore>DockWidget::DockWidget(QWidget *parent) : QMainWindow(parent), ui(new Ui_dockwidget)
{ui->setupUi(this);StyleMgr::SetStyleToWidgetByCssFile(this, ":/helloqt/resources/qss/custom/dockwidget.qss");// 如果不需要MainWindow的中间窗口,整个视图都由QDockWidget组成,可以把QMainWindow的中间窗口部件去除// QWidget *p = takeCentralWidget();// if (p)//   delete p;// 当不需要MainWindow的中间窗口时,发现不能拖动QDockWidget到中间,需要设置// setDockNestingEnabled(true);ui->dockwidget_dockWidget_1->setWindowTitle("Dock 1");ui->dockwidget_dockWidget_2->setWindowTitle("Dock 2");ui->dockwidget_dockWidget_3->setWindowTitle("Dock 3");ui->dockwidget_dockWidget_4->setWindowTitle("Dock 4");ui->dockwidget_dockWidget_5->setWindowTitle("Dock 5");ui->dockwidget_dockWidget_6->setWindowTitle("Dock 6");ui->dockwidget_dockWidget_7->setWindowTitle("Dock 7");ui->dockwidget_dockWidget_8->setWindowTitle("Dock 8");ui->dockwidget_dockWidget_9->setWindowTitle("Dock 9");ui->dockwidget_dockWidget_1->setFeatures(QDockWidget::DockWidgetMovable);                                   //可移动ui->dockwidget_dockWidget_2->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); //可关闭、移动ui->dockwidget_dockWidget_3->setFeatures(QDockWidget::DockWidgetMovable);                                   //可移动ui->dockwidget_dockWidget_4->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); //可关闭、移动ui->dockwidget_dockWidget_5->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); //可关闭、移动ui->dockwidget_dockWidget_6->setFeatures(QDockWidget::DockWidgetMovable);                                   //可移动ui->dockwidget_dockWidget_7->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); //可关闭、移动ui->dockwidget_dockWidget_8->setFeatures(QDockWidget::DockWidgetMovable);                                   //可移动ui->dockwidget_dockWidget_9->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); //可关闭、移动ui->dockwidget_dockWidget_1->setAllowedAreas(Qt::TopDockWidgetArea);    //可在主窗口的上侧停靠。ui->dockwidget_dockWidget_3->setAllowedAreas(Qt::LeftDockWidgetArea);   //可在主窗口的左侧停靠。ui->dockwidget_dockWidget_6->setAllowedAreas(Qt::RightDockWidgetArea);  //可在主窗口的右侧停靠。ui->dockwidget_dockWidget_8->setAllowedAreas(Qt::BottomDockWidgetArea); //可在主窗口的下侧停靠。// 去掉标题栏// QWidget *Widget = new QWidget;// ui->dockwidget_dockWidget_1->setTitleBarWidget(Widget);// 把QDockWidget标题栏竖起来// ui->dockwidget_dockWidget_6->setFeatures(QDockWidget::DockWidgetVerticalTitleBar);m_docks.append(ui->dockwidget_dockWidget_1);m_docks.append(ui->dockwidget_dockWidget_2);m_docks.append(ui->dockwidget_dockWidget_3);m_docks.append(ui->dockwidget_dockWidget_4);m_docks.append(ui->dockwidget_dockWidget_5);m_docks.append(ui->dockwidget_dockWidget_6);m_docks.append(ui->dockwidget_dockWidget_7);m_docks.append(ui->dockwidget_dockWidget_8);m_docks.append(ui->dockwidget_dockWidget_9);
}DockWidget::~DockWidget()
{delete ui;
}void DockWidget::ShowDockLayout(int type)
{RemoveAllDock();switch (type){case 1:addDockWidget(Qt::TopDockWidgetArea, ui->dockwidget_dockWidget_1);addDockWidget(Qt::LeftDockWidgetArea, ui->dockwidget_dockWidget_3);addDockWidget(Qt::RightDockWidgetArea, ui->dockwidget_dockWidget_6);addDockWidget(Qt::BottomDockWidgetArea, ui->dockwidget_dockWidget_8);resizeDocks({ui->dockwidget_dockWidget_1, ui->dockwidget_dockWidget_8}, {200, 100}, Qt::Vertical);   //上下resizeDocks({ui->dockwidget_dockWidget_3, ui->dockwidget_dockWidget_6}, {300, 300}, Qt::Horizontal); //左右ShowDock(QList<int>() << 0 << 2 << 5 << 7);break;case 2:addDockWidget(Qt::TopDockWidgetArea, ui->dockwidget_dockWidget_1);addDockWidget(Qt::LeftDockWidgetArea, ui->dockwidget_dockWidget_3);addDockWidget(Qt::RightDockWidgetArea, ui->dockwidget_dockWidget_6);addDockWidget(Qt::BottomDockWidgetArea, ui->dockwidget_dockWidget_8);resizeDocks({ui->dockwidget_dockWidget_1, ui->dockwidget_dockWidget_8}, {200, 100}, Qt::Vertical);   //上下,初始化高度resizeDocks({ui->dockwidget_dockWidget_3, ui->dockwidget_dockWidget_6}, {300, 300}, Qt::Horizontal); //左右,初始化宽度resizeDocks({ui->dockwidget_dockWidget_1}, {200}, Qt::Horizontal);splitDockWidget(ui->dockwidget_dockWidget_1, ui->dockwidget_dockWidget_2, Qt::Horizontal);resizeDocks({ui->dockwidget_dockWidget_3}, {50}, Qt::Vertical);splitDockWidget(ui->dockwidget_dockWidget_3, ui->dockwidget_dockWidget_4, Qt::Vertical);resizeDocks({ui->dockwidget_dockWidget_4}, {100}, Qt::Vertical);splitDockWidget(ui->dockwidget_dockWidget_4, ui->dockwidget_dockWidget_5, Qt::Vertical);resizeDocks({ui->dockwidget_dockWidget_6}, {150}, Qt::Vertical);splitDockWidget(ui->dockwidget_dockWidget_6, ui->dockwidget_dockWidget_7, Qt::Vertical);resizeDocks({ui->dockwidget_dockWidget_8}, {300}, Qt::Horizontal);splitDockWidget(ui->dockwidget_dockWidget_8, ui->dockwidget_dockWidget_9, Qt::Horizontal);ShowDock(QList<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8);break;case 3:addDockWidget(Qt::TopDockWidgetArea, ui->dockwidget_dockWidget_1);tabifyDockWidget(ui->dockwidget_dockWidget_1, ui->dockwidget_dockWidget_2);addDockWidget(Qt::LeftDockWidgetArea, ui->dockwidget_dockWidget_3);tabifyDockWidget(ui->dockwidget_dockWidget_3, ui->dockwidget_dockWidget_4);tabifyDockWidget(ui->dockwidget_dockWidget_4, ui->dockwidget_dockWidget_5);addDockWidget(Qt::RightDockWidgetArea, ui->dockwidget_dockWidget_6);tabifyDockWidget(ui->dockwidget_dockWidget_6, ui->dockwidget_dockWidget_7);addDockWidget(Qt::BottomDockWidgetArea, ui->dockwidget_dockWidget_8);tabifyDockWidget(ui->dockwidget_dockWidget_8, ui->dockwidget_dockWidget_9);resizeDocks({ui->dockwidget_dockWidget_1, ui->dockwidget_dockWidget_8}, {200, 100}, Qt::Vertical);   //上下resizeDocks({ui->dockwidget_dockWidget_3, ui->dockwidget_dockWidget_6}, {300, 300}, Qt::Horizontal); //左右ShowDock(QList<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8);break;default:break;}// 解决Tabbar上方有一行间隙无法填充背景色问题Q_FOREACH (QTabBar *bar, this->findChildren<QTabBar *>()){bar->setDrawBase(false);}
}/// @brief 移除并隐藏所有的dock
void DockWidget::RemoveAllDock()
{for (int i = 0; i < 9; ++i){removeDockWidget(m_docks[i]);}
}/// @brief 显示指定序号的dock
/// @param index 指定序号,如果不指定,则会显示所有
void DockWidget::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();}}
}
QWidget#dockwidget {border: none;background-color: rgb(30, 30, 30);
}QDockWidget#dockwidget_dockWidget_1,
#dockwidget_dockWidgetContents_1 {border: none;background-color: rgb(189, 79, 60);
}QDockWidget#dockwidget_dockWidget_2,
#dockwidget_dockWidgetContents_2 {border: none;background-color: rgb(189, 133, 60);
}QDockWidget#dockwidget_dockWidget_3,
#dockwidget_dockWidgetContents_3 {border: none;background-color: rgb(161, 189, 60);
}QDockWidget#dockwidget_dockWidget_4,
#dockwidget_dockWidgetContents_4 {border: none;background-color: rgb(60, 189, 109);
}QDockWidget#dockwidget_dockWidget_5,
#dockwidget_dockWidgetContents_5 {border: none;background-color: rgb(60, 152, 189);
}QDockWidget#dockwidget_dockWidget_6,
#dockwidget_dockWidgetContents_6 {border: none;background-color: rgb(62, 60, 189);
}QDockWidget#dockwidget_dockWidget_7,
#dockwidget_dockWidgetContents_7 {border: none;background-color: rgb(105, 60, 189);
}QDockWidget#dockwidget_dockWidget_8,
#dockwidget_dockWidgetContents_8 {border: none;background-color: rgb(178, 60, 189);
}QDockWidget#dockwidget_dockWidget_9,
#dockwidget_dockWidgetContents_9 {border: none;background-color: rgb(189, 60, 120);
}/* QDockWidget之间的间距调整 */
QMainWindow::separator {width: 0px;height: 0px;margin: 0px;/* 如果将两个QDockWidget之间的间距调为0后,QDockWidget将没办法拉拽,所以留出一点小缝隙 */padding: 0, 1px;
}QDockWidget {color: white;
}/* 标题设置 */
QDockWidget::title {/* 标题字体在这里设置无效,要在QDockWidget中设置! *//* color: white; */text-align: left;/* 不设置背景色时标题栏下方有空隙! */background: rgb(45, 45, 48);padding-left: 5px;
}/* 按钮图标 */
QDockWidget {border: 1px solid rgb(45, 45, 48);titlebar-close-icon: url(:/dockwidget/resources/image/dockwidget/close.png);titlebar-normal-icon: url(:/dockwidget/resources/image/dockwidget/normal.png);
}QDockWidget::close-button,
QDockWidget::float-button {/* 不设置border则hover、pressed时的background颜色不生效! */border: 1px solid transparent;background: rgb(45, 45, 48);/* 会影响标题栏高度 *//* padding: 0px; *//* 不起作用! */icon-size: 32px;
}QDockWidget::close-button:hover,
QDockWidget::float-button:hover {color: rgb(0, 151, 251);background: rgb(62, 62, 64);
}QDockWidget::close-button:pressed,
QDockWidget::float-button:pressed {background: rgb(37, 37, 38);padding: 1px -1px -1px 1px;
}/* tabifyDockWidgets TabBar设置*/
QTabBar {qproperty-drawBase: 0;background: rgb(45, 45, 48);
}QTabBar::tab {color: white;background: rgb(45, 45, 48);padding: 4px;border: 1px solid transparent;
}QTabBar::tab:hover {color: rgb(0, 151, 251);
}QTabBar::tab:selected {color: rgb(0, 151, 251);background: rgb(37, 37, 38);border-bottom-color: rgb(0, 151, 251);
}/* 当tab个数大于一定个数时,会出现如下图左侧白线所示,这个是Qt自带的,作用是点击回到第一个tab,但是显示不好看,这里隐藏掉 */
QTabBar::tear {width: 0px;border: none;
}

github

https://github.com/weichangk/helloqt

参考:

https://doc.qt.io/qt-5/qdockwidget.html
https://doc.qt.io/qt-5/qmainwindow.html#resizeDocks
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qdockwidget
https://github.com/czyt1988/czyBlog/tree/master/tech/QDockWidget_VSStudioMode
https://zhuanlan.zhihu.com/p/381444869
https://forum.qt.io/topic/88409/stylesheet-and-qtabbar-which-element-is-this

Qt 停靠布局QDockWidget使用相关推荐

  1. Qt Widgets 之 QDockWidget(停靠窗口)

    目录 什么是停靠窗口 如何添加停靠窗口 QDockWidget::setWidget() QMainWindow::addDockWidget() 设置停靠选项 (Options) AnimatedD ...

  2. QT界面:QDockWidget停靠窗口使用小结

    QDockWidget停靠窗口 Qt构建停靠窗口使用的是QDockWidget类. 窗口特性 停靠窗口特性可以通过setFeatures(QDockWidget::AllDockWidgetFeatu ...

  3. Qt5—嵌入停靠窗口QDockWidget

    参考链接:http://blog.csdn.net/summer_xiyer/article/details/12875899 新建一个GUI工程: QDockWidget是QWidget的子类,也等 ...

  4. 第3章 Qt 5布局管理

    一.分割窗口QSplitter类 [例](简单)(CH301)一个十分简单的分割窗口功能,整个窗口由三个子窗口组成,各个子窗口之间的大小可随意拖曳改变,效果如图3.1所示. 本实例采用编写代码的方式实 ...

  5. 第15.39节、splitDockWidget和tabifyDockWidget嵌套布局QDockWidget的PyQt人机对话案例:笨笨机器人

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 在第<第三十一章.containers容器类部件QDo ...

  6. Qt 垂直布局 (QVBoxLayout)

    Qt 垂直布局 (QVBoxLayout) 上一节说了水平布局:https://blog.csdn.net/weixin_42837024/article/details/82114258 QVBox ...

  7. Qt Quick 布局介绍

    在 Qt Widgets 中,我们经常使用布局管理器来管理界面上的众多 widgets .在 Qt Quick 中其实有两套与布局管理相关的类库,一套叫作 Item Positioner ,一套叫作 ...

  8. QT QTreeWidget与QDockWidget的使用

    主要实现悬浮窗口的左右移动,QTreeWidget子项信号的使用 ,以及菜单栏与状态栏的使用. 一.效果图展示 二.主要代码 mainwindow.h public:int m_time;QLabel ...

  9. Qt之布局设置setLayout详解-源码剖析(下)

    一.简述 大家好,我是前行中的小猪,今天呢给大家继续上一篇Qt之布局设置setLayout详解(上)之后的内容,再给大家进行一下拓展. 1.1 setLayout源码剖析 上篇我们说到如何清空部件上的 ...

最新文章

  1. .net framework 2.0 安装包下载url
  2. HTML5 中的canvas元素用于,HTML5中的Canvas元素
  3. 音视频技术开发周刊 | 166
  4. mybatis oracle trim,Mybatis trim标签
  5. 通俗的讲,这就是容器CPU隔离的底层实现机制
  6. python闭包应用实例_Python中的闭包详细介绍和实例
  7. 【CVPR2021】论文汇总列表--Part2
  8. java基础-(一)-JDK的下载和安装
  9. 新手下载安装GitHub
  10. SpringBoot配置SSL证书
  11. 12306 抢票系列之只要搞定RAIL_DEVICEID的来源,从此抢票不再掉线(中)
  12. UE4中3DUI防遮挡显示/穿模部分透明化显示
  13. tieredImageNet 数据集介绍
  14. PyCharm代码格式化插件
  15. 中国服装自主品牌行业市场环境与投资趋势分析报告
  16. 【阅读笔记】SiamMask
  17. wannacry 专杀_蠕虫勒索软件专杀工具
  18. ENVI 5.6软件安装教程
  19. Student学生表(学号,姓名、性别、年龄、组织部门),Course 课程表(编号,课程名称),Sc选课表(学号,课程编号,成绩)
  20. SCI论文写作(二) | SCI论文的引言(Introduction)部分

热门文章

  1. JS输入手机号码加空格
  2. linux 磁盘io监控
  3. 李嘉诚:打工是最愚蠢的投资
  4. 涟源举办系列文旅活动推动湖南文旅产业发展!
  5. 中孚实业建河南云计算数据中心
  6. Springboot_ Mybatis-plus联表查询
  7. 计算机毕业设计Python+Django基于python摄影作品相册分享系统(源码+系统+mysql数据库+Lw文档)
  8. 计算机主机接通显示器位置发,电脑主机和显示器连接不上
  9. 词法分析与词性标注学习之笔记(一)----词法分析
  10. 常见的关系型数据库和非关系型都有哪些?