重载QTabBar实现进度条功能

怎么样,还行吧?

下面请出核心君~~~掌声!!!

/*
    作者:侯文斌
    E-mail:houwenbin1986@gmail.com
    注:请尊重原作者劳动成果,仅供学习使用,请勿盗用,违者必究!
*/

#ifndef AEQUILATETABBAR_H
#define AEQUILATETABBAR_H

#include <QTabBar>
#include <QProxyStyle>
#include <QStyleOption>
#include <QPainter>

//自定义Tab样式
class CustomTabStyle : public QProxyStyle
{
    Q_OBJECT
public:
    CustomTabStyle();
signals:
public slots:
    void setTabIndex(int index);
public:
    void setTabRect(int index, QRect rect);
public:
    void drawControl(ControlElement element, const QStyleOption *option,
        QPainter *painter, const QWidget *widget) const;
private:
    QMap<int,QRect> m_tabRect;
    int m_currentIndex;
};

//等宽TabBar控件类
class AequilateTabBar : public QTabBar
{
    Q_OBJECT
public:
    explicit AequilateTabBar(QWidget *parent = 0);
public:
    void setTabWidth(int value);
    void setTabHeight(int value);
protected:
    QSize tabSizeHint (int index) const;
    void paintEvent(QPaintEvent *);
private:
    void bindEvent();
private:
	int height;
    CustomTabStyle* myCustomTabStyle;
};

#endif // AEQUILATETABBAR_H




/*
    作者:侯文斌
    E-mail:houwenbin1986@gmail.com
    注:请尊重原作者劳动成果,仅供学习使用,请勿盗用,违者必究!
*/
#include "aequilatetabbar.h"
#include <QDebug>

//----------------------------------------------------------------//
// QStyle
CustomTabStyle::CustomTabStyle()
{
    m_currentIndex = 0;
}

void CustomTabStyle::setTabRect(int index, QRect rect)
{
    m_tabRect[index] = rect;
}

void CustomTabStyle::setTabIndex(int index)
{
    m_currentIndex = index;
}

void CustomTabStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    if(element == CE_TabBarTabLabel)//Label
    {
        if(const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
        {
            QRect allRect = tab->rect;
            int r = 10, h=2;
            QPoint circleCenter = QPoint(allRect.left()+allRect.width()/2, allRect.bottom()-r-1);
            QRect lineRect = QRect(allRect.left(), allRect.bottom()-r-h, allRect.width(), 2*h);
            QRect circleRect = QRect(allRect.left()+allRect.width()/2-r, allRect.bottom()-2*r-1, 2*r, 2*r);

            painter->save();
            painter->setRenderHint(QPainter::Antialiasing, true);//反走样
            int tabIndex = 0;//当前第几步骤
            for(int i=0; i<m_tabRect.count(); i++)
            {
                if( allRect.contains(m_tabRect[i]) )
                {
                    tabIndex = i+1;
                    break;
                }
            }
            //绘制进度线条
            if (tab->state & QStyle::State_Selected || tabIndex<=m_currentIndex) {
                painter->setPen(0x3b98de);//蓝色
                painter->setBrush(QBrush(0x3b98de));
            } else {
                painter->setPen(0xb0b0b0);//灰色
                painter->setBrush(QBrush(0xb0b0b0));
            }
            painter->drawRect(lineRect);
            //绘制进度圆圈
            painter->drawEllipse(circleCenter, r, r);
            //绘制进度数字
            painter->setPen(0xffffff);
            painter->drawText(circleRect, Qt::AlignCenter, QString("%1").arg(tabIndex));
            //绘制Tab标题
            QTextOption txtoption;
            txtoption.setAlignment(Qt::AlignCenter);
            //if (tab->state & QStyle::State_Selected) {
                painter->setPen(0x333333);
            //} else {
                //painter->setPen(0xcdcdcd);
            //}
            painter->drawText(allRect.adjusted(0,0,-2*r,-2*r), tab->text, txtoption);
            painter->restore();
            return;
        }
    }
    else if(element == CE_TabBarTabShape)
    {
        if(const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
        {
            QRect bgRect = tab->rect;
            painter->save();
            painter->fillRect(bgRect, Qt::white);
            painter->restore();
            return;
        }
    }

    if(element == CE_TabBarTab)//Tab
    {
        QProxyStyle::drawControl(element, option, painter, widget);
    }
}

//----------------------------------------------------------------//
// TabBar
AequilateTabBar::AequilateTabBar(QWidget *parent)
    : QTabBar(parent), height(55)
{
    this->setContentsMargins(5,5,5,5);
    myCustomTabStyle = new CustomTabStyle();
    this->setStyle(myCustomTabStyle);
    this->bindEvent();
}

void AequilateTabBar::bindEvent()
{
    connect( this, SIGNAL(currentChanged(int)), myCustomTabStyle, SLOT(setTabIndex(int)) );
}

QSize AequilateTabBar::tabSizeHint(int index) const
{    
    int w = width()/count(); //等分宽度

    QSize newSize = QSize(width()/count(), height);
    QRect tabGeometry(QPoint(index*w, 0),  newSize);
    myCustomTabStyle->setTabRect(index, tabGeometry);

    return newSize;
}

void AequilateTabBar::paintEvent(QPaintEvent *e)
{
    QTabBar::paintEvent(e);

    //QPainter p(this);
    //p.fillRect(rect(), Qt::gray);
}

void AequilateTabBar::setTabWidth(int value)
{
    this->setFixedWidth(value-2);
}

void AequilateTabBar::setTabHeight(int value)
{
	height = value;
}


  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值