Qt模仿Visual Studio停靠窗口效果

前言

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

效果图

功能

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_OBJECT
public:
	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模仿Visual Studio停靠窗口效果的文章就介绍到这了,更多相关Qt停靠窗口 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • PyQT5实现选项卡窗口、堆栈窗口、停靠窗口、子窗口

    一.选项卡控件QTabWidget import sys # 使用调色板等 from PyQt5.QtGui import QIcon # 导入QT,其中包含一些常量,例如颜色等 # 导入常用组件 from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QTabWidget from PyQt5.QtWidgets import QFormLayout, QLineEdit,QLabel from PyQt5.QtGui i

  • Qt模仿Visual Studio停靠窗口效果

    前言 众所周知,停靠窗口可以实现任意拖动效果,本文重点在于如何利用Qt制作与Visual Studio相似的带有停靠方向标及停靠区域预览的的停靠窗口框架. 效果图 功能 1.鼠标在中间方向标:叠加窗口2.鼠标在上下左右方向标:分割目标窗口,并紧挨着目标窗口周边位置添加新窗口3.鼠标在内部最上下左右方向标:目标窗口所在的最上下左右位置添加新窗口4.鼠标在外部最上下左右方向标:程序主窗口的最上下左右位置添加新窗口5.鼠标在Tab位置上:在当前所在tab页位置插入新窗口6.鼠标在Tab最右侧位置上:在

  • windows下安装QT及visual studio 2017搭建开发环境

    1.环境搭建 这里并不是说qt必须要和visual studio结合使用,不过用习惯了visual studio开发,继续使用可节省开发时间,并大大提供便利性. 关于安装过程这里不再详细赘述,软件下载链接如下: visual studio:https://www.visualstudio.com/zh-hans/downloads/ QT:http://download.qt.io/archive/qt/(这里推荐安装最新的,原因是vs2017不支持一些老版本的makefile文件生成,这个在文

  • Qt模仿实现文字浮动字母的效果

    目录 前沿 功能实现 定时器操作 文本偏移实现 控件自绘 总结 前沿 最近可能是小视频着魔了,尤其是动画字幕效果的,身为一名技术开发人员,当然是想试一试了,哪怕只是简单的移动也是可以的~ 这不,说干就干拿起来我的C++语言就要尝试,还好使用的Qt框架,这样是使用MFC框架写小demo,真的好困难呀! 先来看一看我实现的效果吧~ 效果很简单就是文本向上移动,在移动过程中文字整体变大或缩小. 那么,我就来讲解下我是如何实现的吧! 功能实现 在实现这个文本移动的效果过程中,用到了以下几个功能: 1:定

  • Visual Studio IDE编写程序时不显示窗口或窗口一闪而逝的解决方法

    使用Visual Studio IDE编写程序时不显示窗口,或窗口一闪而逝,遇到这个问题并不是你的代码出错了,而是IDE本身的设置问题,所以不用总是纠结自己代码哪里写错了. 例如写了一个这样的程序: #include "iostream" using namespace std; int main(int argc, char *argv[]) { cout << "hello world!" << endl; return 0; } 下面提

  • Visual Studio 2019配置qt开发环境的搭建过程

    宇宙第一IDE Visual Studio 配置 Qt 开发环境

  • Visual Studio快速开发以及Visual Studio 2010新功能介绍

    1.快捷命令: 复制代码 代码如下: "devenv" 启动相应版本的 Visual Studio "Inetmgr" IIS 管理器,不用到管理里去找了,很快就可以显示 IIS管理了 2.集成开发环境(IDE) 复制代码 代码如下: vs2010 的 IDE 已经过重新设计,提高了可性读. 为了减少杂乱,不必要的行和渐变都已删除 安装Visual Studio 后第一次加载需要选择默认的集成开发环境 (IDE),根据项目选择,一般选Visual C#开发, 如果在

  • Visual Studio Debugger七个鲜为人知的小功能

    Visual Studio debugger是一个很棒的调试工具,可以帮助程序猿们快速地发现和解决问题.这里给大家简单介绍一下VS调试工具中的七个鲜为人知的小功能. 1. 一键跳转到指定语句 调试过程中经常需要拖拽黄箭头,使特定语句执行或者不执行.常规方法就是使用鼠标直接拖拽. 在Visual Studio 2017 15.3预览版中,有一个更简单地跳转到目标行的方法:在目标行盘旋鼠标指针,出现绿色竖线右箭头图标后,按住CTRL后鼠标左键点击,就把调试黄箭头移过去了,再点击调试下一步或者F5就直

  • 分享Visual Studio原生开发的10个调试技巧(2)

    之前关于Visual Studio调试技巧的文章引起了大家很大的兴趣,以至于我决定分享更多调试的知识.以下的列表中你可以看到写原生开发的调试技巧(接着以前的文章来编号).这些技巧可以应用在VS2005或者更新版本中(当然有一些可以适用于旧版本).如果你继续,你可以知道每个技巧的详细信息. 技巧11:数据断点 当数据所在内存位置变化时,调试器将会中断.然而,这是唯一可能在一个时间创建4这样的硬件的数据断点.数据断点只能在编译的过程中添加,可以通过菜单(编译>新断点>新数据断点)或者通过断点窗口来

  • 积累Visual Studio 常用快捷键的动画演示

    在程序开发过程中,如何会使用键盘来完成所有的操作,会提高开发的速度.所以说,灵活的掌握并应用visual studio 的键盘快捷键非常重要. 为了便于日后查看,我根据使用的效果分成这么几块:代码编辑.查找与替换.代码美化.代码导航.Visual Studio 窗口和调试,并在最后提供修改默认快捷键的方法.同时,在参考了资源[2]的文章后,发现使用动画演示不仅直观而且更方便于日后回忆,因此也尝试用 Gif 录制软件为快捷键配上了动画演示. 本文所介绍的快捷方式适用于 C#.对于其它语言的使用者,

  • 在Visual Studio上构建C++的GUI框架wxWidgets的开发环境

    本文使用的Unicode+DLL+Debug的方式,因为不想最后生成的exe文件太大. 环境搭建步骤如下: 1.下载wxWidgets包: 登录wxWidgets的下载页面:http://www.wxwidgets.org/downloads 下载最新的Stable Release稳定版,我这里用旧的2.8.12版作演示. 2.将wxMSW-2.8.12.zip解压到D盘根目录下. 转到D:\wxMSW-2.8.12\build\msw目录,用VS2005打开wx.dsw,会有提示转换项目: 选

随机推荐