当前位置: 首页 > news >正文

Qt中如何从头到尾自定义设计一个标题栏

使用qt的widget自定义设计标题栏

头文件TitleBar.h

#pragma once

#include <QWidget>
#include<QLabel>
#include<QPushButton>

enum ButtonType
{
    MIN_BUTTON = 0,
    MIN_MAX_BUTTON,
    ONLY_CLOSE_BUTTON
};

class TitleBar  : public QWidget
{
	Q_OBJECT

public:
	TitleBar(QWidget *parent = nullptr);
	~TitleBar();


    void setTitleIcon(QString& filePath);//设置标题栏图标
    void setTitleContent(QString& titleContent);//设置标题栏内容
    void setTitleWidth(int width);
    void setButtonType(ButtonType buttonType);//设置标题栏中的按钮类型;

    //保存、获取窗口最大化前的窗口的位置及大小
    void saveRestoreInfo(const QPoint& point, const QSize& size);
    void getRestoreInfo(QPoint& point, QSize& size);


private:
    void paintEvent(QPaintEvent* event);
    void mouseDoubleClickEvent(QMouseEvent* event);
    void mousePressEvent(QMouseEvent* event);
    void mouseMoveEvent(QMouseEvent* event);
    void mouseReleaseEvent(QMouseEvent* event);

    void initControl();//初始化控件
    void initConnections();//初始化信号与槽的连接
    void loadStyleSheet(const QString& sheetName);//加载样式表


signals:
    //按钮发射的信号
    void signalButtonMinClicked();//最小化按钮
    void signalButtonRestoreClicked();//最大化还原按钮
    void signalButtonMaxClicked();//最大化按钮
    void signalButtonCloseClicked();//关闭按钮

private slots:
    void onButtonMinClicked();
    void onButtonRestoreClicked();
    void onButtonMaxClicked();
    void onButtonCloseClicked();

private:
    QLabel* m_pIcon;
    QLabel* m_pTitleContent;
    QPushButton* m_pButtonMin;
    QPushButton* m_pButtonRestore;//还原
    QPushButton* m_pButtonMax;
    QPushButton* m_pButtonClose;

    //最大化还原按钮变量 (用于保存窗体位置及大小)   
    QPoint m_restorePos;
    QSize m_restoreSize;

    //移动窗口的变量
    bool m_isPressed;
    QPoint m_startMovePos;
    QString m_titleContent;
    ButtonType m_buttonType;
};

实现:TitleBar.cpp

#include "TitleBar.h"
#include <QHBoxLayout>
#include<Qpainter>
#include<QMouseEvent>
#define BUTTON_HEIGHT 27
#define BUTTON_WIDTH 27
#define TITLE_HEIGHT 27

TitleBar::TitleBar(QWidget* parent)
	: QWidget(parent)
	, m_isPressed(false)
	, m_buttonType(MIN_MAX_BUTTON)
{
	initControl();
	initConnections();
	loadStyleSheet("Title");

}

TitleBar::~TitleBar()
{}

void TitleBar::initControl()
{
	m_pIcon = new QLabel(this);
	m_pTitleContent = new QLabel(this);

	m_pButtonMin = new QPushButton(this);
	m_pButtonRestore = new QPushButton(this);
	m_pButtonMax = new QPushButton(this);
	m_pButtonClose = new QPushButton(this);

	m_pButtonMin->setFixedSize(QSize(BUTTON_WIDTH,BUTTON_HEIGHT));
	m_pButtonRestore->setFixedSize(QSize(BUTTON_WIDTH, BUTTON_HEIGHT));
	m_pButtonMax->setFixedSize(QSize(BUTTON_WIDTH, BUTTON_HEIGHT));
	m_pButtonClose->setFixedSize(QSize(BUTTON_WIDTH, BUTTON_HEIGHT));

	//设置对象名
	m_pTitleContent->setObjectName("TitleContent");
	m_pButtonMin->setObjectName("ButtonMin");
	m_pButtonRestore->setObjectName("ButtonRestore");
	m_pButtonMax->setObjectName("ButtonMax");
	m_pButtonClose->setObjectName("ButtonClose");


	//设置布局
	QHBoxLayout* mylayout = new QHBoxLayout(this);
	mylayout->addWidget(m_pIcon);
	mylayout->addWidget(m_pTitleContent);

	mylayout->addWidget(m_pButtonMin);
	mylayout->addWidget(m_pButtonRestore);
	mylayout->addWidget(m_pButtonMax);
	mylayout->addWidget(m_pButtonClose);

	mylayout->setContentsMargins(5, 0, 0, 0);
	mylayout->setSpacing(0);

	m_pTitleContent->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

	setFixedHeight(TITLE_HEIGHT);
	setWindowFlags(Qt::FramelessWindowHint);//窗体无边框

}

void TitleBar::initConnections()
{
	connect(m_pButtonMin, SIGNAL(clicked()), this, SLOT(onButtonMinCliked()));
	connect(m_pButtonRestore, SIGNAL(clicked()), this, SLOT(onButtonRestoreClicked()));
	connect(m_pButtonMax, SIGNAL(clicked()), this, SLOT(onButtonMaxClicked()));
	connect(m_pButtonClose, SIGNAL(clicked()), this, SLOT(onButtonCloseClicked()));
}

void TitleBar::setTitleIcon(QString &filePath)
{
	QPixmap titleIcon(filePath);
	m_pIcon->setFixedSize(titleIcon.size());
	m_pIcon->setPixmap(titleIcon);
}

void TitleBar::setTitleContent(QString& titleContent)
{
	m_pTitleContent->setText(titleContent);
	m_titleContent = titleContent;
}

void TitleBar::setTitleWidth(int width)
{
	setFixedWidth(width);
}

void TitleBar::setButtonType(ButtonType buttontype)
{
	m_buttonType = buttontype;
		switch (buttontype)
		{
		case MIN_BUTTON:
		{
			m_pButtonRestore->setVisible(false);
			m_pButtonMax->setVisible(false);
		}
		break;
		case MIN_MAX_BUTTON:
		{
			m_pButtonRestore->setVisible(false);

		}
		break;
		case ONLY_CLOSE_BUTTON:
		{
			m_pButtonRestore->setVisible(false);
			m_pButtonMax->setVisible(false);
			m_pButtonMin->setVisible(false);
		}
		break;
		default:
			break;
		}
}

//保存最大化窗口前窗口的位置以及大小
void TitleBar::saveRestoreInfo(const QPoint& point, const QSize& size)
{
	m_restorePos = point;
	m_restoreSize = size;
 }

//获取最大化窗口前窗口的位置以及大小
void TitleBar::getRestoreInfo(QPoint& point, QSize& size)
{
	point = m_restorePos;
	size = m_restoreSize;
}

//绘制标题栏	
void TitleBar::paintEvent(QPaintEvent* event)
{   
	//设置背景色
	QPainter painter(this); 
	QPainterPath pathBack;
	pathBack.setFillRule(Qt::WindingFill);//设置填充规则
	pathBack.addRoundedRect(QRect(0,0,width(),height()),3,3); //添加圆角矩形到绘图路径
	painter.setRenderHint(QPainter::SmoothPixmapTransform, true);

	//当窗口最大化或还原后,窗口长度改变,标题栏相应做出改变
   //parentWidget()返回父部件
	if (width() != parentWidget()->width())
	{
		setFixedWidth(parentWidget()->width());
	}
}

//双击响应事件,实现双击标题栏进行最大化和最小化的操作
void TitleBar::mouseDoubleClickEvent(QMouseEvent* event)
{
	if (m_buttonType == MIN_MAX_BUTTON)
	{
		if (m_pButtonMax->isVisible())
			onButtonMaxClicked();
		else
			onButtonRestoreClicked();
	}

	return QWidget::mouseDoubleClickEvent(event);
}

//通过鼠标按下,鼠标移动,鼠标释放实现拖动标题栏移动窗口
void TitleBar::mousePressEvent(QMouseEvent* event)
{
	if (m_buttonType == MIN_MAX_BUTTON)
	{
		if (m_pButtonMax->isVisible())
		{

			m_isPressed = true;
			m_startMovePos = event->globalPos();//globalPos()会返回事件发生时鼠标在全局的位置
		}
	}
	else
	{
		m_isPressed = true;
		m_startMovePos = event->globalPos();
	}
	return QWidget::mousePressEvent(event);
}

void TitleBar::mouseMoveEvent(QMouseEvent* event)
{
	if (m_isPressed)
	{
		QPoint movePoint = event->globalPos() - m_startMovePos;
		QPoint widgetPos = parentWidget()->pos();//获取当前父窗口的位置
		m_startMovePos = event->globalPos();
		parentWidget()->move(widgetPos.x() + movePoint.x(), widgetPos.y() + movePoint.y());//移动父窗口
	}
	return QWidget::mouseMoveEvent(event);
}

void TitleBar::mouseReleaseEvent(QMouseEvent* event)
{
	m_isPressed = false;
	return QWidget::mouseReleaseEvent(event);//这个事件在当前对象中处理完,剩下的操作由父类完成
}

//加载样式表
void TitleBar::loadStyleSheet(const QString& sheetName)
{
	QFile file(":/Resources/QSS" + sheetName + ".css");
	file.open(QFile::ReadOnly);
	if (file.isOpen())
	{
		QString styleSheet = this->styleSheet();
		styleSheet += QLatin1String(file.readAll());
		setStyleSheet(styleSheet);
	}
}

void TitleBar::onButtonMinClicked()
{
	emit signalButtonMinClicked();
}

void TitleBar::onButtonRestoreClicked()
{
	m_pButtonRestore->setVisible(false);
	m_pButtonMax->setVisible(true);
	emit signalButtonRestoreClicked();
}

void TitleBar::onButtonMaxClicked()
{ 
	m_pButtonMax->setVisible(false);
	m_pButtonRestore->setVisible(true);
		emit signalButtonMaxClicked();
}

void TitleBar::onButtonCloseClicked()
{
	emit signalButtonCloseClicked();
}

运行效果:

可以拖动,也可以最大化和最小化

相关文章:

  • libcoap在Ubuntu下的编译(基于CMake)
  • Exoplayer2源码编译FFmpeg拓展模块实现音频软解码
  • 深度探索:直击服务器权限获取之旅
  • 快速开始React开发(一)
  • 车载测试:智能座舱测试中多屏联动与语音交互的挑战
  • OpenMCU(一):STM32F407 FreeRTOS移植
  • OpenHarmony定制子系统
  • SQL Server查询计划操作符(7.3)——查询计划相关操作符(8)
  • 预测 38 种成分与 X 蛋白的结合活性,并构建 GCN(图卷积网络)与 Transformer 双模型进行交叉验证的大致步骤
  • 企业工程项目管理系统源码:Java版源码解析
  • 扣子(Coze):重构AI时代的工作流革命
  • 利用Ollama+AnythingLLM+本地向量数据库Milvus+本地DeepSeek大模型实现知识库的搭建
  • Docker基础-自定义镜像与容器网络
  • 【MySQL】(3) 数据类型
  • 韩国互联网巨头 NAVER 如何借助 StarRocks 实现实时数据洞察
  • 【系统架构设计师】软件架构的重要性
  • STM32——串口通信 UART
  • Gartner:数据安全平台DSP提升数据流转及使用安全
  • 大白话css第九章主要聚焦于前沿技术整合、生态贡献与技术传承
  • 一文了解Conda使用
  • 用上海注册的公司建的网站/广告公司推广方案
  • 怀柔网站整站优化公司/网站注册流程
  • 企业网站备案怎么做/百度快照没有了用什么代替了
  • 拓者设计吧电脑版/seo网页优化平台
  • 东莞网站建设案例/建站推广
  • 公司flash网站模板/汕尾网站seo