这个功能的实现包括两个重要的部分,第一个是菜单条的文字下面的滑动伸缩线。第二个是菜单下拉框的动画效果,以及下拉框的上浮,下沉的效果。
MenuBar.h
#ifndef MENU_BAR_H
#define MENU_BAR_H
#include
#include
#include
#include
#include
class QPushButton;
class QPropertyAnimation;
class MenuBar : public QWidget
{
Q_OBJECT
public:
explicit MenuBar(QWidget *parent = 0);
virtual ~MenuBar();
public slots:
void slot_update_pos();
void slot_animation_changed(QVariant);
void slot_lenght_animation(QVariant);
void slot_animation_finshed();
void slot_enter();
void slot_leave();
protected:
void paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPen pen;
pen.setColor(Qt::red);
pen.setWidth(2);
painter.setPen(pen);
painter.drawLine(QPoint(m_x_value + m_offset, m_pos.y() + m_high + 2), QPoint(m_x_value + m_line_lenght + m_offset, m_pos.y() + m_high + 2));
}
private:
QPropertyAnimation *m_pos_animation;
QPropertyAnimation *m_lenght_animation;
QPoint m_pos;
int m_x_value;
int m_line_lenght;
int m_text_lenght;
int m_button_lenght;
int m_high;
int m_offset;
QPushButton *m_current_button;
bool is_animotion_finished;
bool is_enter;
};
#endif // MENU_BAR_H
1.这里通过offerset 和line_lenght来控制下划线的长度的变化
2.通过x_value来控制下滑线位置的变化。
3.通过Animation来做动画效果。(这里其实通过定时器也可以达到一样的效果,Animation底层的实现也是通过定时器)
MenuBar.cc
#include "menu_bar.h"
#include
#include
#include
#include
MenuBar::MenuBar(QWidget *parent):
QWidget(parent),
m_pos(0, 0),
m_x_value(0),
m_line_lenght(0),
m_text_lenght(0),
m_button_lenght(0),
m_high(0),
m_offset(0),
m_current_button(NULL),
is_animotion_finished(false),
is_enter(false)
{
setParent(parent);
setFixedHeight(30);
m_pos_animation = new QPropertyAnimation(this,"");
m_pos_animation->setDuration(100);
m_pos_animation->setEasingCurve(QEasingCurve::InQuad);
connect(m_pos_animation, SIGNAL(valueChanged(QVariant)), this, SLOT(slot_animation_changed(QVariant)));
connect(m_pos_animation, SIGNAL(finished()), this, SLOT(slot_animation_finshed()));
m_lenght_animation = new QPropertyAnimation(this,"");
m_lenght_animation->setDuration(100);
m_lenght_animation->setEasingCurve(QEasingCurve::InQuad);
connect(m_lenght_animation, SIGNAL(valueChanged(QVariant)), this, SLOT(slot_lenght_animation(QVariant)));
setAutoFillBackground(true);
QPalette palet = this->palette();
palet.setColor(QPalette::Background, QColor(233, 233, 233));
setPalette(palet);
}
MenuBar::~MenuBar()
{
}
void MenuBar::slot_update_pos()
{
m_current_button = static_cast (sender());
m_pos_animation->setStartValue(m_pos.x());
m_pos_animation->setEndValue(m_current_button->pos().x());
is_animotion_finished = false;
m_pos_animation->start();
m_pos = m_current_button->pos();
m_button_lenght = m_current_button->width();
m_high = m_current_button->height();
m_line_lenght = m_button_lenght;
QFont font;
QFontMetrics fm(font);
m_text_lenght = fm.width(m_current_button->text());
m_offset = 0;
}
void MenuBar::slot_animation_changed(QVariant data)
{
m_x_value = data.toInt();
update();
}
void MenuBar::slot_lenght_animation(QVariant data)
{
m_line_lenght = data.toPoint().x();
m_offset = data.toPoint().y();
update();
}
void MenuBar::slot_animation_finshed()
{
is_animotion_finished = true;
// add the flag in order to updata pos animation and lenght animotion (when run two animation as the sametime will be confict)
if(!is_enter)
{
m_lenght_animation->setStartValue(QPoint (m_button_lenght, 0));
m_lenght_animation->setEndValue(QPoint(m_text_lenght, (m_button_lenght - m_text_lenght) / 2));
m_lenght_animation->start();
}
}
void MenuBar::slot_enter()
{
QPushButton *button = static_cast (sender());
is_enter = true;
if ((button == m_current_button) && is_animotion_finished)
{
m_lenght_animation->setStartValue(QPoint(m_text_lenght, (m_button_lenght - m_text_lenght) / 2));
m_lenght_animation->setEndValue(QPoint(m_button_lenght, 0));
m_lenght_animation->start();
}
}
void MenuBar::slot_leave()
{
is_enter = false;
QPushButton *button = static_cast (sender());
if ((m_current_button == button) && is_animotion_finished)
{
m_lenght_animation->setStartValue(QPoint (m_button_lenght, 0));
m_lenght_animation->setEndValue(QPoint(m_text_lenght, (m_button_lenght - m_text_lenght) / 2));
m_lenght_animation->start();
}
}
通过Menubar上button的pos来计算相关值的变化。
代码源码地址:https://download.csdn.net/download/mario_z/11224710