QT: QDockWidget使用详解

QDockWidget简介

思路

  • 首先有一个主界面,用来存放每个QDockWidget
  • 根据需要写很多个QWidget。每个QWidget都有独立的 .h .cpp .ui文件
  • 槽函数: 希望把所有的子界面作为一个整体控制

代码

QMainWindow

主界面需要继承 QMainWindow
这个ui只需要一个空的界面就好
QT: QDockWidget使用详解_第1张图片

  1. QWidget1是自定义的子界面,你可以放任何需要的控件,在主界面include它的头文件
  2. 需要new一个QDockWidget ,把QWidget1加进去
  3. 最后设置排版

排版可以用splitDockWidget
田字形的排版如下:
加入第一个QDockWidget ,也就是左上角

this->addDockWidget(Qt::LeftDockWidgetArea, pDock1 );

横向扩展一个,即右上角。在第一个QDockWidget 横向插入一个QDockWidget

splitDockWidget(pDock1 , pDock2, Qt::Horizontal);

左下角

//第一竖列
splitDockWidget(pDock1 , pDock3, Qt::Vertical);

右下角

//第二竖列
splitDockWidget(pDock2, pDock4, Qt::Vertical);

整体代码如下:

h文件

#pragma once
#include 
#include
#include "ui_WidStageCtrl.h"

class WidStageCtrl :
	public QMainWindow
{
public:
	WidStageCtrl(QWidget *parent = Q_NULLPTR);
	~WidStageCtrl();

protected:
	void InitData();
	void  removeAllDock();
private:
	Ui::WidStageCtrl ui;
	QList<QDockWidget*> m_docks;//< 记录所有dockWidget的指针
};

cpp文件



WidStageCtrl::WidStageCtrl(QWidget *parent  ):QMainWindow(parent)
{
	ui.setupUi(this);
	InitData();
}
WidStageCtrl::~WidStageCtrl()
{

}


void WidStageCtrl::InitData()
{
	QDockWidget *pDock1 = new QDockWidget( QStringLiteral("界面1"));
	QWidget1*Widget1= new QWidget1(pDock1 );
	pDock1 ->setWidget(Widget1);
	m_docks.append(pDock1);

	QDockWidget *pDock2 = new QDockWidget( QStringLiteral("界面2"));
	QWidget2*Widget2= new QWidget2(pDock2 );
	pDock2 ->setWidget(Widget2);
	m_docks.append(pDock2);

	QDockWidget *pDock3 = new QDockWidget( QStringLiteral("界面3"));
	QWidget3*Widget3= new QWidget1(pDock3 );
	pDock3 ->setWidget(Widget3);
	m_docks.append(pDock3);

	QDockWidget *pDock4 = new QDockWidget( QStringLiteral("界面4"));
	QWidget4*Widget4= new QWidget4(pDock4 );
	pDock4 ->setWidget(Widget4);
	m_docks.append(pDock4);


	//初始布局
	//第一横排
	this->addDockWidget(Qt::LeftDockWidgetArea, pDock1 );
	splitDockWidget(pDock1 , pDock2, Qt::Horizontal);
	//第一竖列
	splitDockWidget(pDock1 , pDock3, Qt::Vertical);
	//第二竖列
	splitDockWidget(pDock2, pDock4, Qt::Vertical);

}


void WidStageCtrl::removeAllDock()
{
	for (int i = 0; i < m_docks.size(); ++i)
	{
		removeDockWidget(m_docks[i]);
	}
}

槽函数

这些界面虽然是分开的,但是很多操作却是关联到一起的,还有一些子界面给子界面发消息的功能。
如果我在每个界面直接处理业务逻辑的话很麻烦。
为了能统一,方便以后改代码。新建一个Signals类

#define INST_Signals Signals ::Instance()
class Signals : public QObject
{
	Q_OBJECT
 	public:
	static Signals * Instance();
	static void Close();
	private:
static Signals * m_pSingletion;
public:
	~CSignals();
}

所有的子界面的槽函数,都不直接处理业务,而是交给Signals 发送
比如:
子界面

#include "Signals.h"
void service1(QString str)
{
	INST_Signals->service1(str);
}

Signals.h 转发信号

void Signals::service1(QString str)
{
	emit service1(str);
}

主界面:

#include "Signals.h"
connect(INST_CSignals, SIGNAL(service1(QString)), this, SLOT(SLOT_service1(QString));

这样就可以在主界面统一处理了

补:单例模式的实现

 Signals* Signals::m_pSingletion = NULL;

Signals* Signals::Instance()
{
	if (m_pSingletion == NULL)
	{
		m_pSingletion = new Signals;
	}
		return m_pSingletion;
}

void Signals::Close()
{
	if (m_pSingletion != NULL)
	{
		delete m_pSingletion;
		m_pSingletion = NULL;
	}
}

还有一个思路统一处理
新建一个处理类 CtrlClass
在主界面的类里面 定义全局变量,并初始化

#include "CtrlClass.h"

CtrlClass* g_CtrlClass = NULL;

WidStageCtrl ::WidStageCtrl ()

在子界面里面使用它

extern CtrlClass* g_CtrlClass;

你可能感兴趣的:(qt,qt,c++,开发语言)