当前位置: 首页 > article >正文

Qt放Element网页滑动菜单栏

基于QTabWidget实现菜单

tabwidget.h

#ifndef TAB_WIDGET_H
#define TAB_WIDGET_H

#include <QTabWidget>
#include <QVariantAnimation>
#include "customcomponent_global.h"

class TabBarAnimation;

class TabWidget : public QTabWidget
{
    Q_OBJECT

public:
    InoTabWidget(QWidget *parent = 0);
    ~InoTabWidget();

    void setAnimationCurrentValue(int value);

protected:
    void paintEvent(QPaintEvent *);
    bool eventFilter(QObject *o, QEvent *e);

private:
    void startAnimation(int beginX, int endX, int duration);

private:
    TabBarAnimation *m_animation;
    int m_animationX;
};

#endif

tabwidget.cpp

#include "tabwidget.h"
#include <QStyleOptionTabWidgetFrame>
#include <QStylePainter>
#include <QMouseEvent>

const int AnimateBarWidth = 64;
const int AnimateBarHeight = 2;
const int AnimateBarXOffset = 30;

const int LogoWidth = 140;
const int LogoHeight = 20;

class TabBarAnimation : public QVariantAnimation
{
public:
    TabBarAnimation(InoTabWidget *t) :
        tabs(t)
    {
        setEasingCurve(QEasingCurve::InOutQuad);
    }

    void updateCurrentValue(const QVariant &current) Q_DECL_OVERRIDE;

private:
    InoTabWidget *tabs;
};

void TabBarAnimation::updateCurrentValue(const QVariant &current)
{
    if (tabs) {
        tabs->setAnimationCurrentValue(current.toInt());
    }
}

TabWidget::TabWidget(QWidget *parent) :
    QTabWidget(parent),
    m_animation(nullptr),
    m_animationX(-1)
{
    tabBar()->installEventFilter(this);
    tabBar()->setFixedHeight(40);
}

TabWidget::~TabWidget()
{
    if (m_animation) {
        delete m_animation;
        m_animation = nullptr;
    }
}

bool TabWidget::eventFilter(QObject *obj, QEvent *event)
{
    if (obj == tabBar() && event->type() == QEvent::MouseButtonPress) {
        QMouseEvent *pMouseEvent = (QMouseEvent *)event;
        if (pMouseEvent->button() == Qt::LeftButton) {
            const QPoint pos = pMouseEvent->pos();
            int index = tabBar()->tabAt(pos);

            if (index >= 0) {
                int curIndex = tabBar()->currentIndex();
                if (index != curIndex) {
                    const QPoint tabBarPos = tabBar()->mapToGlobal(tabBar()->rect().topLeft());
                    startAnimation(tabBarPos.x() + tabBar()->tabRect(curIndex).x() + tabBar()->tabRect(curIndex).width() / 2 - AnimateBarXOffset,
                                   tabBarPos.x() + tabBar()->tabRect(index).x() + tabBar()->tabRect(index).width() / 2 - AnimateBarXOffset, 250);
                }
            }
        }
    }

    return false;
}

void TabWidget::startAnimation(int beginX, int endX, int duration)
{
    if (!m_animation) {
        m_animation = new TabBarAnimation(this);
    }

    m_animation->setStartValue(beginX);
    m_animation->setEndValue(endX);
    m_animation->setDuration(duration);
    m_animation->start();
}

void TabWidget::setAnimationCurrentValue(int value)
{
    m_animationX = value;
    update();
}

// 绘制背景下划线和当前Index的下划线
void TabWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    int index = tabBar()->currentIndex();
    QRect rect = tabBar()->tabRect(index);
    const QPoint tabBarPos = tabBar()->mapToGlobal(tabBar()->rect().topLeft());

    QStyleOptionTabWidgetFrame option;
    initStyleOption(&option);
    option.lineWidth = 0;
    QStylePainter p(this);
    option.rect = style()->subElementRect(QStyle::SE_TabWidgetTabPane, &option, this);
    p.drawPrimitive(QStyle::PE_FrameTabWidget, option);

    p.fillRect(QRect(option.rect.x(), rect.y(), option.rect.width(),
                     rect.y() + rect.height() + AnimateBarHeight * 2),
               QColor(41, 90, 176));
    int x = (m_animation && m_animation->state() == QAbstractAnimation::Running) ?
                m_animationX :
                (tabBarPos.x() + rect.x() + rect.width() / 2 - AnimateBarXOffset);
    p.fillRect(QRect(x, rect.y() + rect.height(),
                     AnimateBarWidth, AnimateBarHeight),
               QColor(255, 255, 255));
}


http://www.kler.cn/news/292789.html

相关文章:

  • Quartz.Net_快速开始
  • ​如何通过Kimi强化论文写作中的数据分析?
  • CommonJS与ESModule标准
  • 企业在选择CRM系统时需要注意哪些问题呼叫系统外呼系统部署搭建
  • FPGA第 9 篇,Verilog 中的关键字和基数
  • kuka6轴机器人配置外部启动信号(学习记录,可能不对)
  • Spring框架中的循环依赖详解以及解决方案
  • html初体验之hello world
  • 【前端面试】标记、绘画视频的某一帧
  • 微信小程序webgl 显示图片
  • 121.rk3399 uboot(2017.09) 源码分析1(2024-09-05)
  • Xilinx高速接口文档简介
  • 【机器人工具箱Robotics Toolbox开发笔记(七)】 创建机器人连杆对象
  • Docker in Docker 实践 on mac
  • 苹果手机之间如何互传文件?简单又高效的选择
  • Redis(Remote Dictionary Server)
  • pod控制器:
  • 【2024数模国赛赛题思路公开】国赛C题第三套思路丨无偿自提
  • Java项目:128 基于Spring Boot的装饰工程管理系统
  • 机器学习——决策树模型
  • TensorFlow-keras介绍(一)
  • 如何在极狐GitLab中添加 SSH Key?
  • Ubuntu固定USB串口名(包括1拖N的USB串口)
  • 系统架构师考试学习笔记第三篇——架构设计高级知识(17)云原生架构设计理论与实践
  • Echart 环形图 特殊字体 富文本
  • excel透视图、看板案例(超详细)
  • 基于SringBoot框架的智慧博物馆预约平台
  • ChatGPT 调教教程
  • 人工智能主要是学什么的?
  • 过滤器(Filter)和拦截器(Interceptor)