自定义按键组件
自定义动画按键导航控件
参考网上大神绘制的自定义按键组件思路,自己重新整理一份代码,方便学习管理,源码全部开放,不喜勿喷!谢谢。
目前实现顶端与左端布局,当作控件使用,布局即可。
#ifndef BUTTONGROUP_H
#define BUTTONGROUP_H
#include <QWidget>
#include <QBoxLayout>
#include <QPaintEvent>
class QBoxLayout;
class QPushButton;
class QButtonGroup;
class QAbstractButton;
class QPropertyAnimation;
class ButtonGroup : public QWidget {
Q_OBJECT
public:
ButtonGroup(QWidget *parent = NULL);
~ButtonGroup();
enum LinePosition {
LinePosition_Left = 0,
LinePosition_Right = 1,
LinePosition_Top = 2,
LinePosition_Bottom = 3
};
void setButtonSize(QSize buttonSize);
void setLayoutMode(QBoxLayout::Direction mode);
void addButtonItem(QAbstractButton *button, int id, bool isEnd = false);
void setInterval(int interval) {
_interval = interval;
}
void setBaseColor(const QColor &color) {
_baseColor = color;
}
void setLineColor(const QColor &color) {
_lineColor = color;
}
void setLineWeight(int lineWeight) {
_lineWeight = lineWeight;
}
void setLinePosition(LinePosition linePosition) {
_linePosition = linePosition;
}
protected:
void resizeEvent(QResizeEvent *e);
void paintEvent(QPaintEvent *e);
private slots:
void _onButtonClicked(int id);
void _onValueChange(QVariant _currentIndex);
private:
void _initAnimation();
private:
int _offset;
int _lineWeight;
int _interval;
int _currentIndex;
LinePosition _linePosition;
QSize _btnSize;
QColor _textColor;
QColor _baseColor;
QColor _lineColor;
QColor _hoverColor;
QBoxLayout::Direction _mode;
QBoxLayout *_layout;
QButtonGroup *_btnGroup;
QPropertyAnimation *_animation;
};
#endif
#include <QPainter>
#include <QBoxLayout>
#include <QPushButton>
#include <QButtonGroup>
#include <QAbstractButton>
#include <QPropertyAnimation>
#include "ButtonGroup.h"
ButtonGroup::ButtonGroup(QWidget *parent)
: QWidget(parent)
, _offset(4)
, _lineWeight(4)
, _interval(200)
, _currentIndex(0)
, _linePosition(LinePosition_Top)
, _btnSize(QSize(80, 32))
, _textColor(QColor(Qt::black))
, _baseColor(QColor(Qt::white))
, _lineColor(QColor(23,160,134))
, _hoverColor(QColor(87,184,166).light(150))
, _mode(QBoxLayout::RightToLeft)
, _layout(new QBoxLayout(_mode))
, _btnGroup(new QButtonGroup(this))
, _animation(new QPropertyAnimation(this, ""))
{
_initAnimation();
connect(_btnGroup, SIGNAL(buttonClicked(int)),
this, SLOT(_onButtonClicked(int)));
}
ButtonGroup::~ButtonGroup() {
}
void ButtonGroup::setButtonSize(QSize buttonSize) {
if (NULL == _btnGroup) {
return;
}
foreach(QAbstractButton *button, _btnGroup->buttons()) {
if (NULL == button) {
continue;
}
button->setFixedSize(buttonSize);
}
_btnSize = buttonSize;
}
void ButtonGroup::setLayoutMode(QBoxLayout::Direction mode) {
if (NULL == _layout) {
return;
}
_layout->setDirection(mode);
_layout->setMargin(4);
_layout->setSpacing(0);
}
void ButtonGroup::addButtonItem(QAbstractButton *button, int id, bool isEnd) {
if (NULL == button) {
return;
}
QString back = QString("QPushButton{background-color:rgba(%1, %2, %3, 80);border:none;}")
.arg(_baseColor.red()).arg(_baseColor.green()).arg(_baseColor.blue());
QString hover = QString("QPushButton:hover{background-color:rgba(%1, %2, %3, 40);}")
.arg(_hoverColor.red()).arg(_hoverColor.green()).arg(_hoverColor.blue());
QString check = QString("QPushButton:pressed, QPushButton:checked{background-color:rgba(%1, %2, %3, 80);}")
.arg(_lineColor.red()).arg(_lineColor.green()).arg(_lineColor.blue());
QString style = QString("%1%2%3").arg(back).arg(hover).arg(check);
button->setStyleSheet(style);
_layout->addWidget(button);
if (isEnd) {
_layout->addStretch(0);
setLayout(_layout);
}
_btnGroup->addButton(button, id);
}
void ButtonGroup::resizeEvent(QResizeEvent *e) {
QWidget::resizeEvent(e);
}
void ButtonGroup::paintEvent(QPaintEvent *e) {
QWidget::paintEvent(e);
int xPos = 0;
int yPos = 0;
int width = 0;
int height = 0;
switch (_linePosition) {
case LinePosition_Top:
xPos = _offset;
yPos = 0;
width = _btnSize.width();
height = _lineWeight;
break;
case LinePosition_Bottom:
xPos = _offset;
yPos = this->height() - _lineWeight;
width = _btnSize.width();
height = _lineWeight;
break;
case LinePosition_Left:
xPos = 0;
yPos = _offset;
width = _lineWeight;
height = _btnSize.height();
break;
case LinePosition_Right:
xPos = this->width() - _lineWeight;
yPos = _offset;
width = _lineWeight;
height = _btnSize.height();
break;
default:
break;
}
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing);
painter.setPen(Qt::NoPen);
painter.setBrush(_lineColor);
painter.drawRect(xPos, yPos, width, height);
}
void ButtonGroup::_onButtonClicked(int id) {
if ((NULL == _btnGroup)
|| (NULL == _animation))
{
return;
}
_btnGroup->button(id)->setCheckable(true);
_btnGroup->button(id)->setChecked(true);
int offset = _currentIndex * _btnSize.width() + 4;
int endOffset = id * _btnSize.width() + 4;
if (_linePosition < LinePosition_Top) {
offset = _currentIndex * _btnSize.height() + 4;
endOffset = id * _btnSize.height() + 4;
}
_animation->setStartValue(offset);
_animation->setEndValue(endOffset);
_animation->start();
_currentIndex = id;
}
void ButtonGroup::_onValueChange(QVariant index) {
_offset = index.toInt();
update();
}
void ButtonGroup::_initAnimation() {
if (NULL == _animation) {
return;
}
_animation->setDuration(_interval);
connect(_animation, SIGNAL(valueChanged(QVariant)),
this, SLOT(_onValueChange(QVariant)));
}