QT纯代码实现滑动开关控件
立即下载
资源介绍:
开关按钮大家应该很熟悉,在设置里面经常遇到,切换时候的滑动效果比较帅气。通常说的开关按钮,有两个状态:on、off。大部分的开关按钮控件,基本上有两大类,第一类是纯代码绘制,这种对代码的掌控度要求比较高,但是灵活性比较好。第二类是贴图,专业的美工做好的各种状态的背景图片,只需要用代码将该图片画到界面上即可。本示例实现纯代码绘制的开关按钮。
#include "slipbutton.h"
#include
#include
struct SlipButtonPrivate{
int offset = 0;
QColor uncheckBackgroundColor = QColor("#FFE0E0E0");
QColor checkedBackgroundColor = QColor("#4da1ff");
bool hover = false;
QPropertyAnimation *animation;
};
SlipButton::SlipButton(QWidget *parent)
: QAbstractButton(parent)
, d(new SlipButtonPrivate)
{
d->animation = new QPropertyAnimation(this, "offset", this);
setCheckable(true);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
connect(this, &SlipButton::toggled, this, &SlipButton::onStartAnimation);
}
SlipButton::~SlipButton()
{
}
QSize SlipButton::sizeHint() const
{
return QSize(100 * 1.8, 100);
}
QSize SlipButton::minimumSizeHint() const
{
return QSize(10 * 1.8, 10);
}
void SlipButton::setCheckedBackgroundColor(const QColor& color)
{
d->checkedBackgroundColor = color;
update();
}
QColor SlipButton::checkedBackgroundColor() const
{
return d->checkedBackgroundColor;
}
void SlipButton::setUncheckedBackgroundColor(const QColor &color)
{
d->uncheckBackgroundColor = color;
update();
}
QColor SlipButton::uncheckedBackgroundColor() const
{
return d->uncheckBackgroundColor;
}
int SlipButton::offset() const
{
return d->offset;
}
void SlipButton::setOffset(int offset)
{
d->offset = offset;
update();
}
double SlipButton::widthMargin() const
{
return width() / 22.0;
}
double SlipButton::heightMargin() const
{
return height() / 22.0;
}
void SlipButton::paintEvent(QPaintEvent* event)
{
//qDebug() << offset();
QWidget::paintEvent(event);
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
double w = width() - widthMargin() * 2;
double h = height() - heightMargin() * 2;
// 画背景
QRectF rectSlot((width() - w) / 2, (height() - h) / 2, w, h);
double slotRoundness = rectSlot.height() / 2;
painter.setBrush(d->uncheckBackgroundColor);
painter.drawRoundedRect(rectSlot, slotRoundness, slotRoundness);
// 选中情况下,背景变蓝
if(isEnabled() && isChecked()){
QRectF rectSlotFill = rectSlot.adjusted(0, 0, offset() + h - (width() - widthMargin()), 0);
painter.setBrush(d->checkedBackgroundColor);
painter.drawRoundedRect(rectSlotFill, slotRoundness, slotRoundness);
}
QRectF rectThumb = QRectF(offset(), (height() - h) / 2, h, h);
QColor colorThumbBorder = (d->hover) ? d->checkedBackgroundColor: QColor("#FFA8A8A8");
painter.setBrush(colorThumbBorder);
painter.drawEllipse(rectThumb);
// 按钮圆点
QColor colorThumb = isEnabled() ? QColor(Qt::white) : QColor("#FFE0E0E0");
painter.setBrush(colorThumb);
rectThumb.adjust(1.1, 1.1, -1.1, -1.1);
painter.drawEllipse(rectThumb);
}
void SlipButton::enterEvent(QEvent *event)
{
QAbstractButton::enterEvent(event);
setCursor(Qt::PointingHandCursor);
d->hover = true;
}
void SlipButton::leaveEvent(QEvent* event)
{
QAbstractButton::leaveEvent(event);
d->hover = false;
}
void SlipButton::resizeEvent(QResizeEvent *event)
{
QAbstractButton::resizeEvent(event);
if(isChecked()){
double h = height() - heightMargin() * 2;
setOffset(width() - widthMargin() - h);
}else
setOffset(widthMargin());
}
void SlipButton::onStartAnimation()
{
double h = height() - heightMargin() * 2;
double start = widthMargin();
double end = width() - start - h;
if(!isChecked())
qSwap(start, end);
// 改变参数值(offset = startValue, offset += interval_1...offset += interval_N)
// 改变offset的同时,不断repaint(update)
// 直到为目标值(offset = endValue)paint完成;
d->animation->setStartValue(start);
d->animation->setEndValue(end);
d->animation->setDuration(120);
d->animation->start();
}