Qt模仿Visual?Studio??看翱谛Ч?/h1>
更新時(shí)間:2022年01月13日 15:56:15 作者:浮生卍流年
這篇文章主要介紹了如何利用Qt制作與Visual?Studio相似的帶有??糠较驑?biāo)及停靠區(qū)域預(yù)覽的??看翱诳蚣埽疚耐ㄟ^實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
前言
眾所周知,停靠窗口可以實(shí)現(xiàn)任意拖動(dòng)效果,本文重點(diǎn)在于如何利用Qt制作與Visual Studio相似的帶有停靠方向標(biāo)及??繀^(qū)域預(yù)覽的的停靠窗口框架。
效果圖

功能
1、鼠標(biāo)在中間方向標(biāo):疊加窗口
2、鼠標(biāo)在上下左右方向標(biāo):分割目標(biāo)窗口,并緊挨著目標(biāo)窗口周邊位置添加新窗口
3、鼠標(biāo)在內(nèi)部最上下左右方向標(biāo):目標(biāo)窗口所在的最上下左右位置添加新窗口
4、鼠標(biāo)在外部最上下左右方向標(biāo):程序主窗口的最上下左右位置添加新窗口
5、鼠標(biāo)在Tab位置上:在當(dāng)前所在tab頁位置插入新窗口
6、鼠標(biāo)在Tab最右側(cè)位置上:在tab頁尾部添加新窗口
注釋:Dock停靠優(yōu)先級(jí):某些情況下,外部最上下左右方向的方向標(biāo)會(huì)和目標(biāo)窗口方向標(biāo)重疊,此時(shí)遵循 中間停靠優(yōu)于外部??俊⒎较驑?biāo)??績?yōu)于tab頁???/code>的原則。
部分頭文件
#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();
// 設(shè)置程序主窗口
void setMainWindow(QMainWindow *mainWindow);
// 創(chuàng)建??看翱?
QWHDockWidget *createDockWidget(QWHDockWidget::AreaMode areaMode, const QString &windowTitle = "");
// 創(chuàng)建分裂器(水平分裂)
QSplitter *createSplitter();
// 創(chuàng)建分裂器(由參數(shù)orientation決定分裂方向)
QSplitter *createSplitter(Qt::Orientation orientation);
// 設(shè)置程序主分裂器
void setMainSplitter(QSplitter *splitter);
// 設(shè)置目標(biāo)窗口(接收方)
void setTargetWidget(QTabWidget *widget);
// 設(shè)置當(dāng)前頁索引(鼠標(biāo)移入當(dāng)前頁 或 鼠標(biāo)移入中心方向標(biāo))
void setCurTabIndex(int index);
// 設(shè)置鼠標(biāo)按下的停靠窗口(準(zhǔn)備移動(dòng)的窗口)
void setMousePressed(QWHDockWidget *moveDockWidget);
// 設(shè)置鼠標(biāo)釋放
void setMouseReleased();
// 獲取??看翱谕扑]最小尺寸
QSize minimumSizeHint() const override;
// 獲取鼠標(biāo)按下的??看翱冢?zhǔn)備移動(dòng)或正在移動(dòng)的窗口)
QDockWidget *moveDockWidget();
// 獲取程序主分裂器
QSplitter *mainSplitter();
// 獲取程序主窗口
QMainWindow *mainWindow();
protected:
void paintEvent(QPaintEvent *event);
private:
// 獲取指定索引的邊界路徑
QPainterPath tabWidgetBorderPath(QTabWidget *tabWidget, int tabIndex);
// 繪制主??看翱诘闹甘酒?
void drawMainDockIndicator();
// 繪制次停靠窗口的指示器
void drawMinorDockIndicator();
// 檢查鼠標(biāo)所在方向標(biāo)區(qū)域
Area checkArea(QPoint globalPos);
signals:
// 創(chuàng)建??看翱?
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; // 四個(gè)方位矩形(緊挨著中心矩形)
QRect m_topMoreRect, m_rightMoreRect, m_bottomMoreRect, m_leftMoreRect; // 更加靠邊四個(gè)方位矩形(緊挨著四個(gè)方位矩形)
QRect m_topMostRect, m_rightMostRect, m_bottomMostRect, m_leftMostRect; // 最靠邊四個(gè)方向矩形(緊挨著主窗口四邊)
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;
};
測(cè)試代碼
TestVSWindow::TestVSWindow(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
QWHTabWidgetMask::getInstance()->setMainWindow(this);
// 測(cè)試左側(cè)??看绑w
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, "第三頁");
// 測(cè)試中間??看绑w
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");
// 測(cè)試右側(cè)??看绑w
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);
}
到此這篇關(guān)于Qt模仿Visual Studio??看翱谛Ч奈恼戮徒榻B到這了,更多相關(guān)Qt??看翱?內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
-
詳解C++如何實(shí)現(xiàn)在Word文檔中創(chuàng)建列表
這篇文章主要為大家詳細(xì)介紹了介紹如何使用C++在Word文檔中創(chuàng)建編號(hào)列表、項(xiàng)目符號(hào)列表和多級(jí)列表,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下 2023-05-05
-
C++實(shí)現(xiàn)LeetCode(103.二叉樹的之字形層序遍歷)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(103.二叉樹的之字形層序遍歷),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下 2021-07-07
-
OpenCV + MFC實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別
這篇文章主要為大家詳細(xì)介紹了OpenCV + MFC實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下 2019-08-08
-
基于C++實(shí)現(xiàn)的各種內(nèi)部排序算法匯總
這篇文章主要介紹了基于C++實(shí)現(xiàn)的各種內(nèi)部排序算法,非常經(jīng)典,需要的朋友可以參考下 2014-08-08
-
詳解如何配置CLion作為Qt5開發(fā)環(huán)境的方法
這篇文章主要介紹了詳解如何配置CLion作為Qt5開發(fā)環(huán)境的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧 2021-04-04
最新評(píng)論
前言
眾所周知,停靠窗口可以實(shí)現(xiàn)任意拖動(dòng)效果,本文重點(diǎn)在于如何利用Qt制作與Visual Studio相似的帶有停靠方向標(biāo)及??繀^(qū)域預(yù)覽的的停靠窗口框架。
效果圖

功能
1、鼠標(biāo)在中間方向標(biāo):疊加窗口
2、鼠標(biāo)在上下左右方向標(biāo):分割目標(biāo)窗口,并緊挨著目標(biāo)窗口周邊位置添加新窗口
3、鼠標(biāo)在內(nèi)部最上下左右方向標(biāo):目標(biāo)窗口所在的最上下左右位置添加新窗口
4、鼠標(biāo)在外部最上下左右方向標(biāo):程序主窗口的最上下左右位置添加新窗口
5、鼠標(biāo)在Tab位置上:在當(dāng)前所在tab頁位置插入新窗口
6、鼠標(biāo)在Tab最右側(cè)位置上:在tab頁尾部添加新窗口
注釋:Dock停靠優(yōu)先級(jí):某些情況下,外部最上下左右方向的方向標(biāo)會(huì)和目標(biāo)窗口方向標(biāo)重疊,此時(shí)遵循 中間停靠優(yōu)于外部??俊⒎较驑?biāo)??績?yōu)于tab頁???/code>的原則。
部分頭文件
#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();
// 設(shè)置程序主窗口
void setMainWindow(QMainWindow *mainWindow);
// 創(chuàng)建??看翱?
QWHDockWidget *createDockWidget(QWHDockWidget::AreaMode areaMode, const QString &windowTitle = "");
// 創(chuàng)建分裂器(水平分裂)
QSplitter *createSplitter();
// 創(chuàng)建分裂器(由參數(shù)orientation決定分裂方向)
QSplitter *createSplitter(Qt::Orientation orientation);
// 設(shè)置程序主分裂器
void setMainSplitter(QSplitter *splitter);
// 設(shè)置目標(biāo)窗口(接收方)
void setTargetWidget(QTabWidget *widget);
// 設(shè)置當(dāng)前頁索引(鼠標(biāo)移入當(dāng)前頁 或 鼠標(biāo)移入中心方向標(biāo))
void setCurTabIndex(int index);
// 設(shè)置鼠標(biāo)按下的停靠窗口(準(zhǔn)備移動(dòng)的窗口)
void setMousePressed(QWHDockWidget *moveDockWidget);
// 設(shè)置鼠標(biāo)釋放
void setMouseReleased();
// 獲取??看翱谕扑]最小尺寸
QSize minimumSizeHint() const override;
// 獲取鼠標(biāo)按下的??看翱冢?zhǔn)備移動(dòng)或正在移動(dòng)的窗口)
QDockWidget *moveDockWidget();
// 獲取程序主分裂器
QSplitter *mainSplitter();
// 獲取程序主窗口
QMainWindow *mainWindow();
protected:
void paintEvent(QPaintEvent *event);
private:
// 獲取指定索引的邊界路徑
QPainterPath tabWidgetBorderPath(QTabWidget *tabWidget, int tabIndex);
// 繪制主??看翱诘闹甘酒?
void drawMainDockIndicator();
// 繪制次停靠窗口的指示器
void drawMinorDockIndicator();
// 檢查鼠標(biāo)所在方向標(biāo)區(qū)域
Area checkArea(QPoint globalPos);
signals:
// 創(chuàng)建??看翱?
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; // 四個(gè)方位矩形(緊挨著中心矩形)
QRect m_topMoreRect, m_rightMoreRect, m_bottomMoreRect, m_leftMoreRect; // 更加靠邊四個(gè)方位矩形(緊挨著四個(gè)方位矩形)
QRect m_topMostRect, m_rightMostRect, m_bottomMostRect, m_leftMostRect; // 最靠邊四個(gè)方向矩形(緊挨著主窗口四邊)
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;
};測(cè)試代碼
TestVSWindow::TestVSWindow(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
QWHTabWidgetMask::getInstance()->setMainWindow(this);
// 測(cè)試左側(cè)??看绑w
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, "第三頁");
// 測(cè)試中間??看绑w
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");
// 測(cè)試右側(cè)??看绑w
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);
}到此這篇關(guān)于Qt模仿Visual Studio??看翱谛Ч奈恼戮徒榻B到這了,更多相關(guān)Qt??看翱?內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解C++如何實(shí)現(xiàn)在Word文檔中創(chuàng)建列表
這篇文章主要為大家詳細(xì)介紹了介紹如何使用C++在Word文檔中創(chuàng)建編號(hào)列表、項(xiàng)目符號(hào)列表和多級(jí)列表,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-05-05
C++實(shí)現(xiàn)LeetCode(103.二叉樹的之字形層序遍歷)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(103.二叉樹的之字形層序遍歷),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
OpenCV + MFC實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別
這篇文章主要為大家詳細(xì)介紹了OpenCV + MFC實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08
基于C++實(shí)現(xiàn)的各種內(nèi)部排序算法匯總
這篇文章主要介紹了基于C++實(shí)現(xiàn)的各種內(nèi)部排序算法,非常經(jīng)典,需要的朋友可以參考下2014-08-08
詳解如何配置CLion作為Qt5開發(fā)環(huán)境的方法
這篇文章主要介紹了詳解如何配置CLion作為Qt5開發(fā)環(huán)境的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04

