QTabBar关闭按钮最下端文字从上到下显示

效果图

在这里插入图片描述
实现的效果有tab页文字从上到下显示,如果超出规定长度显示省略号,关闭按钮在最下端。原理是通过继承QTabBar重写tabSizeHint paintEvent mousePressEvent等函数来实现的。因为QTabWidget的setTabBar函数权限是protect,所以要想使用必须在自定义一个QTabWidget

关键代码

CustomTabBar.cpp

#include "CustomTabBar.h"
#include <QPainter>
#include <QDebug>

#define TAB_WIDTH 30
#define TAB_HEIGHT 120
#define PIXMAP_WIDTH 16
#define PIXMAP_HEIGHT 16
#define TEXTLABEL_TOP_MARGIN 8
#define PIXMAP_TOP_MARGIN 4
#define FACTOR 7

#define COLOR_HOVER         "#CDC9C9"
#define COLOR_SELECT_0      "#4F94CD"
#define COLOR_SELECT_1      "#EEB422"
#define COLOR_NORMAL_0      "#63B8FF"
#define COLOR_NORMAL_1      "#FFFF00"
#define COLOR_MARK          "#FF3333"

CustomTabBar::CustomTabBar(QWidget *parent) : QTabBar(parent)
{

}

QSize CustomTabBar::tabSizeHint(int index) const
{
    Q_UNUSED(index);
    return QSize(TAB_WIDTH,TAB_HEIGHT);
}

void CustomTabBar::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter p(this);
    for(int i = 0 ; i < count(); i++)
    {
        QRect rc = tabRect(i);

        QStyleOptionTabV2 option;
        initStyleOption(&option, i);

        //tab背景
        p.setPen(Qt::NoPen);
        if(QStyle::State_MouseOver & option.state)
        {
            p.setBrush(QColor(COLOR_HOVER));

        }
        else if(QStyle::State_Selected & option.state)
        {
            if(i == 0)
            {
                p.setBrush(QColor(COLOR_SELECT_0));
            }
            else if(i == 1)
            {
                p.setBrush(QColor(COLOR_SELECT_1));
            }
        }
        else
        {
            if(i == 0)
            {
                p.setBrush(QColor(COLOR_NORMAL_0));
            }
            else if(i == 1)
            {
                p.setBrush(QColor(COLOR_NORMAL_1));
            }
        }
        p.drawRect(rc);

        //tab文字
        p.setPen(Qt::black);
        p.setBrush(Qt::NoBrush);
        QRect textLabelRect = rc;
        //顶部间距8个像素
        textLabelRect.setY(rc.y() + TEXTLABEL_TOP_MARGIN);
        textLabelRect.setHeight(textLabelRect.height() - PIXMAP_HEIGHT - PIXMAP_TOP_MARGIN);
        QString showStr = tabText(i);
        showStr = getElidedText(QFont(), showStr, textLabelRect.height());
        showStr = showStr.split("",QString::SkipEmptyParts).join("\n");
        p.drawText(textLabelRect,Qt::AlignTop | Qt::AlignHCenter, showStr);
        //tab图片rect 16x16
        QRect imageRect(rc.x() + rc.width() / 2 - PIXMAP_WIDTH / 2, rc.y() + TEXTLABEL_TOP_MARGIN + textLabelRect.height() + PIXMAP_TOP_MARGIN, 16, 16);
        p.drawPixmap(imageRect, QPixmap(":/pic/close.png"));
    }
}

void CustomTabBar::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        int index = tabAt(event->pos());
        if(index != -1)
        {
            QRect rc = tabRect(index);
            //图片框 (rc.height() - PIXMAP_HEIGHT - PIXMAP_TOP_MARGIN - TEXTLABEL_TOP_MARGIN)是计算textLabelRect.height()
            QRect imageRect(rc.x() + rc.width() / 2 - PIXMAP_WIDTH / 2, rc.y() + TEXTLABEL_TOP_MARGIN + (rc.height() - PIXMAP_HEIGHT - PIXMAP_TOP_MARGIN - TEXTLABEL_TOP_MARGIN) + PIXMAP_TOP_MARGIN, PIXMAP_WIDTH, PIXMAP_HEIGHT);
            if(imageRect.contains(event->pos()))
            {
                emit tabCloseRequested(index);
            }
        }
    }
    QTabBar::mousePressEvent(event);
}

QString CustomTabBar::getElidedText(QFont font, QString str, int MaxWidth)
{
    if (str.isEmpty())
    {
        return "";
    }
    QFontMetrics fontWidth(font);
    //计算字符串宽度
    int width = fontWidth.width(str);
    //当字符串宽度大于最大宽度时进行转换
    if (width >= MaxWidth)
    {
        //右部显示省略号
        str = fontWidth.elidedText(str, Qt::ElideRight, MaxWidth);
    }
    //返回处理后的字符串
    return str;
}

CustomTabBar.h

#ifndef CUSTOMTABBAR_H
#define CUSTOMTABBAR_H

#include <QtWidgets>
#include <QTabBar>

class CustomTabBar : public QTabBar
{
    Q_OBJECT
public:
    explicit CustomTabBar(QWidget *parent = nullptr);
protected:
    QSize tabSizeHint(int index) const override;
    void paintEvent(QPaintEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
private:
    QString getElidedText(QFont font, QString str, int MaxWidth);
};

#endif // CUSTOMTABBAR_H

CustomTabWidget.cpp

#include "CustomTabWidget.h"
#include "CustomTabBar.h"

CustomTabWidget::CustomTabWidget(QWidget *parent) : QTabWidget(parent)
{
    setTabBar(new CustomTabBar(this));
}

CustomTabWidget.h

#ifndef CUSTOMTABWIDGET_H
#define CUSTOMTABWIDGET_H

#include <QWidget>
#include <QTabWidget>

class CustomTabWidget : public QTabWidget
{
    Q_OBJECT
public:
    explicit CustomTabWidget(QWidget *parent = nullptr);
};

#endif // CUSTOMTABWIDGET_H

然后使用自定义的CustomTabWidget即可

码云下载

CustomTabBar

参考文章

改造QTabWidget的QTabBar,自绘随意控制样式,不同颜色

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值