1. 程式人生 > 其它 >Qt自定義標題欄

Qt自定義標題欄

Qt新增自定義標題欄02

新建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();