欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

QT自绘滑动开关按钮

程序员文章站 2022-05-28 14:33:28
...

一、借鉴于飞杨青云的思想,进行修改:

1、使用鼠标妥当滑块,拖到左边为“关”,拖到右边为“开”。

2、释放鼠标时判断开关,并发射开、关状态信号。

3、关状态时滑块为黑色,拖动状态时为红色,开状态时滑块为蓝色。

二、类的封装:

#ifndef SWITCHBUTTON_H
#define SWITCHBUTTON_H

#include <QWidget>
#include <QPainter>
#include <QMouseEvent>

class SwitchButton : public QWidget
{
	Q_OBJECT

public:
	SwitchButton(QWidget *parent);
	~SwitchButton();

private:
	bool bSwitch;                     //开关状态:开true,关false

	QColor bgColorOn;                 //开状态时的背景颜色
	QColor bgColorOff;                //关状态时的背景颜色

	QColor sliderColor;               
	QColor sliderColorOn;             //开状态时滑块的背景颜色
	QColor sliderColorOff;            //关状态时滑块的背景颜色

	QColor textColorOn;               //开状态时文字颜色
	QColor textColorOff;              //关状态时文字颜色

	QString strText;                  //文字内容

	QPoint startPoint;                //滑块移动的起始点
	QPoint endPoint;                  //滑块移动的终点   
	QPoint centerPoint;               //滑块移动的中间某点

	int mouseX;           

	bool bPress;                      //左键是否按下

private:
	void paintEvent(QPaintEvent *e);
	void resizeEvent(QResizeEvent *e);
	void mousePressEvent(QMouseEvent *e);
	void mouseMoveEvent(QMouseEvent *e);
	void mouseReleaseEvent(QMouseEvent *e);
	void drawBg(QPainter& painter);        //绘制背景
	void drawSlidBlock(QPainter& painter); //绘制滑块
	void drawText(QPainter& painter);      //绘制文字

signals:
	void btnState(bool bswitch);
};

#endif // SWITCHBUTTON_H
#include "SwitchButton.h"
#include <QDebug>

SwitchButton::SwitchButton(QWidget *parent)
	: QWidget(parent)
{
	bSwitch = false;

	bgColorOff = QColor(192,192,192);
	bgColorOn = QColor(20,255,20);
	
	sliderColorOff = QColor(100, 100, 100);
	sliderColorOn = QColor(100, 184, 255);
	sliderColor = sliderColorOff;

	textColorOn = QColor(255,255,255);
	textColorOff = QColor(0,0,0);

	mouseX = 0;
	bPress = false;
}

SwitchButton::~SwitchButton()
{
}

void SwitchButton::mousePressEvent(QMouseEvent *e)
{
	if (e->button() == Qt::LeftButton)
	{
		if ((e->pos().x() - centerPoint.x())*(e->pos().y() - centerPoint.y()) <= ((rect().height()/2) * (rect().height()/2)))
		{
			bPress = true;
			mouseX = e->pos().x();
			sliderColor = QColor(160,30,30);
			update();
		}
	}
}

void SwitchButton::mouseMoveEvent(QMouseEvent *e)
{
	if (bPress)
	{
		if ((e->pos().x() >= startPoint.x()) && (e->pos().x() <= endPoint.x()))
		{
			int tempX = e->pos().x();
			centerPoint.setX(tempX - mouseX + centerPoint.x());
			mouseX = centerPoint.x();

			update();
		}
	}
}

void SwitchButton::mouseReleaseEvent(QMouseEvent *e)
{
	bPress = false;
	sliderColor = QColor(245,245,245);

	if (centerPoint.x() >= rect().width()/2)
	{
		centerPoint.setX(endPoint.x());
		sliderColor = sliderColorOn;

		if(!bSwitch)
			emit btnState(true);

		bSwitch = true;
	}
	else if (centerPoint.x() < rect().width()/2)
	{
		centerPoint.setX(startPoint.x());
		sliderColor = sliderColorOff;

		if(bSwitch)
			emit btnState(false);

		bSwitch = false;
	}

	update();
}

void SwitchButton::resizeEvent(QResizeEvent *e)
{
	startPoint = QPoint(rect().height()/2,rect().height()/2);
	centerPoint = startPoint;
	endPoint = QPoint((rect().right() - rect().height()/2),rect().height()/2);
}

void SwitchButton::paintEvent(QPaintEvent *e)
{
	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing);

	drawBg(painter);
	drawSlidBlock(painter);
	drawText(painter);
}

/*
** 绘制背景
*/
void SwitchButton::drawBg(QPainter& painter)
{
	painter.save();
	painter.setPen(Qt::NoPen);

	if (bSwitch)
	{
		painter.setBrush(QBrush(bgColorOn));
	} 
	else
	{
		painter.setBrush(QBrush(bgColorOff));
	}

	/*
	** 绘制按钮外边框
	*/
	QPainterPath path;
	int startX = rect().height()/2;
	int startY = rect().top();

	path.moveTo(startX,startY);
	path.arcTo(QRect(rect().left(),rect().top(),rect().height(),rect().height()),90,180);
	path.lineTo((rect().right() - startX),rect().height());
	path.arcTo(QRect((rect().right() - rect().height()),rect().top(),rect().height(),rect().height()),270,180);
	path.lineTo(startX,startY);
	painter.drawPath(path);

	painter.restore();
}

/*
** 绘制滑块
*/
void SwitchButton::drawSlidBlock(QPainter& painter)
{
	painter.save();
	painter.setPen(Qt::NoPen);

	painter.setBrush(QBrush(sliderColor));
	
	painter.drawEllipse(centerPoint,rect().height()/2 - 2,rect().height()/2 - 2);

	painter.restore();
}

void SwitchButton::drawText(QPainter& painter)
{
	painter.save();
	QFont font("Microsoft YaHei", 12, 50, false);
	painter.setFont(font);

	int x,y; 

	if (bSwitch)
	{
		painter.setPen(QPen(textColorOn));

		x = rect().left();
		y = rect().top();

		strText = QString::fromLocal8Bit("开");
	} 
	else
	{
		painter.setPen(QPen(textColorOff));
	
		x = rect().right() - rect().height();
		y = rect().top();

		strText = QString::fromLocal8Bit("关");
	}

	painter.drawText(x,y,rect().height(),rect().height(),Qt::AlignCenter,strText);

	painter.restore();
}

主框架调用:

#ifndef SWITCHBUTTONCLASS_H
#define SWITCHBUTTONCLASS_H

#include <QtGui/QWidget>
#include "ui_switchbuttonclass.h"

class SwitchButtonClass : public QWidget
{
	Q_OBJECT

public:
	SwitchButtonClass(QWidget *parent = 0, Qt::WFlags flags = 0);
	~SwitchButtonClass();

private:
	Ui::SwitchButtonClassClass ui;

private slots:
	void OnButtonState(bool bState);
};

#endif // SWITCHBUTTONCLASS_H
#include "switchbuttonclass.h"
#include <QMessageBox>

SwitchButtonClass::SwitchButtonClass(QWidget *parent, Qt::WFlags flags)
	: QWidget(parent, flags)
{
	ui.setupUi(this);
	connect(ui.widget,SIGNAL(btnState(bool)),this,SLOT(OnButtonState(bool)));
}

SwitchButtonClass::~SwitchButtonClass()
{

}

void SwitchButtonClass::OnButtonState(bool bState)
{
	if (bState)
	{
		QMessageBox::information(this,QString::fromLocal8Bit("开关状态"),QString::fromLocal8Bit("打开"));

	}else{
		QMessageBox::information(this,QString::fromLocal8Bit("开关状态"),QString::fromLocal8Bit("关闭"));
	}
}

QT自绘滑动开关按钮