1. 程式人生 > >Qt自定義標題欄詳細介紹(可拖動、放大縮小、關閉、標題欄具有漸變色)

Qt自定義標題欄詳細介紹(可拖動、放大縮小、關閉、標題欄具有漸變色)

前言

使用Qt自帶的標題欄可能沒有辦法適合我們的需求,例如標題欄的顏色,標題欄的寬度、高度,標題欄的放大、縮小、還原、關閉按鈕等都沒有辦法發生改變。因為預設的標題欄是和作業系統相關的、它會根據作業系統的變化而發生變化,在Window上不同風格的主題,在Qt程式產生的標題欄也會發生相應的變化,在linux上也是如此。而自定義標題欄則不會這樣,顏色,大小,按鈕圖示這完全有我們來控制,來達到標題欄的自由性和統一性。

/*mytitilebar.h*/
#ifndef MYTITLEBAR_H
#define MYTITLEBAR_H

#include <QWidget>
#include <QToolButton>
#include <QPixmap> #include <QLabel> #include <QColor> #include <QPainter> #include <QHBoxLayout> #include <QMouseEvent> #include <QStyle> #include <QLabel> #include <QtDebug> #include <QLinearGradient> #define ICON_WIDTH 20 #define ICON_HEIGHT 20
#define BUTTON_WIDTH 30 #define BUTTON_HEIGHT 30 #define TITLE_HEIGHT 30 class myTitleBar : public QWidget { Q_OBJECT public: myTitleBar(QWidget *parent); void SetTitleBackground(QColor Color); // 供外部呼叫設定標題欄背景 void SetTitleContent(QString content); // ……………設定標題欄內容 void SetTitleIcon(QString iconPath); // ……………設定標題欄圖示
public slots: void ShowSmall(); //槽函式,最小化 void ShowMaxRestore(); // 槽函式 ,最大化或者還原 protected: void mousePressEvent(QMouseEvent *e); // 滑鼠點選事件 void mouseMoveEvent(QMouseEvent *e); // 滑鼠移動事件 void mouseDoubleClickEvent(QMouseEvent *e); // 滑鼠雙擊事件 private: void InitTitleBar(); // 初始化標題欄 void paintEvent(QPaintEvent *event); // 過載繪畫函式 QToolButton *m_Minimize; // 最小化按鈕 QToolButton *m_Maximize; // 最大化按鈕 QToolButton *m_Close; // 關閉按鈕 QPixmap *m_RestorePix; // 還原按鈕的圖片 QPixmap *m_MaxPix; // 最大化按鈕的圖片 QPixmap *m_MinPix; // 最小化按鈕的圖片 QPoint m_StartPos; // 記錄視窗開始的位置 QPoint m_ClickPos; QLabel *m_TitleIcon; // 標題欄圖示 QLabel *m_TitleConten; // 標題欄標題 QLabel m_TitleLabel; QColor m_ColorL; // 標題欄漸變色 QColor m_ColorR; // 標題欄漸變色 QWidget *m_Parent; //父窗體 }; #endif // MYTITLEBAR_H
/*************************************************************************/
//File name:    mytitlebar.cpp
//Date:         2017.10.23
//Description:  自定義標題欄
/*************************************************************************/

#include "mytitlebar.h"

myTitleBar::myTitleBar(QWidget *parent):m_ColorL(QColor(0,0,0)),
m_ColorR(QColor(255,255,255)) // 初始化漸變色(白->黑漸變)
{

    this->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);  // 隱藏預設的標題欄
    m_Parent = parent;       // 獲取標題欄的父窗體,用來控制視窗放大,縮小,關閉等行為
    m_MaxNormal = false;     // 初始化視窗不是最大化狀態
    InitTitleBar();          // 初始化標題欄

    // 連線標題欄三個按鈕到相應的槽函式中
    connect(m_Close, SIGNAL( clicked() ), m_Parent, SLOT(close() ));
    connect(m_Minimize, SIGNAL( clicked() ), this, SLOT(ShowSmall() ) );
    connect(m_Maximize, SIGNAL( clicked() ), this, SLOT(ShowMaxRestore() ) );
}


void myTitleBar::InitTitleBar()
{

    m_Close= new QToolButton(this);                              // 關閉按鈕
    m_ClosePix  = new QPixmap(":/icon/close.png");               // 關閉按鈕圖片
    m_Close->setIcon(*m_ClosePix);
    m_Close->setToolTip("關閉");                                   // 顯示提示文字
    m_Close->setIconSize(QSize(ICON_WIDTH,ICON_HEIGHT));         // 設定圖片的大小
    m_Close->setFixedSize(m_ClosePix->size());                   // 設定按鈕大小為圖片的大小
    m_Close->setStyleSheet("border-style:flat");                 // 設定按鈕背景透明

    m_Maximize = new QToolButton(this);                          // 最大化按鈕
    m_MaxPix  = new QPixmap(":/icon/scale.png");
    m_RestorePix  = new QPixmap(":/icon/scale.png");
    m_Maximize->setIcon(*m_MaxPix);
    m_Maximize->setToolTip("最大化");
    m_Maximize->setIconSize(QSize(ICON_WIDTH,ICON_HEIGHT));
    m_Maximize->setFixedSize(m_MaxPix->size());
    m_Maximize->setStyleSheet("border-style:flat");

    m_Minimize = new QToolButton(this);                         // 最小化按鈕
    m_MinPix  = new QPixmap(":/icon/mi.png");
    m_Minimize->setIcon(*m_MinPix);
    m_Minimize->setToolTip("最小化");
    m_Minimize->setIconSize(QSize(ICON_WIDTH,ICON_HEIGHT));
    m_Minimize->setFixedSize(m_MinPix->size());
    m_Minimize->setStyleSheet("border-style:flat");

    m_TitleConten = new QLabel(this);                          // 標題欄文字
    QFont TitleFont; 
    TitleFont.setPointSize(12);
    m_TitleConten->setFont(TitleFont);
    m_TitleConten->setText(tr("自定義標題欄"));

    m_TitleIcon = new QLabel(this);                            // 標題欄左上角圖示
    m_TitleIcon->setPixmap(QPixmap(":/icon/icon.png"));


    QHBoxLayout *hbox = new QHBoxLayout(this);           // 新建水平容器,把所有控制元件放在容器中
    hbox->addWidget(m_TitleIcon);
    hbox->addWidget(m_TitleConten);
    hbox->addWidget(m_Minimize);
    hbox->addWidget(m_Maximize);
    hbox->addWidget(m_Close);

    hbox->setSpacing(5);                      // 設定容器的屬性,標題欄高度等
    hbox->setContentsMargins(5, 2, 5, 2);
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    this->setFixedHeight(TITLE_HEIGHT);
    this->setStyleSheet("border-style:flat");
    setAttribute(Qt::WA_TranslucentBackground);

}

/*用於重新繪製標題欄,當外部呼叫了設定標題欄相關屬性的函式時呼叫*/
void myTitleBar::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    QLinearGradient linearGradient(QPointF(0, 0), QPointF(0, this->height()));

    // 設定漸變的顏色,如果m_ColorL和m_ColorR相同時為純色,而不是漸變色
    linearGradient.setColorAt(0, m_ColorL);  
    linearGradient.setColorAt(1, m_ColorR);

    linearGradient.setSpread(QGradient::ReflectSpread);
    painter.setBrush(linearGradient);
    QPen pen(m_Color);
    painter.setPen(pen);
    QPainterPath pathBack;                 // 先在QPainterPath畫圖,再用QPainter顯示出來
    pathBack.setFillRule(Qt::WindingFill);
    pathBack.addRoundedRect(QRect(0, 0, this->width(), this->height()), 0, 0);

}

// 最小化
void myTitleBar::ShowSmall()
{
    parentWidget()->showMinimized();
}

//最大化/還原
void myTitleBar::ShowMaxRestore()
{
    if (m_MaxNormal) {
        parentWidget()->showNormal();
        m_MaxNormal = !m_MaxNormal;
        m_Maximize->setToolTip("最大化");
        m_Maximize->setIcon(*m_MaxPix);
    } else {
        parentWidget()->showMaximized();
        m_Maximize->setToolTip("向下還原");
        m_MaxNormal = !m_MaxNormal;
        m_Maximize->setIcon(*m_RestorePix);
    }
}

// 當滑鼠點選了標題欄,記錄下當時的位置
void myTitleBar::mousePressEvent(QMouseEvent *e)
{
    m_StartPos = e->globalPos();
    m_ClickPos = mapToParent(e->pos());
}

// 滑鼠移動
void myTitleBar::mouseMoveEvent(QMouseEvent *e)
{
    if (m_MaxNormal)  // 如果處於最大化狀態,則不能移動
        return;
    parentWidget()->move(e->globalPos() - m_ClickPos);
}

// 雙擊滑鼠左鍵和放大按鈕效果一致
void myTitleBar::mouseDoubleClickEvent(QMouseEvent *e)
{
    if(e->button() == Qt::LeftButton)
    {
        ShowMaxRestore();
    }
}



//設定標題欄的漸變色
void myTitleBar::SetTitleBackground(QColor ColorL,QColor ColorR )
{
    m_ColorL = ColorL;
    m_ColorR = ColorR;

    update();     // 通知更改,系統自動條用PainterEvent()函式
}


// 設定標題欄顯示的文字
void myTitleBar::SetTitleContent(QString content)
{
    m_TitleConten->setText(content);
}

// 設定標題欄左上角的圖示
void myTitleBar::SetTitleIcon(QString iconPath)
{
    QPixmap map(iconPath);
    m_TitleIcon->setPixmap(map);

}

自定義標題欄的程式碼如上所示,但是上面的程式碼不能直接執行喲。這裡只是給出了自定義標題欄的程式碼,具體驗證的也挺簡單的,新建一個類,把預設的標題欄隱藏,直接new出來我們自定義的標題欄
myTitleBar *title = new myTitleBar(this),然後通過move函式把,title放在視窗的最上面就可以了。這樣自定義標題欄就完成了。