这个控件比较简单,模仿现代应用程序常见的开关按钮绘制。通过这个案例你可以了解Qt动画的使用。在VS2015和Qt5.9上简单测试通过。下面是效果图:
下面给出代码,头文件:
class MSwitch : public QWidget { Q_OBJECT public: MSwitch(QWidget* parent = 0); QSize sizeHint() const override; bool isOpened() const; signals: void clicked(bool); private: void setButtonPos(float where); void paintEvent(QPaintEvent *event) override; void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void enterEvent(QEvent *event) override; void leaveEvent(QEvent *event) override; private: bool opened; bool hover; float atWhere; /* [0, 1] */ QPoint pressPt; };
CPP文件(代码中变量atWhere是用来配合绘制动画的):
MSwitch::MSwitch(QWidget* parent) : QWidget(parent) { opened = false; hover = false; atWhere = 0; } void MSwitch::setButtonPos(float where) { atWhere = where; update(); } bool MSwitch::isOpened() const { return opened; } void MSwitch::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); qreal rad = height() * 0.5; /* 圆半径 */ int xleft = rad; int xright = width() - rad; int xpos = xleft + (xright - xleft) * atWhere; painter.setPen(Qt::NoPen); painter.setBrush((xpos == xright) ? QColor(0, 170, 255) : QColor(173, 173, 173)); painter.drawRoundedRect(0, 0, width(), height(), rad, rad); if (hover) /* 鼠标悬停稍微提亮一点 */ { painter.setBrush(QColor(255, 255, 255, 63)); painter.drawRoundedRect(0, 0, width(), height(), rad, rad); } painter.setPen(QColor(213, 213, 213)); painter.setBrush(QColor(243, 243, 243)); painter.drawEllipse(QPointF(xpos, rad), rad - 1, rad - 1); } void MSwitch::mousePressEvent(QMouseEvent *event) { pressPt = event->pos(); } void MSwitch::mouseReleaseEvent(QMouseEvent *event) { if (pressPt == event->pos()) { opened = !opened; emit clicked(opened); QVariantAnimation* ani = new QVariantAnimation(this); ani->setStartValue(0.0f); ani->setEndValue(1.0f); ani->setDuration(200); ani->setDirection(opened ? QVariantAnimation::Forward : QVariantAnimation::Backward); connect(ani, &QVariantAnimation::valueChanged, this, [this](const QVariant& value) { setButtonPos(value.toFloat()); }); ani->start(QAbstractAnimation::DeleteWhenStopped); } } void MSwitch::enterEvent(QEvent *event) { hover = true; update(); } void MSwitch::leaveEvent(QEvent *event) { hover = false; update(); } QSize MSwitch::sizeHint() const { return QSize(42, 21); }
标签:rad,Qt,自定义,void,按钮,MSwitch,event,painter,opened From: https://www.cnblogs.com/mengxiangdu/p/16926176.html