學c++以來,用qt做過一些界面,個人感覺軟件界面還是比較漂亮的,但是如果界面想嵌入一些漂亮的圖標做按鈕,利用qt本身已有的控件實現就有點困難了,當然可以通過爲QPushButton類添加背景圖標來實現,但是自我感覺效果不是很好,所以寫了這篇博客,想實現一下用純圖片來做按鈕控件,通過改變圖片的觀感,比如圖片的形狀大小,來表示按鈕的選中或者未選中,同時爲這圖片按鈕添加鼠標事件,從而模擬一個按鍵出來,這樣的好處主要是它能爲界面增色,不同的圖片,形狀,大小以及按鈕選中和未選中所展現給用戶的不同觀感將大大提高界面整體的美化程度。
設計思路主要通過重載Qt的幾個事件實現,
void mousePressEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
void enterEvent(QEvent *event);
void leaveEvent(QEvent *event);
同時還需要爲圖標按鈕添加一個信號函數,void isclicked(),由該函數發送鼠標按下的信號,供其他類使用。
代碼簡要分析:
/*IconButton類的構造函數*/
IconButton::IconButton(QString iconStr1,QString iconStr2,QWidget *parent)
: QWidget(parent, Qt::FramelessWindowHint)
{
//加載圖片作爲程序的界面
m_Pixmap.load(iconStr1);
m_Pixmap1.load(iconStr2);
if(m_Pixmap1.size().width()<m_Pixmap.size().width())
{
m_Pixmap.load(iconStr2);
m_Pixmap1.load(iconStr1);
}
leave=true; //初始化圖標按鈕爲未選中狀態
this->x=0; //初始化圖標按鈕的位置
this->y=0;
}
/*重載mousePressEvent函數*/
void IconButton::mousePressEvent(QMouseEvent *event)
{
//按下左鍵則發送按下信號
if(event->button() == Qt::LeftButton)
{
emit isclicked();
}
}
/*重載paintEvent函數*/
void IconButton::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
//分兩種情況來顯示不同的外觀,未選中時畫m_Pixmap,選中時畫m_Pixmap1
if(leave)
{
resize( m_Pixmap.size() );
painter.drawPixmap(0,0, m_Pixmap);
move(x+(m_Pixmap1.size().width()-m_Pixmap.size().width())/2,y+(m_Pixmap1.size().width()-m_Pixmap.size().width())/2);
}
else
{
resize( m_Pixmap1.size() );
painter.drawPixmap(0, 0, m_Pixmap1);
move(x,y);
this->setToolTip(iconTip);
}
}
/*重載:leaveEvent函數*/
void IconButton::leaveEvent(QEvent *event)
{
//鼠標離開窗口時是普通的指針
setCursor(Qt::ArrowCursor);
leave=true;
update(); //調用paintevent函數進行更新
}
/*重載:enterEvent函數*/
void IconButton::enterEvent(QEvent *event)
{
//鼠標留在窗口上時是一個手指,表示可以讀取按鍵事件
setCursor(Qt::PointingHandCursor);
leave=false;
update();//調用paintevent函數進行更新
}
//下面是供給用戶使用的兩個基本接口,分別是設置圖標按鈕的位置以及需要顯示的提示信息,這裏只簡單的寫了兩個功能,還可以增加其他功能,使這個IconButton類更加完善
void IconButton::setPosition(int x,int y)
{
this->x=x;
this->y=y;
}
void IconButton::setIconTip(QString iconTip)
{
this->iconTip=iconTip;
}
以下是實現該類的源碼:
iconButton.h
#ifndef ICONBUTTON_H
#define ICONBUTTON_H
#include <QtGui/QWidget>
class IconButton : public QWidget
{
Q_OBJECT
public:
IconButton(QString iconStr1,QString iconStr2,QWidget *parent = 0);
void setPosition(int x,int y);
void setIconTip(QString iconTip);
protected:
void mousePressEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
void enterEvent(QEvent *event);
void leaveEvent(QEvent *event);
signals:
void isclicked();
private:
QPixmap m_Pixmap,m_Pixmap1;
int x,y;
QString iconTip;
bool leave;
};
#endif // ICONBUTTON_H
iconButton.cpp
<pre class="cpp" name="code">#include "iconButton.h"
#include <QtGui>
IconButton::IconButton(QString iconStr1,QString iconStr2,QWidget *parent)
: QWidget(parent, Qt::FramelessWindowHint)
{
//加載一幅有部分區域是透明的圖片作爲程序的界面
m_Pixmap.load(iconStr1);
m_Pixmap1.load(iconStr2);
if(m_Pixmap1.size().width()<m_Pixmap.size().width())
{
m_Pixmap.load(iconStr2);
m_Pixmap1.load(iconStr1);
}
//setStyleSheet("background-color:lightblue");
leave=true;
this->x=0;
this->y=0;
}
void IconButton::mousePressEvent(QMouseEvent *event)
{
//按住左鍵關閉程序
if(event->button() == Qt::LeftButton)
{
emit isclicked();
}
}
void IconButton::setPosition(int x,int y)
{
this->x=x;
this->y=y;
}
void IconButton::setIconTip(QString iconTip)
{
this->iconTip=iconTip;
}
void IconButton::paintEvent(QPaintEvent *event)
{
qDebug("paint");
QPainter painter(this);
if(leave)
{
resize( m_Pixmap.size() );
//setMask( m_Pixmap.mask() );
painter.drawPixmap(0,0, m_Pixmap);
move(x+(m_Pixmap1.size().width()-m_Pixmap.size().width())/2,y+(m_Pixmap1.size().width()-m_Pixmap.size().width())/2);
}
else
{
resize( m_Pixmap1.size() );
//setMask( m_Pixmap1.mask() );
painter.drawPixmap(0, 0, m_Pixmap1);
move(x,y);
this->setToolTip(iconTip);
}
}
void IconButton::leaveEvent(QEvent *event)
{
//鼠標離開窗口時是普通的指針
setCursor(Qt::ArrowCursor);
leave=true;
update();
}
void IconButton::enterEvent(QEvent *event)
{
//鼠標留在窗口上時是一個手指
setCursor(Qt::PointingHandCursor);
leave=false;
update();
}