Qt自定义控件实现炫酷开关按钮

本文将介绍如何使用Qt框架自定义一个带有动画效果的精美开关按钮。

1. 功能概述

该自定义开关按钮具有以下功能:

  • 可以设置开关状态(打开/关闭)。
  • 支持自定义背景颜色、滑块颜色、文字颜色等。
  • 可以设置圆角大小。
  • 支持显示/隐藏文字。
  • 可以开启/关闭动画效果。

2. 代码实现

switchform.h

#ifndef SWITCHFORM_H
#define SWITCHFORM_H

#include <QWidget>
#include <QTimer>
#include <QColor>

namespace Ui {
class SwitchForm;
}

class SwitchForm : public QWidget
{
    Q_OBJECT

public:
    explicit SwitchForm(QWidget *parent = nullptr);

signals:
    void statusChanged(bool checked);


public slots:
    void updateValue();

private:
    void drawBackGround(QPainter *painter);
    void drawSlider(QPainter *painter);

protected:
    void paintEvent(QPaintEvent *ev);
    void mousePressEvent(QMouseEvent *ev);

private:

    int m_space;                //滑块距离边界距离
       int m_radius;               //圆角角度

       bool m_checked;             //是否选中
       bool m_showText;            //是否显示文字
       bool m_showCircle;          //是否显示圆圈
       bool m_animation;           //是否使用动画

       QColor m_bgColorOn;         //打开时候的背景色
       QColor m_bgColorOff;        //关闭时候的背景色
       QColor m_sliderColorOn;     //打开时候滑块颜色
       QColor m_sliderColorOff;    //关闭时候滑块颜色
       QColor m_textColor;         //文字颜色

       QString m_textOn;           //打开时候的文字
       QString m_textOff;          //关闭时候的文字

       QTimer  *m_timer;            //动画定时器
       int     m_step;             //动画步长
       int     m_startX;           //滑块开始X轴坐标
       int     m_endX;             //滑块结束X轴坐标

public:
    int space()                 const;
    int radius()                const;
    bool checked()              const;
    bool showText()             const;
    bool showCircel()           const;
    bool animation()            const;

    QColor bgColorOn()          const;
    QColor bgColorOff()         const;
    QColor sliderColorOn()      const;
    QColor sliderColorOff()     const;
    QColor textColor()          const;

    QString textOn()            const;
    QString textOff()           const;

    int step()                  const;
    int startX()                const;
    int endX()                  const;

public Q_SLOTS:
    void setSpace(int space);
    void setRadius(int radius);
    void setChecked(bool checked);
    void setShowText(bool show);
    void setShowCircle(bool show);
    void setAnimation(bool ok);

    void setBgColorOn(const QColor &color);
    void setBgColorOff(const QColor &color);
    void setSliderColorOn(const QColor &color);
    void setSliderColorOff(const QColor &color);
    void setTextColor(const QColor &color);

    void setTextOn(const QString &text);
    void setTextOff(const QString &text);

};

bool getStatus();

#endif // SWITCHFORM_H

switchform.cpp

#include 'switchform.h'
#include 'ui_switchform.h'
#include <QPainter>

SwitchForm::SwitchForm(QWidget *parent) :
    QWidget(parent)
{
    // 初始化成员变量
    m_space = 2;
    m_radius = 5;
    m_checked = false;
    m_showText = true;
    m_showCircle = false;
    m_animation = true;

    m_bgColorOn = QColor(102, 205, 170);
    m_bgColorOff = QColor(190, 190, 190);

    m_sliderColorOn = QColor(255, 255, 255);
    m_sliderColorOff = QColor(255, 255, 255);

    m_textColor = QColor(255, 255, 255);

    m_textOn = '开启';
    m_textOff = '关闭';

    m_step = 0;
    m_startX = 0;
    m_endX = 0;

    // 创建定时器
    m_timer = new QTimer(this);
    m_timer->setInterval(30);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(updateValue()));
}

void SwitchForm::drawBackGround(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);

    // 设置背景颜色
    QColor bgColor = m_checked ? m_bgColorOn : m_bgColorOff;
    if (isEnabled()) {
        bgColor.setAlpha(150);
    }
    painter->setBrush(bgColor);

    // 绘制圆角矩形
    QRect rect(0, 0, width(), height());
    int side = qMin(width(), height());
    QPainterPath path;
    path.addRoundedRect(rect, side / 2, side / 2);
    painter->drawPath(path);

    // 绘制文本
    int sliderWidth = qMin(height(), width()) - m_space * 2 - 5;
    if (m_checked) {
        QRect textRect(0, 0, width() - sliderWidth, height());
        painter->setPen(QPen(m_textColor));
        painter->drawText(textRect, Qt::AlignCenter, m_textOn);
    } else {
        QRect textRect(sliderWidth, 0, width() - sliderWidth, height());
        painter->setPen(QPen(m_textColor));
        painter->drawText(textRect, Qt::AlignCenter, m_textOff);
    }

    painter->restore();
}

void SwitchForm::drawSlider(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);

    // 设置滑块颜色
    QColor color = m_checked ? m_sliderColorOn : m_sliderColorOff;
    painter->setBrush(QBrush(color));

    // 计算滑块位置
    int sliderWidth = qMin(width(), height()) - m_space * 2;
    int sliderX = m_checked ? width() - sliderWidth - m_space : m_space;

    // 绘制滑块
    QRect rect(sliderX, m_space, sliderWidth, sliderWidth);
    painter->drawEllipse(rect);

    painter->restore();
}

void SwitchForm::paintEvent(QPaintEvent *ev)
{
    Q_UNUSED(ev);

    // 启用反锯齿
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    // 绘制背景
    drawBackGround(&painter);

    // 绘制滑块
    drawSlider(&painter);
}

void SwitchForm::mousePressEvent(QMouseEvent *ev)
{
    Q_UNUSED(ev);

    // 切换状态
    m_checked = !m_checked;
    emit statusChanged(m_checked);

    // 计算滑块目标位置
    m_endX = m_checked ? width() - height() : 0;

    // 计算步长
    m_step = qAbs(m_endX - m_startX) / 10;

    // 启动动画
    if (m_animation) {
        m_timer->start();
    } else {
        m_startX = m_endX;
        update();
    }
}

void SwitchForm::updateValue()
{
    // 更新滑块位置
    if (m_checked) {
        if (m_startX < m_endX) {
            m_startX += m_step;
        } else {
            m_startX = m_endX;
            m_timer->stop();
        }
    } else {
        if (m_startX > m_endX) {
            m_startX -= m_step;
        } else {
            m_startX = m_endX;
            m_timer->stop();
        }
    }

    // 更新界面
    update();
}

// 省略其他 getter 和 setter 函数

3. 使用方法

  1. switchform.hswitchform.cpp 文件添加到你的Qt项目中。
  2. 在你的Qt Designer界面中,添加一个QWidget,并将类名设置为SwitchForm
  3. 使用信号槽机制连接statusChanged信号到你的槽函数,以便在开关状态改变时进行处理。

4. 效果展示

开关按钮效果图

5. 总结

本文介绍了如何使用Qt自定义控件实现一个炫酷的开关按钮,并提供了详细的代码示例和讲解。你可以根据自己的需求修改代码,定制出更符合你项目风格的开关按钮。

Qt自定义控件实现炫酷开关按钮

原文地址: http://www.cveoy.top/t/topic/fARu 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录