前言
众所周知,停靠窗口可以实现任意拖动效果,本文重点在于如何利用Qt制作与Visual Studio相似的带有停靠方向标及停靠区域预览的的停靠窗口框架。

百度网盘体验地址:
链接:https://pan.baidu.com/s/19pCO8Z2aQZFpOXPVQw13EA
提取码:ihwk

效果图

功能
1、鼠标在中间方向标:叠加窗口
2、鼠标在上下左右方向标:分割目标窗口,并紧挨着目标窗口周边位置添加新窗口
3、鼠标在内部最上下左右方向标:目标窗口所在的最上下左右位置添加新窗口
4、鼠标在外部最上下左右方向标:程序主窗口的最上下左右位置添加新窗口
5、鼠标在Tab位置上:在当前所在tab页位置插入新窗口
6、鼠标在Tab最右侧位置上:在tab页尾部添加新窗口
注释:Dock停靠优先级:某些情况下,外部最上下左右方向的方向标会和目标窗口方向标重叠,此时遵循 中间停靠优于外部停靠、方向标停靠优于tab页停靠的原则。

部分头文件

#pragma once#include <QWidget>
#include <QPaintEvent>
#include "QWHDockWidget.h"class QMainWindow;
class QTabWidget;
class QDockWidget;
class QSplitter;class QWHTabWidgetMask : public QWidget
{Q_OBJECTpublic:enum Area{None,Top, Right, Bottom, Left, TopMore, RightMore, BottomMore, LeftMore, Center, TopMost, RightMost, BottomMost, LeftMost};QWHTabWidgetMask();~QWHTabWidgetMask();static QWHTabWidgetMask *getInstance();// 设置程序主窗口void setMainWindow(QMainWindow *mainWindow);// 创建停靠窗口QWHDockWidget *createDockWidget(QWHDockWidget::AreaMode areaMode, const QString &windowTitle = "");// 创建分裂器(水平分裂)QSplitter *createSplitter();// 创建分裂器(由参数orientation决定分裂方向)QSplitter *createSplitter(Qt::Orientation orientation);// 设置程序主分裂器void setMainSplitter(QSplitter *splitter);// 设置目标窗口(接收方)void setTargetWidget(QTabWidget *widget);// 设置当前页索引(鼠标移入当前页 或 鼠标移入中心方向标)void setCurTabIndex(int index);// 设置鼠标按下的停靠窗口(准备移动的窗口)void setMousePressed(QWHDockWidget *moveDockWidget);// 设置鼠标释放void setMouseReleased();// 获取停靠窗口推荐最小尺寸QSize minimumSizeHint() const override;// 获取鼠标按下的停靠窗口(准备移动或正在移动的窗口)QDockWidget *moveDockWidget();// 获取程序主分裂器QSplitter *mainSplitter();// 获取程序主窗口QMainWindow *mainWindow();protected:void paintEvent(QPaintEvent *event);private:// 获取指定索引的边界路径QPainterPath tabWidgetBorderPath(QTabWidget *tabWidget, int tabIndex);// 绘制主停靠窗口的指示器void drawMainDockIndicator();// 绘制次停靠窗口的指示器void drawMinorDockIndicator();// 检查鼠标所在方向标区域Area checkArea(QPoint globalPos);signals:// 创建停靠窗口void dockWidgetAdded(QWHDockWidget *newDockWidget);private:QMainWindow *m_mainWindow;QSplitter *m_mainSplitter;QWHDockWidget *m_moveDockWidget;QTabWidget *m_targetWidget;QList<QWHDockWidget *> m_listDockWidgets;int m_tabIndex;QColor m_borderColor;QColor m_bgColor;QRect m_centerRect;    // 中心矩形QRect m_topRect, m_rightRect, m_bottomRect, m_leftRect;  // 四个方位矩形(紧挨着中心矩形)QRect m_topMoreRect, m_rightMoreRect, m_bottomMoreRect, m_leftMoreRect; // 更加靠边四个方位矩形(紧挨着四个方位矩形)QRect m_topMostRect, m_rightMostRect, m_bottomMostRect, m_leftMostRect;   // 最靠边四个方向矩形(紧挨着主窗口四边)QPixmap m_centerPixmap;QPixmap m_topPixmap, m_rightPixmap, m_bottomPixmap, m_leftPixmap;QPixmap m_topMostPixmap, m_rightMostPixmap, m_bottomMostPixmap, m_leftMostPixmap;QPixmap m_centerPixmapHover;QPixmap m_topPixmapHover, m_rightPixmapHover, m_bottomPixmapHover, m_leftPixmapHover;QPixmap m_topMostPixmapHover, m_rightMostPixmapHover, m_bottomMostPixmapHover, m_leftMostPixmapHover;
};

测试代码

TestVSWindow::TestVSWindow(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);QWHTabWidgetMask::getInstance()->setMainWindow(this);// 测试左侧停靠窗体QWHDockWidget *dockWidget = QWHTabWidgetMask::getInstance()->createDockWidget(QWHDockWidget::Mode_Minor, "总tab");QSplitter *splitter = QWHTabWidgetMask::getInstance()->createSplitter();splitter->addWidget(dockWidget);dockWidget->setFloating(false);QWidget *widget1 = new QWidget();widget1->setMinimumSize(200, 100);widget1->setStyleSheet("background-color: green;");dockWidget->tabWidget()->addTab(widget1, "第一页");QWidget *widget2 = new QWidget();widget2->setMinimumSize(200, 100);widget2->setStyleSheet("background-color: green;");dockWidget->tabWidget()->addTab(widget2, "第二页");QWidget *widget3 = new QWidget();widget3->setMinimumSize(200, 100);widget3->setStyleSheet("background-color: green;");dockWidget->tabWidget()->addTab(widget3, "第三页");// 测试中间停靠窗体QWHDockWidget *dockWidgetCenter = QWHTabWidgetMask::getInstance()->createDockWidget(QWHDockWidget::Mode_Main, "总tabCenter");splitter->addWidget(dockWidgetCenter);dockWidgetCenter->setFloating(false);QWidget *widgetCenter1 = new QWidget();widgetCenter1->setMinimumSize(200, 100);widgetCenter1->setStyleSheet("background-color: rgb(255, 174, 201);");dockWidgetCenter->tabWidget()->addTab(widgetCenter1, "第一页Center");QWidget *widgetCenter2 = new QWidget();widgetCenter2->setMinimumSize(200, 100);widgetCenter2->setStyleSheet("background-color: rgb(255, 174, 201);");dockWidgetCenter->tabWidget()->addTab(widgetCenter2, "第二页Center");QWidget *widgetCenter3 = new QWidget();widgetCenter3->setMinimumSize(200, 100);widgetCenter3->setStyleSheet("background-color: rgb(255, 174, 201);");dockWidgetCenter->tabWidget()->addTab(widgetCenter3, "第三页Center");// 测试右侧停靠窗体QWHDockWidget *dockWidget2 = QWHTabWidgetMask::getInstance()->createDockWidget(QWHDockWidget::Mode_Minor, "总tab2");splitter->addWidget(dockWidget2);dockWidget2->setFloating(false);QWidget *widget12 = new QWidget();widget12->setMinimumSize(200, 100);widget12->setStyleSheet("background-color: gray;");dockWidget2->tabWidget()->addTab(widget12, "第一页2");QWidget *widget22 = new QWidget();widget22->setMinimumSize(200, 100);widget22->setStyleSheet("background-color: gray;");dockWidget2->tabWidget()->addTab(widget22, "第二页2");QWidget *widget32 = new QWidget();widget32->setMinimumSize(200, 100);widget32->setStyleSheet("background-color: gray;");dockWidget2->tabWidget()->addTab(widget32, "第三页2");QWHTabWidgetMask::getInstance()->setMainSplitter(splitter);
}

Qt模仿VS停靠窗口(一)相关推荐

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

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

  2. Qt(三)窗口分割、停靠、堆叠

    文章目录 一.窗口分割 QSplitter 二.窗口停靠 QDockWidget 三.窗口堆叠 QStackedWidget 演示实例: 创建QMainWindow应用, 无UI文件 一.窗口分割 Q ...

  3. QT--QDockWidget 停靠窗口

    #include "mainwindow.h" #include<QDockWidget> #include<QTextEdit> MainWindow:: ...

  4. Qt5之布局管理之分割窗口、停靠窗口、堆栈窗口

    一.分割窗口 效果图 分割窗口功能的实现非常简单,这里通过代码实现分割窗口,效果图如下: 代码及说明 #include "QtWidgetsApplication1.h" #inc ...

  5. 【QT】QT从零入门教程(六):QDockWidget停靠窗口

    QDockWidget   上节我们引出了QDockWidget的概念,这节进行讲解并加以引用.   常用函数:   1.addDockWidget:添加停靠控件,用于指定或更改停靠控件的位置以及方向 ...

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

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

  7. QT:停靠窗口(拥有自动合并分离的功能)

    1-停靠窗口(拥有自动合并分离的功能)                                       2-停靠窗口一般可以和 工具栏一起使用达到更好的联动效果(停靠窗口有方法可以直接返回 ...

  8. PyQt主窗体设置停靠窗口(QDockWidget)的叠加顺序

    PyQt提供了方便的停靠窗口控件,我们可以很方便的编写一个停靠窗口,代码和效果如下: # -*- coding: utf-8 -*- from PyQt4 import QtGui, QtCore c ...

  9. Qt应用程序主窗口之一:主窗口框架

    对于日常见到的应用程序而言,许多都是基于主窗口的,主窗口中包含了菜单栏.工具栏.状态栏和中心区域等.这一章会详细介绍主窗口的每一个部分,还会涉及资源管理.富文本处理.拖放操作和文档打印等相关内容.重点 ...

最新文章

  1. Everest 0.6 设置ADSL上网
  2. scala函数的定义语法说明
  3. pod 的亲和性,反亲和性 实验
  4. mysql常用快速查询修改操作
  5. RedMonk 2020 年 Q3 编程语言排行:Python力压Java和PHP,Rust 首次进入前 20
  6. 微软计划Windows 7 SP2开发
  7. Spring+springmvc+hibernate+redis整合配置文件
  8. 在ubuntu下使用搜狗的教育网代理
  9. IPFS(DRAFT 3) 中文版白皮书
  10. Java如何调用webservice
  11. 分析日志的工具: 日志易
  12. C语言--指针实现字符串逆序输出
  13. 【算法系列】-开根号
  14. matlab人脸识别样本库建立,facenet 人脸识别(二)——创建人脸库搭建人脸识别系统...
  15. 请问,我要去工商局申请一个工作室,法律上需要那些流程
  16. BigDecimal和DecimalFormat
  17. 老板、方太、美的们决战洗碗机“中国化”的新拐点
  18. 云栖科技评论第8期:美国五大科技巨头联手组建“AI联合国”
  19. 到底什么是大数据?新手学习大数据的路径是什么?
  20. idea批量替换一个变量(不同类也能实现)

热门文章

  1. 夏盈盈:4.18主流货币牛市合约交易游刃有余,玩波段怎么看支撑和压力是否有效...
  2. 超时空的爱情--胡彦斌
  3. PDF如何添加注释?怎样免费给PDF添加注释?
  4. vue项目安装使用 Ant Design 和 sass
  5. 通过银行卡号解析银行名称和卡别
  6. 2021年:金三银四最强悍的 js 面试题
  7. Java基础 精短强悍 学习笔记
  8. com QueryInterface
  9. 华为系统鸿蒙3.0,华为鸿蒙操作系统正式发布!引起沸腾!速看
  10. 面试题: Docker的优缺点