Qt自定义标题栏


Qt添加自定义标题栏

原文基础上稍加改动,使之更适用于项目

新建mytitle类,定义代码如下

mytitle.h

#ifndef _MyTitleBar_H_
#define _MyTitleBar_H_

#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QTimer>
#include <QDesktopWidget>
#include <QApplication>


//设置标题字体样式
struct struTitleStyle
{
    int title_height = 60;      // 标题栏高度;
    int btn_height = 30;        // 按钮高度;
    int btn_width = 30;         // 按钮宽度;

    QString family = "Microsoft YaHei"; // 字体
    int FontSize = 18;                  // 字体大小(单位:px)
    QColor color = qRgb(0, 0, 0);       // 字体颜色
    bool Bold = false;                  // 字体加粗
};

class MyTitleBar : public QWidget
{
    Q_OBJECT

public:
    MyTitleBar(QWidget *parent);
    // 这里parent没有给默认值NULL,保证在创建MyTitleBar对象时父指针必须得赋值;且赋值不为NULL;
    ~MyTitleBar();

    // 设置标题栏样式
    void setTitleStyle(struTitleStyle &struTitleStyle);
    // 设置标题栏背景色及是否设置标题栏背景色透明;
    void setBackgroundColor(int r, int g, int b , bool isTransparent = false);
    // 设置标题栏图标,默认图标大小为30px×30px
    void setTitleIcon(QString filePath , QSize IconSize = QSize(30 , 30));
    // 设置标题字体样式
    void setFontStyle();
    // 设置标题内容
    void setTitleContent(QString titleContent="Title" );
    // 设置标题栏长度;
    void setTitleWidth(int width);
    // 设置窗口边框宽度;
    void setWindowBorderWidth(int borderWidth = 0);
    // 设置只有关闭按钮可见
    bool setCloseButton();
    // 设置是否启用双击最大化功能,默认false
    void setMouseDoubleClick(bool b = false);

    // 保存/获取 最大化前窗口的位置及大小;
    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();

private slots:
    // 按钮触发的槽;
    void onButtonMinClicked();
    void onButtonRestoreClicked();
    void onButtonMaxClicked();
    void onButtonCloseClicked();

private:
    struTitleStyle m_struTitleStyle;    // 标题栏样式
    QLabel *m_pIcon;                    // 标题栏图标;
    QLabel *m_pTitleContent;            // 标题栏内容;
    QPushButton *m_pButtonMin;          // 最小化按钮;
    QPushButton *m_pButtonRestore;      // 最大化还原按钮;
    QPushButton *m_pButtonMax;          // 最大化按钮;
    QPushButton *m_pButtonClose;        // 关闭按钮;

    // 标题栏背景色;
    int m_colorR;
    int m_colorG;
    int m_colorB;

    // 最大化,最小化变量;
    QPoint m_restorePos;
    QSize m_restoreSize;
    // 移动窗口的变量;
    bool m_isPressed;
    QPoint m_startMovePos;
    // 标题栏内容;
    QString m_titleContent;
    // 窗口边框宽度;
    int m_windowBorderWidth;
    // 标题栏是否透明;
    bool m_isTransparent;
    // 是否启用双击最大化
    bool m_mouseDoubleClickEvent;
};

#endif

mytitle.cpp

#include "mytitlebar.h"
#include <QHBoxLayout>
#include <QPainter>
#include <QFile>
#include <QMouseEvent>


MyTitleBar::MyTitleBar(QWidget *parent)
    : QWidget(parent)
    , m_colorR(192)
    , m_colorG(192)
    , m_colorB(192)
    , m_isPressed(false)
    , m_windowBorderWidth(0)
    , m_isTransparent(true)
{
    // 初始化;
    initControl();
    initConnections();
    m_pButtonRestore->setVisible(false);
}

MyTitleBar::~MyTitleBar()
{

}

/***********************************************************************
Function:    // setTitleStyle

Description: // 设置标题栏样式

Return:      // void
************************************************************************/
void MyTitleBar::setTitleStyle(struTitleStyle &struTitleStyle)
{
    m_struTitleStyle = struTitleStyle;
}

// 初始化控件;
void MyTitleBar::initControl()
{
    m_pIcon = new QLabel;
    m_pTitleContent = new QLabel;

    m_pButtonMin = new QPushButton;
    m_pButtonRestore = new QPushButton;
    m_pButtonMax = new QPushButton;
    m_pButtonClose = new QPushButton;

    m_pButtonMin->setFixedSize(QSize(m_struTitleStyle.btn_width, m_struTitleStyle.btn_height));
    m_pButtonRestore->setFixedSize(QSize(m_struTitleStyle.btn_width, m_struTitleStyle.btn_height));
    m_pButtonMax->setFixedSize(QSize(m_struTitleStyle.btn_width, m_struTitleStyle.btn_height));
    m_pButtonClose->setFixedSize(QSize(m_struTitleStyle.btn_width, m_struTitleStyle.btn_height));

    m_pTitleContent->setObjectName("TitleName");
    m_pButtonMin->setObjectName("ButtonMin");
    m_pButtonRestore->setObjectName("ButtonRestore");
    m_pButtonMax->setObjectName("ButtonMax");
    m_pButtonClose->setObjectName("ButtonClose");

    m_pButtonMin->setToolTip("最小化");
    m_pButtonRestore->setToolTip("还原");
    m_pButtonMax->setToolTip("最大化");
    m_pButtonClose->setToolTip("关闭");

    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);
    this->setFixedHeight(m_struTitleStyle.title_height);
    this->setWindowFlags(Qt::FramelessWindowHint);
}

// 信号槽的绑定;
void MyTitleBar::initConnections()
{
    connect(m_pButtonMin, SIGNAL(clicked()), this, SLOT(onButtonMinClicked()));
    connect(m_pButtonRestore, SIGNAL(clicked()), this, SLOT(onButtonRestoreClicked()));
    connect(m_pButtonMax, SIGNAL(clicked()), this, SLOT(onButtonMaxClicked()));
    connect(m_pButtonClose, SIGNAL(clicked()), this, SLOT(onButtonCloseClicked()));
}

// 设置标题栏背景色,在paintEvent事件中进行绘制标题栏背景色;
// 在构造函数中给了默认值,可以外部设置颜色值改变标题栏背景色;
void MyTitleBar::setBackgroundColor(int r, int g, int b, bool isTransparent)
{
    m_colorR = r;
    m_colorG = g;
    m_colorB = b;
    m_isTransparent = isTransparent;
    // 重新绘制(调用paintEvent事件);
    update();
}

// 设置标题栏图标;
void MyTitleBar::setTitleIcon(QString filePath, QSize IconSize)
{
    QPixmap titleIcon(filePath);
    m_pIcon->setPixmap(titleIcon.scaled(IconSize));
}

/***********************************************************************
Function:    // setFontStyle

Description: // 设置标题栏字体样式

Return:      // void
************************************************************************/
void MyTitleBar::setFontStyle()
{
    // 设置标题字体大小;
    QFont font = m_pTitleContent->font();
    font.setFamily(m_struTitleStyle.family);
    font.setPixelSize(m_struTitleStyle.FontSize);
    font.setBold(m_struTitleStyle.Bold);
    QPalette l_palette;
    l_palette.setColor(QPalette::WindowText, m_struTitleStyle.color);
    m_pTitleContent->setPalette(l_palette);
    m_pTitleContent->setFont(font);
}

// 设置标题内容;
void MyTitleBar::setTitleContent(QString titleContent)
{
    m_pTitleContent->setText(titleContent);
    m_titleContent = titleContent;
    setFontStyle();
}

// 设置标题栏长度;
void MyTitleBar::setTitleWidth(int width)
{
    this->setFixedWidth(width);
}

// 设置窗口边框宽度;
void MyTitleBar::setWindowBorderWidth(int borderWidth)
{
    m_windowBorderWidth = borderWidth;
}

/***********************************************************************
Function:    // setCloseButton

Description: // 设置只有关闭按钮可见

Return:      // bool
************************************************************************/
bool MyTitleBar::setCloseButton()
{
    m_pButtonMin->setVisible(false);
    m_pButtonRestore->setVisible(false);
    m_pButtonMax->setVisible(false);
    return true;
}

/***********************************************************************
Function:    // setMouseDoubleClick

Description: // 设置是否启用双击最大化

Return:      // bool
************************************************************************/
void MyTitleBar::setMouseDoubleClick(bool b)
{
    m_mouseDoubleClickEvent = b;
}

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

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

// 绘制标题栏背景色;
void MyTitleBar::paintEvent(QPaintEvent *event)
{
    // 是否设置标题透明;
    if (!m_isTransparent)
    {
        //设置背景色;
        QPainter painter(this);
        QPainterPath pathBack;
        pathBack.setFillRule(Qt::WindingFill);
        pathBack.addRoundedRect(QRect(0, 0, this->width(), this->height()), 3, 3);
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.fillPath(pathBack, QBrush(QColor(m_colorR, m_colorG, m_colorB)));
    }

    // 当窗口最大化或者还原后,窗口长度变了,标题栏的长度应当一起改变;
    // 这里减去m_windowBorderWidth ,是因为窗口可能设置了不同宽度的边框;
    // 如果窗口有边框则需要设置m_windowBorderWidth的值,否则m_windowBorderWidth默认为0;
    if (this->width() != (this->parentWidget()->width() - m_windowBorderWidth))
    {
        this->setFixedWidth(this->parentWidget()->width() - m_windowBorderWidth);
    }
    QWidget::paintEvent(event);
}

// 双击响应事件,主要是实现双击标题栏进行最大化和最小化操作;
void MyTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
    // 判断是否启用双击最大化功能,默认false
    if(m_mouseDoubleClickEvent == false)
    {
        return;
    }

    // 通过最大化按钮的状态判断当前窗口是处于最大化还是原始大小状态;
    // 或者通过单独设置变量来表示当前窗口状态;
    if (m_pButtonMax->isVisible())
    {
        onButtonMaxClicked();
    }
    else
    {
        onButtonRestoreClicked();
    }

    return QWidget::mouseDoubleClickEvent(event);
}

// 以下通过mousePressEvent、mouseMoveEvent、mouseReleaseEvent三个事件实现了鼠标拖动标题栏移动窗口的效果;
void MyTitleBar::mousePressEvent(QMouseEvent *event)
{
    // 在窗口最大化时禁止拖动窗口;
    if (m_pButtonMax->isVisible())
    {
        m_isPressed = true;
        m_startMovePos = event->globalPos();
    }
    else
    {
        m_isPressed = true;
        m_startMovePos = event->globalPos();
    }

    return QWidget::mousePressEvent(event);
}

void MyTitleBar::mouseMoveEvent(QMouseEvent *event)
{
    if (m_isPressed)
    {
        QPoint movePoint = event->globalPos() - m_startMovePos;
        QPoint widgetPos = this->parentWidget()->pos();
        m_startMovePos = event->globalPos();
        this->parentWidget()->move(widgetPos.x() + movePoint.x(), widgetPos.y() + movePoint.y());
    }
    return QWidget::mouseMoveEvent(event);
}

void MyTitleBar::mouseReleaseEvent(QMouseEvent *event)
{
    m_isPressed = false;
    return QWidget::mouseReleaseEvent(event);
}

void MyTitleBar::onButtonMinClicked()
{
    this->window()->showMinimized();
}

void MyTitleBar::onButtonRestoreClicked()
{
    QPoint windowPos;
    QSize windowSize;
    getRestoreInfo(windowPos, windowSize);
    this->window()->setGeometry(QRect(windowPos, windowSize));

    m_pButtonMax->setVisible(true);
    m_pButtonRestore->setVisible(false);
}

void MyTitleBar::onButtonMaxClicked()
{
    saveRestoreInfo(this->window()->pos(), QSize(this->window()->width(), this->window()->height()));
    QRect desktopRect = QApplication::desktop()->availableGeometry();
    QRect FactRect = QRect(desktopRect.x() - 3, desktopRect.y() - 3, desktopRect.width() + 6, desktopRect.height() + 6);
    this->window()->setGeometry(FactRect);

    m_pButtonRestore->setVisible(true);
    m_pButtonMax->setVisible(false);
}

void MyTitleBar::onButtonCloseClicked()
{
    this->window()->close();
}

widget.h添加代码

#include "Include/titlebar.h"

private:

    titlebar *m_pTitleBarMain;

widget.cpp添加代码

    titlebar::TitleInfo l_titleInfo;
    l_titleInfo.m_FontSize = 22;
    l_titleInfo.m_bkcolor = QColor(255, 255, 255);
    l_titleInfo.m_Height = 46;
    l_titleInfo.m_bmaxNeed = false;
    l_titleInfo.m_Textcolor = QColor(255, 255, 255);
    l_titleInfo.m_bminNeed = false;
    l_titleInfo.m_bcloseNeed = true;

    m_pTitleBarMain = new titlebar(nullptr, Qt::Dialog);
    l_titleInfo.m_strTitle = QStringLiteral("Mytitle");
    m_pTitleBarMain->SetTitleBarInfo(this, &l_titleInfo);
    m_pTitleBarMain->setFixedSize(1200, 820);
    m_pTitleBarMain->show();

参考文章


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM