qt/LedOK/base/switchcontrol.cpp
2023-04-18 14:14:46 +08:00

485 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "switchcontrol.h"
#include "qpainter.h"
#include <QPainterPath>
#include "qevent.h"
#include "qtimer.h"
#include "qdebug.h"
SwitchControl::SwitchControl(QWidget *parent): QWidget(parent)
{
checked = false;
buttonStyle = ButtonStyle_Rect;
bgColorOff = QColor(225, 225, 225);
bgColorOn = QColor(250, 250, 250);
sliderColorOff = QColor(100, 100, 100);
sliderColorOn = QColor(100, 184, 255);
textColorOff = QColor(255, 255, 255);
textColorOn = QColor(10, 10, 10);
textOff = "";
textOn = "";
imageOff = ":/image/btncheckoff1.png";
imageOn = ":/image/btncheckon1.png";
space = 2;
rectRadius = 5;
step = width() / 50;
startX = 0;
endX = 0;
timer = new QTimer(this);
timer->setInterval(5);
connect(timer, SIGNAL(timeout()), this, SLOT(updateValue()));
setFont(QFont("Microsoft Yahei", 10));
}
SwitchControl::~SwitchControl()
{
}
void SwitchControl::mousePressEvent(QMouseEvent *)
{
checked = !checked;
//每次移动的步长为宽度的 50分之一
step = width() / 50;
//状态切换改变后自动计算终点坐标
if (checked) {
if (buttonStyle == ButtonStyle_Rect) {
endX = width() - width() / 2;
} else if (buttonStyle == ButtonStyle_CircleIn) {
endX = width() - height();
} else if (buttonStyle == ButtonStyle_CircleOut) {
endX = width() - height() + space;
}
} else {
endX = 0;
}
timer->start();
emit checkedChanged(checked);
}
void SwitchControl::resizeEvent(QResizeEvent *)
{
//每次移动的步长为宽度的 50分之一
step = width() / 50;
//尺寸大小改变后自动设置起点坐标为终点
if (checked) {
if (buttonStyle == ButtonStyle_Rect) {
startX = width() - width() / 2;
} else if (buttonStyle == ButtonStyle_CircleIn) {
startX = width() - height();
} else if (buttonStyle == ButtonStyle_CircleOut) {
startX = width() - height() + space;
}
} else {
startX = 0;
}
update();
}
void SwitchControl::paintEvent(QPaintEvent *)
{
//绘制准备工作,启用反锯齿
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
if (buttonStyle == ButtonStyle_Image) {
//绘制图片
drawImage(&painter);
} else {
//绘制背景
drawBg(&painter);
//绘制滑块
drawSlider(&painter);
//绘制文字
drawText(&painter);
}
}
void SwitchControl::drawBg(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
if (!checked) {
painter->setBrush(bgColorOff);
} else {
painter->setBrush(bgColorOn);
}
if (buttonStyle == ButtonStyle_Rect) {
painter->drawRoundedRect(rect(), rectRadius, rectRadius);
} else if (buttonStyle == ButtonStyle_CircleIn) {
QRect rect(0, 0, width(), height());
//半径为高度的一半
int radius = rect.height() / 2;
//圆的宽度为高度
int circleWidth = rect.height();
QPainterPath path;
path.moveTo(radius, rect.left());
path.arcTo(QRectF(rect.left(), rect.top(), circleWidth, circleWidth), 90, 180);
path.lineTo(rect.width() - radius, rect.height());
path.arcTo(QRectF(rect.width() - rect.height(), rect.top(), circleWidth, circleWidth), 270, 180);
path.lineTo(radius, rect.top());
painter->drawPath(path);
} else if (buttonStyle == ButtonStyle_CircleOut) {
QRect rect(space, space, width() - space * 2, height() - space * 2);
painter->drawRoundedRect(rect, rectRadius, rectRadius);
}
painter->restore();
}
void SwitchControl::drawSlider(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
if (!checked) {
painter->setBrush(sliderColorOff);
} else {
painter->setBrush(sliderColorOn);
}
if (buttonStyle == ButtonStyle_Rect) {
int sliderWidth = width() / 2 - space * 2;
int sliderHeight = height() - space * 2;
QRect sliderRect(startX + space, space, sliderWidth , sliderHeight);
painter->drawRoundedRect(sliderRect, rectRadius, rectRadius);
} else if (buttonStyle == ButtonStyle_CircleIn) {
QRect rect(0, 0, width(), height());
int sliderWidth = rect.height() - space * 2;
QRect sliderRect(startX + space, space, sliderWidth, sliderWidth);
painter->drawEllipse(sliderRect);
} else if (buttonStyle == ButtonStyle_CircleOut) {
QRect rect(0, 0, width() - space, height() - space);
int sliderWidth = rect.height();
QRect sliderRect(startX, space / 2, sliderWidth, sliderWidth);
painter->drawEllipse(sliderRect);
}
painter->restore();
}
void SwitchControl::drawText(QPainter *painter)
{
painter->save();
if (!checked) {
painter->setPen(textColorOff);
painter->drawText(width() / 2, 0, width() / 2 - space, height(), Qt::AlignCenter, textOff);
} else {
painter->setPen(textColorOn);
painter->drawText(0, 0, width() / 2 + space * 2, height(), Qt::AlignCenter, textOn);
}
painter->restore();
}
void SwitchControl::drawImage(QPainter *painter)
{
painter->save();
QPixmap pix;
if (!checked) {
pix = QPixmap(imageOff);
} else {
pix = QPixmap(imageOn);
}
//自动等比例平滑缩放居中显示
int targetWidth = pix.width();
int targetHeight = pix.height();
pix = pix.scaled(targetWidth, targetHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
int pixX = rect().center().x() - targetWidth / 2;
int pixY = rect().center().y() - targetHeight / 2;
QPoint point(pixX, pixY);
painter->drawPixmap(point, pix);
painter->restore();
}
void SwitchControl::updateValue()
{
if (checked) {
if (startX < endX) {
startX = startX + step;
} else {
startX = endX;
timer->stop();
}
} else {
if (startX > endX) {
startX = startX - step;
} else {
startX = endX;
timer->stop();
}
}
update();
}
void SwitchControl::setChecked(bool checked)
{
if (this->checked != checked) {
this->checked = checked;
emit checkedChanged(checked);
update();
}
}
void SwitchControl::setCheckedStatus(bool checked)
{
if (this->checked != checked) {
this->checked = checked;
}
update();
step = width() / 50;
//状态切换改变后自动计算终点坐标
if (checked) {
if (buttonStyle == ButtonStyle_Rect) {
endX = width() - width() / 2;
} else if (buttonStyle == ButtonStyle_CircleIn) {
endX = width() - height();
} else if (buttonStyle == ButtonStyle_CircleOut) {
endX = width() - height() + space;
}
} else {
endX = 0;
}
timer->start();
}
void SwitchControl::setButtonStyle(SwitchControl::ButtonStyle buttonStyle)
{
this->buttonStyle = buttonStyle;
update();
}
void SwitchControl::setBgColor(QColor bgColorOff, QColor bgColorOn)
{
this->bgColorOff = bgColorOff;
this->bgColorOn = bgColorOn;
update();
}
void SwitchControl::setSliderColor(QColor sliderColorOff, QColor sliderColorOn)
{
this->sliderColorOff = sliderColorOff;
this->sliderColorOn = sliderColorOn;
update();
}
void SwitchControl::setTextColor(QColor textColorOff, QColor textColorOn)
{
this->textColorOff = textColorOff;
this->textColorOn = textColorOn;
update();
}
void SwitchControl::setText(QString textOff, QString textOn)
{
this->textOff = textOff;
this->textOn = textOn;
update();
}
void SwitchControl::setImage(QString imageOff, QString imageOn)
{
this->imageOff = imageOff;
this->imageOn = imageOn;
update();
}
void SwitchControl::setSpace(int space)
{
this->space = space;
update();
}
void SwitchControl::setRectRadius(int rectRadius)
{
this->rectRadius = rectRadius;
update();
}
/*#include <QPainter>
#include <QMouseEvent>
SwitchControl::SwitchControl(QWidget *parent)
: QWidget(parent)
{
m_nHeight=16;
m_bChecked=false;
m_radius=8.0;
m_nMargin=5;
m_checkedColor=QColor(0, 150, 136);
m_thumbColor=Qt::white;
m_disabledColor=QColor(190, 190, 190);
m_background=Qt::black;
setAttribute(Qt::WA_DeleteOnClose);
// 鼠标滑过光标形状 - 手型
setCursor(Qt::PointingHandCursor);
// 连接信号槽
connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}
// 绘制开关
void SwitchControl::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
QColor background;
QColor thumbColor;
qreal dOpacity;
if (isEnabled()) { // 可用状态
if (m_bChecked) { // 打开状态
background = m_checkedColor;
thumbColor = m_checkedColor;
dOpacity = 0.600;
} else { //关闭状态
background = m_background;
thumbColor = m_thumbColor;
dOpacity = 0.800;
}
} else { // 不可用状态
background = m_background;
dOpacity = 0.260;
thumbColor = m_disabledColor;
}
// 绘制大椭圆
painter.setBrush(background);
painter.setOpacity(dOpacity);
path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width() - 2 * m_nMargin-(m_nHeight / 2), height() - 2 * m_nMargin), m_radius, m_radius);
painter.drawPath(path.simplified());
// 绘制小椭圆
painter.setBrush(thumbColor);
painter.setOpacity(1.0);
painter.drawEllipse(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), height(), height()));
}
// 鼠标按下事件
void SwitchControl::mousePressEvent(QMouseEvent *event)
{
if (isEnabled()) {
if (event->buttons() & Qt::LeftButton) {
event->accept();
} else {
event->ignore();
}
}
}
// 鼠标释放事件 - 切换开关状态、发射toggled()信号
void SwitchControl::mouseReleaseEvent(QMouseEvent *event)
{
if (isEnabled()) {
if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) {
event->accept();
m_bChecked = !m_bChecked;
emit toggled(m_bChecked);
m_timer.start(10);
} else {
event->ignore();
}
}
}
// 大小改变事件
void SwitchControl::resizeEvent(QResizeEvent *event)
{
m_nX = m_nHeight / 2;
m_nY = m_nHeight / 2;
QWidget::resizeEvent(event);
}
// 默认大小
QSize SwitchControl::sizeHint() const
{
return minimumSizeHint();
}
// 最小大小
QSize SwitchControl::minimumSizeHint() const
{
return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin);
}
// 切换状态 - 滑动
void SwitchControl::onTimeout()
{
if (m_bChecked) {
m_nX += 1;
if (m_nX >= width() - m_nHeight*2)
m_timer.stop();
} else {
m_nX -= 1;
if (m_nX <= m_nHeight / 2)
m_timer.stop();
}
update();
}
// 返回开关状态 - 打开true 关闭false
bool SwitchControl::isToggled() const
{
return m_bChecked;
}
// 设置开关状态
void SwitchControl::setToggle(bool checked)
{
m_bChecked = checked;
m_timer.start(10);
}
// 设置背景颜色
void SwitchControl::setBackgroundColor(QColor color)
{
m_background = color;
}
// 设置拇指颜色
void SwitchControl::setthumbColor(QColor color)
{
//拇指颜色
m_thumbColor = color;
}
// 设置选中颜色
void SwitchControl::setCheckedColor(QColor color)
{
m_checkedColor = color;
}
// 设置不可用颜色
void SwitchControl::setDisbaledColor(QColor color)
{
m_disabledColor = color;
}
*/