前言
众所周知,停靠窗口可以实现任意拖动效果,c/c++开发分享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停靠窗口 内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!
需要了解更多c/c++开发分享Qt模仿Visual Studio停靠窗口效果,都可以关注C/C++技术分享栏目—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/1038057.html