Qt:DockWidget自动停靠窗口,自定义标题栏,自由布局

@Qt实现自动停靠窗口 替代QDockWidget,自定义标题栏,可隐藏,可停靠

  1. 可支持windows和linux平台,资源下载只提供了windows版本
  2. 支持Qt5.12.10,支持Qt6.0以上版本,更低版本未测试编译
  3. MinGW7.3.0编译
  4. 浮动时拖动停靠功能未实现,觉得没啥用
  5. 双击标题栏,浮动窗口,Tabbed状态时,双击标签浮动窗口,双击标题栏还原
  6. QSS控制样式,可在测试程序中截获QSS代码,自行改变风格。
  7. 可用于QDialog或QWidget中
  8. 不可用于商业软件。
  9. 有可能开源。

MainWindow.h

#include <QMainWindow>
#include "DockManager.h"
#include "DockTheme.h"

class TestWidget :public QWidget
{
    Q_OBJECT
public:
    TestWidget(QWidget *parent = nullptr):QWidget(parent){};

public:
    virtual void resizeEvent(QResizeEvent *event);
};

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    
    void test3();
    void test4();

private slots:
    void on_actionTest1_triggered();
    void on_actionTest2_triggered();
    void on_actionTest3_triggered();

protected:
    void updateTheme();

private:
    Ui::MainWindow *ui;

    DockManager *dockManager;
    DockWidget *dock1;
    DockWidget *dock2;
    DockWidget *dock3;
    DockWidget *dock4;
    DockWidget *dock5;
    DockWidget *dock6;
    DockWidget *dock7;
    DockWidget *dock8;
    DockWidget *dock9;
    DockWidget *dock10;
    DockWidget *dock11;
    DockWidget *dock12;
    DockWidget *dockFloat;

    DockTheme m_dockTheme;
};

MainWindow.cpp

#include "ui_MainWindow.h"
#include "DockManager.h"

#include <QFile>
#include <QDir>
#include <QTextEdit>
#include <QDebug>

#include <QMdiArea>
#include <QLayout>

#include <QToolBar>
#include <QCheckBox>
#include <QResizeEvent>


void TestWidget::resizeEvent(QResizeEvent *event)
{
    //测试dock时,centralWidget是否resize
    qDebug() << "TestWidget::resizeEvent" << event->size() << event->oldSize() << this->size();
    QWidget::resizeEvent(event);
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , dockManager(new DockManager)
{

    ui->setupUi(this);
    setAttribute(Qt::WA_StyledBackground, true);
    updateTheme();

    setCentralWidget(dockManager->widget());
    //dockManager->setCentralWidget(new QMdiArea);
    //dockManager->setCentralWidget(new QTextEdit);
    dockManager->setCentralWidget(new TestWidget);

    dockFloat = dockManager->createDock(QIcon(":/image/res/palette.png"),"dockFloat",dockNone);
    dockFloat->setWidget(new QTextEdit("dockFloat"));
    //dockFloat->setFloat(this);
    dockFloat->setFloat(dockManager->widget());

    //测试1
//    test1();
//    测试2
//    test2();
//    //测试3
//    test3();
//    //测试4
    test4();

    QToolBar *toolBar = new QToolBar;
    addToolBar(Qt::TopToolBarArea,toolBar);
    toolBar->setMovable(false);

    QCheckBox * ckb_dock1 = new QCheckBox("Dock1");
    toolBar->addWidget(ckb_dock1);
    ckb_dock1->setChecked(dock1->isVisible());
    connect(ckb_dock1, &QCheckBox::clicked, this,[=](bool checked) {
        dock1->setVisible(checked);
    });
    connect(dock1,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dock1->isChecked()==isVisible) return;
        ckb_dock1->setChecked(isVisible);
    });

    QCheckBox * ckb_dock2 = new QCheckBox("Dock2");
    toolBar->addWidget(ckb_dock2);
    ckb_dock2->setChecked(dock2->isVisible());
    connect(ckb_dock2, &QCheckBox::clicked, this,[=](bool checked) {
        dock2->setVisible(checked);
    });
    connect(dock2,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dock2->isChecked()==isVisible) return;
        ckb_dock2->setChecked(isVisible);
    });

    QCheckBox * ckb_dock3 = new QCheckBox("Dock3");
    toolBar->addWidget(ckb_dock3);
    ckb_dock3->setChecked(dock3->isVisible());
    connect(ckb_dock3, &QCheckBox::clicked, this,[=](bool checked) {
        dock3->setVisible(checked);
    });
    connect(dock3,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dock3->isChecked()==isVisible) return;
        ckb_dock3->setChecked(isVisible);
    });

    QCheckBox * ckb_dock4 = new QCheckBox("Dock4");
    toolBar->addWidget(ckb_dock4);
    ckb_dock4->setChecked(dock4->isVisible());
    connect(ckb_dock4, &QCheckBox::clicked, this,[=](bool checked) {
        dock4->setVisible(checked);
    });
    connect(dock4,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dock4->isChecked()==isVisible) return;
        ckb_dock4->setChecked(isVisible);
    });

    QCheckBox * ckb_dock5 = new QCheckBox("Dock5");
    toolBar->addWidget(ckb_dock5);
    ckb_dock5->setChecked(dock5->isVisible());
    connect(ckb_dock5, &QCheckBox::clicked, this,[=](bool checked) {
        dock5->setVisible(checked);
    });
    connect(dock5,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dock5->isChecked()==isVisible) return;
        ckb_dock5->setChecked(isVisible);
    });

    QCheckBox * ckb_dock6 = new QCheckBox("Dock6");
    toolBar->addWidget(ckb_dock6);
    ckb_dock6->setChecked(dock6->isVisible());
    connect(ckb_dock6, &QCheckBox::clicked, this,[=](bool checked) {
        dock6->setVisible(checked);
    });
    connect(dock6,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dock6->isChecked()==isVisible) return;
        ckb_dock6->setChecked(isVisible);
    });

    QCheckBox * ckb_dock7 = new QCheckBox("Dock7");
    toolBar->addWidget(ckb_dock7);
    ckb_dock7->setChecked(dock7->isVisible());
    connect(ckb_dock7, &QCheckBox::clicked, this,[=](bool checked) {
        dock7->setVisible(checked);
    });
    connect(dock7,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dock7->isChecked()==isVisible) return;
        ckb_dock7->setChecked(isVisible);

    });

    QCheckBox * ckb_dock8 = new QCheckBox("Dock8");
    toolBar->addWidget(ckb_dock8);
    ckb_dock8->setChecked(dock8->isVisible());
    connect(ckb_dock8, &QCheckBox::clicked, this,[=](bool checked) {
        dock8->setVisible(checked);
    });
    connect(dock8,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dock8->isChecked()==isVisible) return;
        ckb_dock8->setChecked(isVisible);
    });

    QCheckBox * ckb_dock9 = new QCheckBox("Dock9");
    toolBar->addWidget(ckb_dock9);
    ckb_dock9->setChecked(dock9->isVisible());
    connect(ckb_dock9, &QCheckBox::clicked, this,[=](bool checked) {
        dock9->setVisible(checked);
    });
    connect(dock9,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dock9->isChecked()==isVisible) return;
        ckb_dock9->setChecked(isVisible);
    });

    QCheckBox * ckb_dock110 = new QCheckBox("Dock10");
    toolBar->addWidget(ckb_dock110);
    ckb_dock110->setChecked(dock10->isVisible());
    connect(ckb_dock110, &QCheckBox::clicked, this,[=](bool checked) {
        dock10->setVisible(checked);
    });
    connect(dock10,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dock110->isChecked()==isVisible) return;
        ckb_dock110->setChecked(isVisible);
    });

    QCheckBox * ckb_dock11 = new QCheckBox("Dock11");
    toolBar->addWidget(ckb_dock11);
    ckb_dock11->setChecked(dock11->isVisible());
    connect(ckb_dock11, &QCheckBox::clicked, this,[=](bool checked) {
        dock11->setVisible(checked);
    });
    connect(dock11,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dock11->isChecked()==isVisible) return;
        ckb_dock11->setChecked(isVisible);
    });

    QCheckBox * ckb_dock12 = new QCheckBox("Dock12");
    toolBar->addWidget(ckb_dock12);
    ckb_dock12->setChecked(dock12->isVisible());
    connect(ckb_dock12, &QCheckBox::clicked, this,[=](bool checked) {
        dock12->setVisible(checked);
    });
    connect(dock12,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dock12->isChecked()==isVisible) return;
        ckb_dock12->setChecked(isVisible);
    });

    QCheckBox * ckb_dockFloat = new QCheckBox("DockFloat");
    toolBar->addWidget(ckb_dockFloat);
    ckb_dockFloat->setChecked(true);
    connect(ckb_dockFloat, &QCheckBox::clicked, this,[=](bool checked) {
        dockFloat->setVisible(checked);
    });
    connect(dockFloat,&DockWidget::sg_visible,this,[=](bool isVisible){
        if(ckb_dockFloat->isChecked()==isVisible) return;
        ckb_dockFloat->setChecked(isVisible);
    });

    //setGeometry(QApplication::desktop()->availableGeometry());
    showMaximized();
    //setWindowState(Qt::WindowMaximized);
}
void MainWindow::test3()
{
    dock1 = dockManager->createDock(QIcon(":/image/res/openfile.png"),"DOCK1",dockLeft);
    dock1->setWidget(new QTextEdit("dock1"));

    dock2= new DockWidget(QIcon(":/image/res/palette.png"),"DOCK2");
    dock2->setWidget(new QTextEdit("dock2"));
    dockManager->tabifyDock(dock1,dock2);

    dock3 = dockManager->createDock(QIcon(":/image/res/openfile.png"),"DOCK3",dockLeft);
    dock3->setWidget(new QTextEdit("dock3"));

    dock4= new DockWidget(QIcon(":/image/res/palette.png"),"DOCK4");
    dock4->setWidget(new QTextEdit("dock4"));
    dockManager->tabifyDock(dock1,dock4);

    dock5 = dockManager->createDock(QIcon(":/image/res/openfile.png"),"DOCK5",dockLeft);
    dock5->setWidget(new QTextEdit("dock5"));

    dock6 = dockManager->createDock(QIcon(":/image/res/openfile.png"),"DOCK6",dockRight);
    dock6->setWidget(new QTextEdit("dock6"));

    dock7= new DockWidget(QIcon(":/image/res/palette.png"),"DOCK7");
    dock7->setWidget(new QTextEdit("dock7"));

    dock8= new DockWidget(QIcon(":/image/res/openfile.png"),"DOCK8");
    dock8->setWidget(new QTextEdit("dock8"));

    dockManager->tabifyDock(dock6,dock8);
    dockManager->splitDock(dock5,dock7,Qt::Vertical);

    dock9 = dockManager->createDock(QIcon(":/image/res/palette.png"),"DOCK9",dockTop);
    dock9->setWidget(new QTextEdit("dock9"));

    dock10 = dockManager->createDock(QIcon(":/image/res/openfile.png"),"DOCK10",dockBottom);
    dock10->setWidget(new QTextEdit("dock10"));

    dock11 = dockManager->createDock(QIcon(":/image/res/palette.png"),"DOCK11",dockBottom);
    dock11->setWidget(new QTextEdit("dock11"));;

    dock12=dockManager->createDock(QIcon(":/image/res/openfile.png"),"DOCK12",dockBottom);
    dock12->setWidget(new QTextEdit("dock12"));
}
void MainWindow::test4()
{
    dock1 = new DockWidget(QIcon(":/image/res/openfile.png"),"DOCK1");
    dock1->setWidget(new QTextEdit("dock1"));
    dockManager->addDock(dockLeft,dock1);

    dock2= new DockWidget(QIcon(":/image/res/palette.png"),"DOCK2");
    dock2->setWidget(new QTextEdit("dock2"));
    dockManager->tabifyDock(dock1,dock2);

    dock3= new DockWidget(QIcon(":/image/res/openfile.png"),"DOCK3");
    dock3->setWidget(new QTextEdit("dock3"));
    dockManager->addDock(dockLeft,dock3);

    dock4= new DockWidget(QIcon(":/image/res/palette.png"),"DOCK4");
    dock4->setWidget(new QTextEdit("dock4"));
    dockManager->tabifyDock(dock1,dock4);

    dock5= new DockWidget(QIcon(":/image/res/palette.png"),"DOCK5");
    dockManager->addDock(dockRight,dock5);
    dock5->setWidget(new QTextEdit("dock5"));

    dock6= new DockWidget(QIcon(":/image/res/openfile.png"),"DOCK6");
    dockManager->addDock(dockRight,dock6);
    dock6->setWidget(new QTextEdit("dock6"));


    dock7= new DockWidget(QIcon(":/image/res/palette.png"),"DOCK7");
    dock7->setWidget(new QTextEdit("dock7"));
    dock8= new DockWidget(QIcon(":/image/res/openfile.png"),"DOCK8");
    dock8->setWidget(new QTextEdit("dock8"));

    dockManager->tabifyDock(dock6,dock8);
    dockManager->splitDock(dock5,dock7,Qt::Vertical);

    dock9= new DockWidget(QIcon(":/image/res/openfile.png"),"DOCK9");
    dockManager->addDock(dockTop,dock9);
    dock9->setWidget(new QTextEdit("dock9"));

    dock10= new DockWidget(QIcon(":/image/res/openfile.png"),"DOCK10");
    dockManager->addDock(dockBottom,dock10);
    dock10->setWidget(new QTextEdit("dock10"));

    dock11= new DockWidget(QIcon(":/image/res/palette.png"),"DOCK11");
    dockManager->addDock(dockBottom,dock11);
    dock11->setWidget(new QTextEdit("dock11"));;

    dock12= new DockWidget(QIcon(":/image/res/palette.png"),"DOCK12");
    dockManager->addDock(dockBottom,dock12);
    dock12->setWidget(new QTextEdit("dock12"));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actionTest1_triggered()
{
    dock1->setPinned(3);
}


void MainWindow::on_actionTest2_triggered()
{
    dock10->setPinned(3);
}

void MainWindow::on_actionTest3_triggered()
{
    dock10->setPinned(2);
}

void MainWindow::updateTheme()
{
    QString sf= ":/style/res/default.qss";
    QFile file(sf);
    if (file.exists()) {
        file.open(QFile::ReadOnly);
        QString styleSheet = qApp->styleSheet();
        styleSheet +=tr(file.readAll());
        styleSheet += "QTextEdit{border:none;}";
        qApp->setStyleSheet(styleSheet);
        file.close();
    }
    m_dockTheme.setTheme();
}

图片1
在这里插入图片描述
图片2
在这里插入图片描述
图片3
在这里插入图片描述
资源下载地址https://download.csdn.net/download/dy2017/87606110

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值