前言
Qt做界面的時候常常會用到開關控件,類似于CheckButton有兩種狀态,隻是界面表現形式不一樣而已。本文通過QWidget類來實作一個開關控件SwitchBtn(有些平台上又稱為SlipButton)。
首先來看看封裝好的控件樣式
正文
其中動畫效果是通過QPropertyAnimation來實作的,按鈕中間的圓是一張準備好的圖檔,而控件背景是通過目前狀态然後用QPainter來繪制的。
話不多說,直接上代碼
頭檔案
#include <QWidget>
#include <QPaintEvent>
#include <QPainterPath>
#include <QPropertyAnimation>
#include <QMouseEvent>
#include <QLabel>
class CTLSlipBtn : public QWidget
{
Q_OBJECT
public:
explicit CTLSlipBtn(int w,int h,QWidget *parent = 0);
~CTLSlipBtn();
void setBtnChecked(bool check);
protected:
void paintEvent(QPaintEvent* e);
void mouseReleaseEvent(QMouseEvent * e);
signals:
void sigClicked(bool);
private:
void _checkBtn();
private:
QLabel * m_pSwitchBtn;
bool
源檔案
#include "ctlslipbtn.h"
#include <QPainter>
#include "alcommonparameter.h"
CTLSlipBtn::CTLSlipBtn(int w, int h, QWidget *parent) :
QWidget(parent),
m_bIsChecked(false)
{
resize(w,h);
m_pSwitchBtn = new QLabel(this);
m_pSwitchBtn->setFixedSize(h,h);
m_pSwitchBtn->setPixmap(QPixmap("btn_switch.png"));
m_pSwitchBtn->move(QPointF(1,0).toPoint());
m_pTBtnBg = new QPainterPath();
m_pTBtnBg->moveTo(width(),height());
m_pTBtnBg->setFillRule(Qt::WindingFill);
m_pTBtnBg->addEllipse(w- h,0,h,h);
m_pTBtnBg->addEllipse(0,0,h,h);
m_pTBtnBg->addRect(h*0.5,0,w-h ,h);
m_pBtnAni = new QPropertyAnimation(m_pSwitchBtn,"pos",this);
m_pBtnAni->setEasingCurve(QEasingCurve::Linear);
m_pBtnAni->setDuration(100);
}
CTLSlipBtn::~CTLSlipBtn()
{
delete m_pBtnAni;
delete m_pTBtnBg;
}
void CTLSlipBtn::setBtnChecked(bool check)
{
m_bIsChecked = check;
if(check)
{
m_pSwitchBtn->move(QPointF(width()-m_pSwitchBtn->height()-1,0).toPoint());
}
else
{
m_pSwitchBtn->move(QPointF(1,0).toPoint());
}
}
void CTLSlipBtn::paintEvent(QPaintEvent *e)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(Qt::NoPen);
if(m_bIsChecked)
{
painter.setBrush(QColor(34,169,173));
}
else
{
painter.setBrush(QColor(200,200,200));
}
painter.drawPath(*m_pTBtnBg);
QWidget::paintEvent(e);
}
void CTLSlipBtn::mouseReleaseEvent(QMouseEvent *e)
{
_checkBtn();
update();
emit sigClicked(m_bIsChecked);
QWidget::mouseReleaseEvent(e);
}
void CTLSlipBtn::_checkBtn()
{
if(m_pBtnAni)
{
if(m_pBtnAni->state() == QAbstractAnimation::Running)
{
return;
}
if(m_bIsChecked)
{
m_pBtnAni->setStartValue(QPointF(width()-height()-1,0).toPoint());
m_pBtnAni->setEndValue(QPointF(1,0).toPoint());
}
else
{
m_pBtnAni->setStartValue(QPointF(1,0).toPoint());
m_pBtnAni->setEndValue(QPointF(width()-height()-1,
0).toPoint());
}
m_pBtnAni->start();
m_bIsChecked = !m_bIsChecked;
}
}
其中開關狀态變化後會發出信号sigClicked(bool)
這裡的控件背景都是固定寫死的,為了靈活性,可以寫一個接口單獨控件背景顔色,比較簡單,這裡不再贅述。控件使用方式也很簡單,直接初始化的時候傳入控件的大小,然後連接配接對象的信号即可。
點選領取Qt學習資料+視訊教程~
連結:http://docs.qq.com/doc/DUlVwTW1FZlZuWE9G