#ifndef SWITCHFORM_H #define SWITCHFORM_H

#include #include #include

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

#include "switchform.h" #include "ui_switchform.h" #include

SwitchForm::SwitchForm(QWidget *parent) : QWidget(parent) { m_space = 2; m_radius = 5; m_checked = false; m_showText = true; m_showText = 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 path1;
path1.addEllipse(rect.x(), rect.y(), side, side);

//右侧半圆
QPainterPath path2;
path2.addEllipse(rect.width() - side, rect.y(), side, side);

//中间的矩形
QPainterPath path3;
path3.addRect(rect.x() + side / 2, rect.y(), rect.width() - side, height());

QPainterPath path = path1 + path2 + path3;
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;
QRect rect(m_space + m_startX, m_space, sliderWidth, sliderWidth);
painter->drawEllipse(rect);

painter->restore();

}

void SwitchForm::paintEvent(QPaintEvent *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_step = width() / 10;

//计算滑块X轴终点坐标
if (m_checked) {
    m_endX = width() - height();
} else {
    m_endX = 0;
}

//判断是否使用动画
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();

}

int SwitchForm::space() const { return m_space; }

bool SwitchForm::checked() const { return m_checked; }

bool SwitchForm::showText() const { return m_showText; }

bool SwitchForm::showCircel() const { return m_showCircle; }

bool SwitchForm::animation() const { return m_animation; }

QColor SwitchForm::bgColorOn() const { return m_bgColorOn; }

QColor SwitchForm::bgColorOff() const { return m_bgColorOff; }

QColor SwitchForm::sliderColorOn() const { return m_sliderColorOn; }

QColor SwitchForm::sliderColorOff() const { return m_sliderColorOff; }

QColor SwitchForm::textColor() const { return m_textColor; }

QString SwitchForm::textOn() const { return m_textOn; }

QString SwitchForm::textOff() const { return m_textOff; }

int SwitchForm::step() const { return m_step; }

int SwitchForm::startX() const { return m_startX; }

int SwitchForm::endX() const { return m_endX; }

void SwitchForm::setSpace(int space) { if (m_space != space) { m_space = space; update(); } }

void SwitchForm::setRadius(int radius) { if (m_radius != radius) { m_radius = radius; update(); } }

void SwitchForm::setChecked(bool checked) { if (m_checked != checked) { m_checked = checked; update(); } }

void SwitchForm::setShowText(bool show) { if (m_showText != show) { m_showText = show; update(); } }

void SwitchForm::setShowCircle(bool show) { if (m_showCircle != show) { m_showCircle = show; update(); } }

void SwitchForm::setAnimation(bool ok) { if (m_animation != ok) { m_animation = ok; update(); } }

void SwitchForm::setBgColorOn(const QColor &color) { if (m_bgColorOn != color) { m_bgColorOn = color; update(); } }

void SwitchForm::setBgColorOff(const QColor &color) { if (m_bgColorOff != color) { m_bgColorOff = color; update(); } }

void SwitchForm::setSliderColorOn(const QColor &color) { if (m_sliderColorOn != color) { m_sliderColorOn = color; update(); } }

void SwitchForm::setSliderColorOff(const QColor &color) { if (m_sliderColorOff != color) { m_sliderColorOff = color; update(); } }

void SwitchForm::setTextColor(const QColor &color) { if (m_textColor != color) { m_textColor = color; update(); } }

void SwitchForm::setTextOn(const QString &text) { if (m_textOn != text) { m_textOn = text; update(); } }

void SwitchForm::setTextOff(const QString &text) { if (m_textOff != text) { m_textOff = text; update(); } }

当setCheck(true)时,内部圆圈图形在整个图形的右侧内容:可以通过修改drawSlider函数来实现内部圆圈图形在整个图形的右侧。

首先,需要修改drawSlider函数的绘制逻辑,使得滑块在右侧绘制。可以通过将滑块的起始坐标m_startX设置为width() - sliderWidth - m_space来实现。

修改后的drawSlider函数如下:

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;
    QRect rect(width() - sliderWidth - m_space - m_startX, m_space, sliderWidth, sliderWidth);
    painter->drawEllipse(rect);

    painter->restore();
}

然后,在mousePressEvent函数中,需要修改滑块的终点坐标m_endX的计算方式,使得滑块在右侧绘制。可以通过将滑块的终点坐标设置为0来实现。

修改后的mousePressEvent函数如下:

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

    m_checked = !m_checked;
    emit statusChanged(m_checked);

    //计算步长
    m_step = width() / 10;

    //计算滑块X轴终点坐标
    if (m_checked) {
        m_endX = 0;
    } else {
        m_endX = width() - height();
    }

    //判断是否使用动画
    if (m_animation) {
        m_timer->start();
    } else{
        m_startX = m_endX;
        update();
    }
}

这样,当调用setChecked(true)时,内部圆圈图形就会在整个图形的右侧绘制。

自定义开关组件:SwitchForm 类

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

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