通俗易懂玩QT:Qpaint绘制开关按钮(内附详细源码)

Qpaint 绘制开关按钮(内附详细源码)

一、实验效果与开发环境

效果图如下:

请添加图片描述

开发环境:

在这里插入图片描述

二、实验代码

switch.h

#ifndef SWITCH_H
#define SWITCH_H

#include 
#include 
#include 
#include 

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;
    is_ok = 0;
    timer -> start(10);
    emit triggered(is_open);
}

学习分享,一起成长!以上为小编的经验分享,若存在不当之处,请批评指正!

你可能感兴趣的:(QT学习,qt,qpainter,自定义按钮)