您好,登錄后才能下訂單哦!
好久沒有使用Qt了,最近在做窗體時做了一個自定義的鈕銨,剛開始是想通過修改其MASK和ICON的 方式來實現(xiàn)。確發(fā)現(xiàn)效果總是不太如意,如是干脆自已定義了一個XPushButton。也將其實現(xiàn)方式記錄發(fā) 布出來。以方便日后自已使用和給有相應問題的朋友一個小小的提示。 為了實現(xiàn)任意形狀的窗體和保留QPushButton的特性,繼承QPushButton創(chuàng)建一個子類。 class QtXPushButton : public QPushButton { Q_OBJECT public: QtXPushButton(QString strImagePath, QWidget *parent = NULL); ~QtXPushButton(); }
為了方便描述按鈕正常、鼠標滑動、選取狀態(tài)、禁止點擊狀態(tài)定義一個狀態(tài)枚舉。
//按鈕狀態(tài)
enum XBUTTONSTATE
{
NORMAL = 0X01,//正常狀態(tài)
HOVER = 0X02,//鼠標滑過狀態(tài)
SELECTED = 0X04,//選中狀態(tài)
DISABLE = 0X08//禁止點擊狀態(tài)
};
為了方便設置個程狀態(tài)的圖標,添加狀態(tài)圖標設置接口,并設置一個標識表明設置了哪些狀態(tài)。
//設置正常圖標
void SetNormalPixmap(QString strImagePath);
//設置鼠標滑動圖片
void SetHoverPixmap(QString strImagePath);
//設置選中狀態(tài)圖片
void SetSelectedPixmap(QString strImagePath);
//設置禁止點擊圖標
void SetDisablePixmap(QString strImagePath);
//設置按鈕當前狀態(tài)
void SetBtnState(XBUTTONSTATE state);
//設置圖片大小
void SetSize(QSize sz);
至此一個具有設置正常、鼠標滑動、選中、禁止點擊功能的按鈕的接口就定義好了。這個子類的最終定義如下。
#pragma once
#include <QPushButton>
#include <QString>
#include <QWidget>
#include <QPixmap>
//按鈕狀態(tài)
enum XBUTTONSTATE
{
NORMAL = 0X01,//正常狀態(tài)
HOVER = 0X02,//鼠標滑過狀態(tài)
SELECTED = 0X04,//選中狀態(tài)
DISABLE = 0X08//禁止點擊狀態(tài)
};
class QtXPushButton : public QPushButton
{
Q_OBJECT
public:
QtXPushButton(QString strImagePath, QWidget *parent = NULL);
~QtXPushButton();
//設置正常圖標
void SetNormalPixmap(QString strImagePath);
//設置鼠標滑動圖片
void SetHoverPixmap(QString strImagePath);
//設置選中狀態(tài)圖片
void SetSelectedPixmap(QString strImagePath);
//設置禁止點擊圖標
void SetDisablePixmap(QString strImagePath);
//設置按鈕當前狀態(tài)
void SetBtnState(XBUTTONSTATE state);
//設置圖片大小
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;//正常圖標
QPixmap m_HoverPix;//鼠標滑動圖標
QPixmap m_SelectedPix;//選中狀態(tài)圖標
QPixmap m_DisablePix;//禁止點擊圖標
int m_iMask;//包含1則啟動正常圖標,包含2啟用滑動圖標,包含4啟用選中狀態(tài)圖標,包含8啟用禁止點擊圖標,默認標為1.
XBUTTONSTATE m_curState;//當前狀態(tài)
XBUTTONSTATE m_lastState;//上一次狀態(tài)
};
接下來實現(xiàn)其相應功能。實現(xiàn)一個不規(guī)則的窗體大至需要做兩個動作。
(1)通過REGON或者MASK確定其邊框,在構(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ù),添加如下代碼。
void QtXPushButton::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawPixmap(0, 0, m_NormalPix);
}
上面兩個步驟可以實現(xiàn)一個任意規(guī)則的自定義窗體,其下來實現(xiàn)其在不同狀態(tài)下的圖片的切換。
設置不同狀態(tài)的圖片,這里以鼠標滑動方式為例。由于鼠標進入窗體區(qū)域后就應當設置為鼠標滑動狀態(tài),重載窗體的鼠標進入和鼠標離開區(qū)域來監(jiān)測其狀態(tài)。
//設置鼠標滑動圖片
void QtXPushButton::SetHoverPixmap(QString strImagePath)
{
m_HoverPix.load(strImagePath);
m_iMask |= XBUTTONSTATE::HOVER;
}
//重載鼠標進入和移出事件
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)過上述過程鼠標進入按鈕區(qū)域,按鈕會顯示HOVER圖片。鼠標移出按鈕區(qū)域,按鈕會顯示鼠標進入之前的狀態(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()
{
}
//設置正常圖標
void QtXPushButton::SetNormalPixmap(QString strImagePath)
{
m_NormalPix.load(strImagePath);
m_iMask |= XBUTTONSTATE::NORMAL;
}
//設置鼠標滑動圖片
void QtXPushButton::SetHoverPixmap(QString strImagePath)
{
m_HoverPix.load(strImagePath);
m_iMask |= XBUTTONSTATE::HOVER;
}
//設置選中狀態(tài)圖片
void QtXPushButton::SetSelectedPixmap(QString strImagePath)
{
m_SelectedPix.load(strImagePath);
m_iMask |= XBUTTONSTATE::SELECTED;
}
//設置禁止點擊圖標
void QtXPushButton::SetDisablePixmap(QString strImagePath)
{
m_DisablePix.load(strImagePath);
m_iMask |= XBUTTONSTATE::DISABLE;
}
//設置按鈕當前狀態(tài)
void QtXPushButton::SetBtnState(XBUTTONSTATE state)
{
m_lastState = m_curState;
m_curState = state;
}
//設置圖片大小
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();
}
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。