QT仿照Word的滑动菜单以及菜单下拉框(1)(滑动导航条)

仿照work的界面的滑动菜单(1)

先上图:

这个功能的实现包括两个重要的部分,第一个是菜单条的文字下面的滑动伸缩线。第二个是菜单下拉框的动画效果,以及下拉框的上浮,下沉的效果。

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

 

 

 

 

 

你可能感兴趣的:(Qt控件系列)