Qt 自定义开关控件:SwitchForm 实现与优化
#include
SwitchForm::SwitchForm(QWidget *parent) : QWidget(parent) { number = 0; 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) { number++; m_textOn = text; update(); } }
void SwitchForm::setTextOff(const QString &text) { if (m_textOff != text) { m_textOff = text; update(); } }
bool SwitchForm::getStatus(int number) { if (number % 2) { return true; } else { return false; } }
#include
class SwitchForm : public QWidget { Q_OBJECT
public: explicit SwitchForm(QWidget *parent = nullptr); bool getStatus(int number);
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);
};
#endif // SWITCHFORM_H 增加判断是开启还是关闭功能的函数,使调用开关组件的界面知道开关的状态内容:在 SwitchForm 类中增加了一个名为 getStatus 的公共函数,用于获取开关的状态。在该函数中,通过判断 number 的奇偶性来确定开关的状态,奇数表示开启,偶数表示关闭。在调用开关组件的界面中,可以通过调用 getStatus 函数来获取开关的状态。
原文地址: https://www.cveoy.top/t/topic/fAlJ 著作权归作者所有。请勿转载和采集!