Qt模仿Visual Studio停靠窗口效果

这篇文章主要介绍了如何利用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 = "Iik7DQoJLy8g5Yib5bu65YiG6KOC5Zmo77yI5rC05bmz5YiG6KOC77yJDQoJUVNwbGl0dGVyICpjcmVhdGVTcGxpdHRlcigpOw0KCS8vIOWIm+W7uuWIhuijguWZqO+8iOeUseWPguaVsG9yaWVudGF0aW9u5Yaz5a6a5YiG6KOC5pa55ZCR77yJDQoJUVNwbGl0dGVyICpjcmVhdGVTcGxpdHRlcihRdDo6T3JpZW50YXRpb24gb3JpZW50YXRpb24pOw0KCS8vIOiuvue9rueoi+W6j+S4u+WIhuijguWZqA0KCXZvaWQgc2V0TWFpblNwbGl0dGVyKFFTcGxpdHRlciAqc3BsaXR0ZXIpOw0KCS8vIOiuvue9ruebruagh+eql+WPo++8iOaOpeaUtuaWue+8iQ0KCXZvaWQgc2V0VGFyZ2V0V2lkZ2V0KFFUYWJXaWRnZXQgKndpZGdldCk7DQoJLy8g6K6+572u5b2T5YmN6aG157Si5byV77yI6byg5qCH56e75YWl5b2T5YmN6aG1IOaIliDpvKDmoIfnp7vlhaXkuK3lv4PmlrnlkJHmoIfvvIkNCgl2b2lkIHNldEN1clRhYkluZGV4KGludCBpbmRleCk7DQoJLy8g6K6+572u6byg5qCH5oyJ5LiL55qE5YGc6Z2g56qX5Y+j77yI5YeG5aSH56e75Yqo55qE56qX5Y+j77yJDQoJdm9pZCBzZXRNb3VzZVByZXNzZWQoUVdIRG9ja1dpZGdldCAqbW92ZURvY2tXaWRnZXQpOw0KCS8vIOiuvue9rum8oOagh+mHiuaUvg0KCXZvaWQgc2V0TW91c2VSZWxlYXNlZCgpOw0KCS8vIOiOt+WPluWBnOmdoOeql+WPo+aOqOiNkOacgOWwj+WwuuWvuA0KCVFTaXplIG1pbmltdW1TaXplSGludCgpIGNvbnN0IG92ZXJyaWRlOw0KCS8vIOiOt+WPlum8oOagh+aMieS4i+eahOWBnOmdoOeql+WPo++8iOWHhuWkh+enu+WKqOaIluato+WcqOenu+WKqOeahOeql+WPo++8iQ0KCVFEb2NrV2lkZ2V0ICptb3ZlRG9ja1dpZGdldCgpOw0KCS8vIOiOt+WPlueoi+W6j+S4u+WIhuijguWZqA0KCVFTcGxpdHRlciAqbWFpblNwbGl0dGVyKCk7DQoJLy8g6I635Y+W56iL5bqP5Li756qX5Y+jDQoJUU1haW5XaW5kb3cgKm1haW5XaW5kb3coKTsNCnByb3RlY3RlZDoNCgl2b2lkIHBhaW50RXZlbnQoUVBhaW50RXZlbnQgKmV2ZW50KTsNCnByaXZhdGU6DQoJLy8g6I635Y+W5oyH5a6a57Si5byV55qE6L6555WM6Lev5b6EDQoJUVBhaW50ZXJQYXRoIHRhYldpZGdldEJvcmRlclBhdGgoUVRhYldpZGdldCAqdGFiV2lkZ2V0LCBpbnQgdGFiSW5kZXgpOw0KCS8vIOe7mOWItuS4u+WBnOmdoOeql+WPo+eahOaMh+ekuuWZqA0KCXZvaWQgZHJhd01haW5Eb2NrSW5kaWNhdG9yKCk7DQoJLy8g57uY5Yi25qyh5YGc6Z2g56qX5Y+j55qE5oyH56S65ZmoDQoJdm9pZCBkcmF3TWlub3JEb2NrSW5kaWNhdG9yKCk7DQoJLy8g5qOA5p+l6byg5qCH5omA5Zyo5pa55ZCR5qCH5Yy65Z+fDQoJQXJlYSBjaGVja0FyZWEoUVBvaW50IGdsb2JhbFBvcyk7DQpzaWduYWxzOg0KCS8vIOWIm+W7uuWBnOmdoOeql+WPow0KCXZvaWQgZG9ja1dpZGdldEFkZGVkKFFXSERvY2tXaWRnZXQgKm5ld0RvY2tXaWRnZXQpOw0KcHJpdmF0ZToNCglRTWFpbldpbmRvdyAqbV9tYWluV2luZG93Ow0KCVFTcGxpdHRlciAqbV9tYWluU3BsaXR0ZXI7DQoJUVdIRG9ja1dpZGdldCAqbV9tb3ZlRG9ja1dpZGdldDsNCglRVGFiV2lkZ2V0ICptX3RhcmdldFdpZGdldDsNCglRTGlzdCZsdDtRV0hEb2NrV2lkZ2V0IComZ3Q7IG1fbGlzdERvY2tXaWRnZXRzOw0KCWludCBtX3RhYkluZGV4Ow0KCVFDb2xvciBtX2JvcmRlckNvbG9yOw0KCVFDb2xvciBtX2JnQ29sb3I7DQoJUVJlY3QgbV9jZW50ZXJSZWN0OwkvLyDkuK3lv4Pnn6nlvaINCglRUmVjdCBtX3RvcFJlY3QsIG1fcmlnaHRSZWN0LCBtX2JvdHRvbVJlY3QsIG1fbGVmdFJlY3Q7CS8vIOWbm+S4quaWueS9jeefqeW9ou+8iOe0p+aMqOedgOS4reW/g+efqeW9ou+8iQ0KCVFSZWN0IG1fdG9wTW9yZVJlY3QsIG1fcmlnaHRNb3JlUmVjdCwgbV9ib3R0b21Nb3JlUmVjdCwgbV9sZWZ0TW9yZVJlY3Q7CS8vIOabtOWKoOmdoOi+ueWbm+S4quaWueS9jeefqeW9ou+8iOe0p+aMqOedgOWbm+S4quaWueS9jeefqeW9ou+8iQ0KCVFSZWN0IG1fdG9wTW9zdFJlY3QsIG1fcmlnaHRNb3N0UmVjdCwgbV9ib3R0b21Nb3N0UmVjdCwgbV9sZWZ0TW9zdFJlY3Q7CS8vIOacgOmdoOi+ueWbm+S4quaWueWQkeefqeW9ou+8iOe0p+aMqOedgOS4u+eql+WPo+Wbm+i+ue+8iQ0KCVFQaXhtYXAgbV9jZW50ZXJQaXhtYXA7DQoJUVBpeG1hcCBtX3RvcFBpeG1hcCwgbV9yaWdodFBpeG1hcCwgbV9ib3R0b21QaXhtYXAsIG1fbGVmdFBpeG1hcDsNCglRUGl4bWFwIG1fdG9wTW9zdFBpeG1hcCwgbV9yaWdodE1vc3RQaXhtYXAsIG1fYm90dG9tTW9zdFBpeG1hcCwgbV9sZWZ0TW9zdFBpeG1hcDsNCglRUGl4bWFwIG1fY2VudGVyUGl4bWFwSG92ZXI7DQoJUVBpeG1hcCBtX3RvcFBpeG1hcEhvdmVyLCBtX3JpZ2h0UGl4bWFwSG92ZXIsIG1fYm90dG9tUGl4bWFwSG92ZXIsIG1fbGVmdFBpeG1hcEhvdmVyOw0KCVFQaXhtYXAgbV90b3BNb3N0UGl4bWFwSG92ZXIsIG1fcmlnaHRNb3N0UGl4bWFwSG92ZXIsIG1fYm90dG9tTW9zdFBpeG1hcEhvdmVyLCBtX2xlZnRNb3N0UGl4bWFwSG92ZXI7DQp9OzwvY29kZT48L3ByZT48L2Rpdj4NCjxoMj7mtYvor5Xku6PnoIE8L2gyPg0KPGRpdiBjbGFzcz0="topstudy">
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停靠窗口 内容请搜索编程学习网以前的文章希望大家以后多多支持编程学习网!

本文标题为:Qt模仿Visual Studio停靠窗口效果