Qt自定义控件实现炫酷开关按钮
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. 使用方法
- 将
switchform.h和switchform.cpp文件添加到你的Qt项目中。 - 在你的Qt Designer界面中,添加一个
QWidget,并将类名设置为SwitchForm。 - 使用信号槽机制连接
statusChanged信号到你的槽函数,以便在开关状态改变时进行处理。
4. 效果展示

5. 总结
本文介绍了如何使用Qt自定义控件实现一个炫酷的开关按钮,并提供了详细的代码示例和讲解。你可以根据自己的需求修改代码,定制出更符合你项目风格的开关按钮。
原文地址: http://www.cveoy.top/t/topic/fARu 著作权归作者所有。请勿转载和采集!