Qpaint 绘制开关按钮## 一、实验效果与开发环境
效果图如下:
开发环境:
二、实验代码
switch.h
#ifndef SWITCH_H
#define SWITCH_H
#include <QWidget>
#include <QPainter>
#include <QTimer>
#include <QMouseEvent>
class Switch : public QWidget
{
Q_OBJECT
public:
explicit Switch(QWidget *parent = nullptr);
~Switch();
signals:
void triggered(int status);
public slots:
void reset(int status);
private:
int is_open, is_ok;
double slot_width, slot_height, slot_coordinate_X, slot_coordinate_Y,
switch_width, switch_height, switch_coordinate_X, switch_coordinate_Y;
QTimer *timer;
void paintEvent(QPaintEvent *e);
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void changeStatus(void);
};
#endif // SWITCH_H
switch.c
#include "switch.h"
Switch::Switch(QWidget *parent) : QWidget(parent) {
is_open = 0; //开关状态
is_ok = 1; //开关防抖
slot_width = 50.0; //卡槽宽度
slot_height = 22.0; //卡槽高度
switch_width = 24.0; //开关宽度
switch_height = 22.0; //开关高度
slot_coordinate_X = 0.0; //卡槽横轴起始坐标
slot_coordinate_Y = 0.0; //卡槽竖轴起始坐标
switch_coordinate_X = -1.0; //开关横轴起始坐标
switch_coordinate_Y = 0.0; //开关竖轴起始坐标
timer = new QTimer();
connect(timer, &QTimer::timeout, [=]() {
changeStatus();
});
setCursor(Qt::PointingHandCursor);
}
Switch::~Switch() {}
/**
* @brief Switch::paintEvent
* @param e
* 使用 paintEvent 将按钮画出来
*/
void Switch::paintEvent(QPaintEvent *e) {
Q_UNUSED(e);
QPainter painter(this);
painter.setPen(Qt::NoPen); //无画笔
painter.setRenderHint(QPainter::Antialiasing); //抗锯齿
QColor slot_color = is_open ? QColor(124, 235, 70) : QColor(180, 180, 180); //卡槽颜色
//开关卡槽阴影
painter.setBrush(QColor(90, 90, 90));
painter.setOpacity(0.6);
painter.drawRoundedRect(QRectF(slot_coordinate_X, slot_coordinate_Y, slot_width + 1.0, slot_height + 1.0), (slot_height + 1.0) / 2, (slot_height + 1.0) / 2);
//开关卡槽
painter.setBrush(slot_color);
painter.setOpacity(0.9);
painter.drawRoundedRect(QRectF(slot_coordinate_X, slot_coordinate_Y, slot_width, slot_height), slot_height / 2, slot_height / 2);
//开关按钮阴影
painter.setBrush(QColor(90, 90, 90));
painter.setOpacity(0.6);
painter.drawEllipse(QRectF(switch_coordinate_X, switch_coordinate_Y, switch_width + 1.0, switch_height + 1.0));
//开关按钮
painter.setBrush(QColor(255, 255, 255));
painter.setOpacity(0.9);
painter.drawEllipse(QRectF(switch_coordinate_X, switch_coordinate_Y, switch_width, switch_height));
//开关状态说明 On/Off
painter.setPen(Qt::white); //白色画笔
painter.setFont(QFont("weiruyahei", 7, QFont::Bold, false)); //微软雅黑 7px 加粗 不倾斜
is_open ? painter.drawText(6, 14, "On") : painter.drawText(27, 14, "Off");
}
/**
* @brief Switch::mousePressEvent
* @param e
* 鼠标按下响应事件,接口预留
*/
void Switch::mousePressEvent(QMouseEvent *e) {
Q_UNUSED(e);
}
/**
* @brief Switch::mouseReleaseEvent
* @param e
* 通过鼠标按键释放响应事件,触发信号并传参
* 鼠标超出按钮范围释放,被视为无效操作
*/
void Switch::mouseReleaseEvent(QMouseEvent *e) {
if(e -> localPos().x() <= slot_width && e -> localPos().y() <= slot_height && e -> type() == QMouseEvent::MouseButtonRelease && e -> button() == Qt::LeftButton && is_ok) {
is_open = !is_open;
is_ok = 0;
timer -> start(10);
emit triggered(is_open);
}
}
/**
* @brief Switch::changeStatus
* 改变按钮的状态,开启或关闭
*/
void Switch::changeStatus() {
if(is_open) {
if(switch_coordinate_X ++ > slot_width - switch_width) {
timer -> stop();
is_ok = 1;
}
switch_coordinate_X = switch_coordinate_X > slot_width - switch_width ? slot_width - switch_width + 1 : switch_coordinate_X;
}
else {
if(switch_coordinate_X -- < slot_coordinate_X) {
timer -> stop();
is_ok = 1;
}
switch_coordinate_X = switch_coordinate_X < slot_coordinate_X ? slot_coordinate_X - 1 : switch_coordinate_X;
}
update();
}
/**
* @brief Switch::reset
* 重置按钮,将按钮还原为开启/关闭状态
*/
void Switch::reset(int status) {
is_open = status;
changeStatus();
}
学习分享,一起成长!以上为小编的经验分享,若存在不当之处,请批评指正!