@Qt实现自动停靠窗口 替代QDockWidget,自定义标题栏,可隐藏,可停靠
- 可支持windows和linux平台,资源下载只提供了windows版本
- 支持Qt5.12.10,支持Qt6.0以上版本,更低版本未测试编译
- MinGW7.3.0编译
- 浮动时拖动停靠功能未实现,觉得没啥用
- 双击标题栏,浮动窗口,Tabbed状态时,双击标签浮动窗口,双击标题栏还原
- QSS控制样式,可在测试程序中截获QSS代码,自行改变风格。
- 可用于QDialog或QWidget中
- 不可用于商业软件。
- 有可能开源。
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.youkuaiyun.com/download/dy2017/87606110
由于工作变动,代码不小心搞丢了,计划年底之前再实现一版,这个版本主要采用QSplitter类,下一个版本很可能是采用layout类实现