Qt自定義按鈕及不同狀態(tài)下圖片的切換

    好久沒有使用Qt了,最近在做窗體時(shí)做了一個(gè)自定義的鈕銨,剛開始是想通過修改其MASK和ICON的
方式來實(shí)現(xiàn)。確發(fā)現(xiàn)效果總是不太如意,如是干脆自已定義了一個(gè)XPushButton。也將其實(shí)現(xiàn)方式記錄發(fā)
布出來。以方便日后自已使用和給有相應(yīng)問題的朋友一個(gè)小小的提示。
    為了實(shí)現(xiàn)任意形狀的窗體和保留QPushButton的特性,繼承QPushButton創(chuàng)建一個(gè)子類。

class QtXPushButton : public QPushButton
{
    Q_OBJECT

public:
    QtXPushButton(QString strImagePath, QWidget *parent = NULL);
    ~QtXPushButton();
}

    為了方便描述按鈕正常、鼠標(biāo)滑動(dòng)、選取狀態(tài)、禁止點(diǎn)擊狀態(tài)定義一個(gè)狀態(tài)枚舉。

成都創(chuàng)新互聯(lián)是一家專注于網(wǎng)站制作、成都網(wǎng)站制作與策劃設(shè)計(jì),翼城網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:翼城等地區(qū)。翼城做網(wǎng)站價(jià)格咨詢:18980820575

//按鈕狀態(tài)
enum XBUTTONSTATE
{
    NORMAL = 0X01,//正常狀態(tài)
    HOVER = 0X02,//鼠標(biāo)滑過狀態(tài)
    SELECTED = 0X04,//選中狀態(tài)
    DISABLE = 0X08//禁止點(diǎn)擊狀態(tài)
};

為了方便設(shè)置個(gè)程狀態(tài)的圖標(biāo),添加狀態(tài)圖標(biāo)設(shè)置接口,并設(shè)置一個(gè)標(biāo)識(shí)表明設(shè)置了哪些狀態(tài)。

//設(shè)置正常圖標(biāo)
void SetNormalPixmap(QString strImagePath);
//設(shè)置鼠標(biāo)滑動(dòng)圖片
void SetHoverPixmap(QString strImagePath);
//設(shè)置選中狀態(tài)圖片
void SetSelectedPixmap(QString strImagePath);
//設(shè)置禁止點(diǎn)擊圖標(biāo)
void SetDisablePixmap(QString strImagePath);
//設(shè)置按鈕當(dāng)前狀態(tài)

void SetBtnState(XBUTTONSTATE state);
//設(shè)置圖片大小
 void SetSize(QSize sz);

    至此一個(gè)具有設(shè)置正常、鼠標(biāo)滑動(dòng)、選中、禁止點(diǎn)擊功能的按鈕的接口就定義好了。這個(gè)子類的最終定義如下。

#pragma once

#include <QPushButton>
#include <QString>
#include <QWidget>
#include <QPixmap>

//按鈕狀態(tài)
enum XBUTTONSTATE
{
    NORMAL = 0X01,//正常狀態(tài)
    HOVER = 0X02,//鼠標(biāo)滑過狀態(tài)
    SELECTED = 0X04,//選中狀態(tài)
    DISABLE = 0X08//禁止點(diǎn)擊狀態(tài)
};

class QtXPushButton : public QPushButton
{
    Q_OBJECT

public:
    QtXPushButton(QString strImagePath, QWidget *parent = NULL);
    ~QtXPushButton();

    //設(shè)置正常圖標(biāo)
    void SetNormalPixmap(QString strImagePath);
    //設(shè)置鼠標(biāo)滑動(dòng)圖片
    void SetHoverPixmap(QString strImagePath);
    //設(shè)置選中狀態(tài)圖片
    void SetSelectedPixmap(QString strImagePath);
    //設(shè)置禁止點(diǎn)擊圖標(biāo)
    void SetDisablePixmap(QString strImagePath);
    //設(shè)置按鈕當(dāng)前狀態(tài)
    void SetBtnState(XBUTTONSTATE state);
    //設(shè)置圖片大小
    void SetSize(QSize sz);

protected:
    virtual void paintEvent(QPaintEvent *event);
    virtual void enterEvent(QEvent *event);
    virtual void leaveEvent(QEvent *event);



private:
    QtXPushButton(const QtXPushButton& btn);
    QtXPushButton& operator=(const QtXPushButton& btn);

private:
    QPixmap m_NormalPix;//正常圖標(biāo)
    QPixmap m_HoverPix;//鼠標(biāo)滑動(dòng)圖標(biāo)
    QPixmap m_SelectedPix;//選中狀態(tài)圖標(biāo)
    QPixmap m_DisablePix;//禁止點(diǎn)擊圖標(biāo)
    int m_iMask;//包含1則啟動(dòng)正常圖標(biāo),包含2啟用滑動(dòng)圖標(biāo),包含4啟用選中狀態(tài)圖標(biāo),包含8啟用禁止點(diǎn)擊圖標(biāo),默認(rèn)標(biāo)為1.
    XBUTTONSTATE m_curState;//當(dāng)前狀態(tài)
    XBUTTONSTATE m_lastState;//上一次狀態(tài)
};

    接下來實(shí)現(xiàn)其相應(yīng)功能。實(shí)現(xiàn)一個(gè)不規(guī)則的窗體大至需要做兩個(gè)動(dòng)作。

(1)通過REGON或者M(jìn)ASK確定其邊框,在構(gòu)造函數(shù)中添加如下代碼:

QtXPushButton::QtXPushButton(QString strImagePath, QWidget *parent)
    :QPushButton(parent)
{
    m_NormalPix.load(strImagePath);
    resize(m_NormalPix.size());
    setMask(QBitmap(m_NormalPix.mask()));
    m_iMask = XBUTTONSTATE::NORMAL;
    m_curState = XBUTTONSTATE::NORMAL;
    m_lastState = XBUTTONSTATE::NORMAL;
}

(2)在窗體繪制時(shí)將圖片繪制于其上,重載其繪圖函數(shù),添加如下代碼。

void QtXPushButton::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.drawPixmap(0, 0, m_NormalPix);
}

        上面兩個(gè)步驟可以實(shí)現(xiàn)一個(gè)任意規(guī)則的自定義窗體,其下來實(shí)現(xiàn)其在不同狀態(tài)下的圖片的切換。

設(shè)置不同狀態(tài)的圖片,這里以鼠標(biāo)滑動(dòng)方式為例。由于鼠標(biāo)進(jìn)入窗體區(qū)域后就應(yīng)當(dāng)設(shè)置為鼠標(biāo)滑動(dòng)狀態(tài),重載窗體的鼠標(biāo)進(jìn)入和鼠標(biāo)離開區(qū)域來監(jiān)測(cè)其狀態(tài)。

//設(shè)置鼠標(biāo)滑動(dòng)圖片
void QtXPushButton::SetHoverPixmap(QString strImagePath)
{
    m_HoverPix.load(strImagePath);
    m_iMask |= XBUTTONSTATE::HOVER;
}

//重載鼠標(biāo)進(jìn)入和移出事件

void QtXPushButton::enterEvent(QEvent *event)
{
    SetBtnState(XBUTTONSTATE::HOVER);
    QPushButton::enterEvent(event);
    update();
}

void QtXPushButton::leaveEvent(QEvent *event)
{
    m_curState = m_lastState;
    QPushButton::leaveEvent(event);
    update();
}

//用指定圖片重繪窗體

void QtXPushButton::paintEvent(QPaintEvent *event)
{
    QPixmap drawPix;

    if (m_curState == XBUTTONSTATE::NORMAL)
    {
        drawPix = m_NormalPix;
    }
    else if (m_curState == XBUTTONSTATE::HOVER)
    {
        int iValue = m_iMask&XBUTTONSTATE::HOVER;
        drawPix = (0 == iValue) ? m_NormalPix : m_HoverPix;
    }
    else if (m_curState == XBUTTONSTATE::SELECTED)
    {
        int iValue = m_iMask&XBUTTONSTATE::SELECTED;
        drawPix = (0 == iValue) ? m_NormalPix : m_SelectedPix;
    }
    else if (m_curState == XBUTTONSTATE::DISABLE)
    {
        int iValue = m_iMask&XBUTTONSTATE::DISABLE;
        drawPix = (0 == iValue) ? m_NormalPix : m_DisablePix;
    }

    QPainter painter(this);
    painter.drawPixmap(0, 0, drawPix);
}

        經(jīng)過上述過程鼠標(biāo)進(jìn)入按鈕區(qū)域,按鈕會(huì)顯示HOVER圖片。鼠標(biāo)移出按鈕區(qū)域,按鈕會(huì)顯示鼠標(biāo)進(jìn)入之前的狀態(tài)。

程序完全源碼如下:

#include "QtXPushButton.h"
#include <QBitmap>
#include <QPainter>

QtXPushButton::QtXPushButton(QString strImagePath, QWidget *parent)
    :QPushButton(parent)
{
    m_NormalPix.load(strImagePath);
    resize(m_NormalPix.size());
    setMask(QBitmap(m_NormalPix.mask()));
    m_iMask = XBUTTONSTATE::NORMAL;
    m_curState = XBUTTONSTATE::NORMAL;
    m_lastState = XBUTTONSTATE::NORMAL;
}

QtXPushButton::~QtXPushButton()
{
}

//設(shè)置正常圖標(biāo)
void QtXPushButton::SetNormalPixmap(QString strImagePath)
{
    m_NormalPix.load(strImagePath);
    m_iMask |= XBUTTONSTATE::NORMAL;
}

//設(shè)置鼠標(biāo)滑動(dòng)圖片
void QtXPushButton::SetHoverPixmap(QString strImagePath)
{
    m_HoverPix.load(strImagePath);
    m_iMask |= XBUTTONSTATE::HOVER;
}

//設(shè)置選中狀態(tài)圖片
void QtXPushButton::SetSelectedPixmap(QString strImagePath)
{
    m_SelectedPix.load(strImagePath);
    m_iMask |= XBUTTONSTATE::SELECTED;
}

//設(shè)置禁止點(diǎn)擊圖標(biāo)
void QtXPushButton::SetDisablePixmap(QString strImagePath)
{
    m_DisablePix.load(strImagePath);
    m_iMask |= XBUTTONSTATE::DISABLE;
}

//設(shè)置按鈕當(dāng)前狀態(tài)
void QtXPushButton::SetBtnState(XBUTTONSTATE state)
{
    m_lastState = m_curState;
    m_curState = state;
}

//設(shè)置圖片大小
void QtXPushButton::SetSize(QSize sz)
{
    m_NormalPix = m_NormalPix.scaled(sz);
    int iValue = m_iMask&XBUTTONSTATE::HOVER;

    if (iValue != 0)
    {
        m_HoverPix = m_HoverPix.scaled(sz);
    }

    iValue = m_iMask&XBUTTONSTATE::SELECTED;

    if (iValue != 0)
    {
        m_SelectedPix = m_SelectedPix.scaled(sz);
    }

    iValue = m_iMask&XBUTTONSTATE::DISABLE;

    if (iValue != 0)
    {
        m_DisablePix = m_DisablePix.scaled(sz);
    }
}

void QtXPushButton::paintEvent(QPaintEvent *event)
{
    QPixmap drawPix;

    if (m_curState == XBUTTONSTATE::NORMAL)
    {
        drawPix = m_NormalPix;
    }
    else if (m_curState == XBUTTONSTATE::HOVER)
    {
        int iValue = m_iMask&XBUTTONSTATE::HOVER;
        drawPix = (0 == iValue) ? m_NormalPix : m_HoverPix;
    }
    else if (m_curState == XBUTTONSTATE::SELECTED)
    {
        int iValue = m_iMask&XBUTTONSTATE::SELECTED;
        drawPix = (0 == iValue) ? m_NormalPix : m_SelectedPix;
    }
    else if (m_curState == XBUTTONSTATE::DISABLE)
    {
        int iValue = m_iMask&XBUTTONSTATE::DISABLE;
        drawPix = (0 == iValue) ? m_NormalPix : m_DisablePix;
    }

    QPainter painter(this);
    painter.drawPixmap(0, 0, drawPix);
}

void QtXPushButton::enterEvent(QEvent *event)
{
    SetBtnState(XBUTTONSTATE::HOVER);
    QPushButton::enterEvent(event);
    update();
}

void QtXPushButton::leaveEvent(QEvent *event)
{
    m_curState = m_lastState;
    QPushButton::leaveEvent(event);
    update();
}

文章標(biāo)題:Qt自定義按鈕及不同狀態(tài)下圖片的切換
文章起源:http://muchs.cn/article24/pppeje.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)Google、品牌網(wǎng)站制作建站公司、域名注冊(cè)用戶體驗(yàn)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)