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();
}
运行效果:
可以拖动,也可以最大化和最小化