前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >美化QTabWidget[通俗易懂]

美化QTabWidget[通俗易懂]

作者头像
全栈程序员站长
发布2022-11-09 20:49:32
1.3K0
发布2022-11-09 20:49:32
举报

大家好,又见面了,我是你们的朋友全栈君。

美化QTabWidget

1.效果展示

在这里插入图片描述
在这里插入图片描述

2.用法展示

代码语言:javascript
复制
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{ 

ui->setupUi(this);
setupUI();
ui->tabWidget->addTab2(new QWidget(), tr("this is first tab"));
}
MainWindow::~MainWindow()
{ 

delete ui;
}
void MainWindow::setupUI()
{ 

connect(ui->tabWidget, SIGNAL(TabInserted(int)), this, SLOT(OnTabInserted(int)));
connect(ui->tabWidget, SIGNAL(AddBtnClicked()), this, SLOT(OnAddBtnClicked()));
connect(ui->tabWidget, SIGNAL(TabClosed(int)), this, SLOT(OnCloseTab(int)));
}
void MainWindow::OnTabInserted(int index)
{ 

QPushButton *button = new QPushButton();
button->setFixedSize(this->iconSize());
button->setStyleSheet("border-image: url(:/images/x-capture-options.png);");
ui->tabWidget->setTabButton2(index, QTabBar::LeftSide, button);
button = new QPushButton();
button->setStyleSheet("QPushButton{border-image: url(:/images/close.png)}"
"QPushButton:hover{border-image: url(:/images/close_hover.png)}");
ui->tabWidget->setTabButton2(index, QTabBar::RightSide, button);
}
void MainWindow::OnTabClosed(int index)
{ 

//todo something
}
void MainWindow::OnAddBtnClicked()
{ 

ui->tabWidget->addTab2(new QWidget(), tr("this is first tab"));
}

3.原理简介

主要原理就是对paintEvent重写,以及QProxyStyle继承重新实现。我也是翻了很多资料,看了实现的源码才知道的。

  • QExtTabBarStyle继承自QProxyStyle
代码语言:javascript
复制
void QExtTabBarStyle::drawPrimitive(PrimitiveElement pe, 
const QStyleOption *option, 
QPainter *painter,
const QWidget *widget) const
{ 

if (pe == QStyle::PE_IndicatorArrowLeft) { 

drawArrow(pe, option, painter, widget);
} else if (pe == QStyle::PE_IndicatorArrowRight) { 

drawArrow(pe, option, painter, widget);
} else{ 

QProxyStyle::drawPrimitive(pe, option, painter, widget);
}
}
int QExtTabBarStyle::pixelMetric(PixelMetric metric, 
const QStyleOption *option, 
const QWidget *widget) const
{ 

if (PM_TabBarScrollButtonWidth == metric) { 

return 30;
} else { 

return QProxyStyle::pixelMetric(metric, option, widget);
}
}
QRect QExtTabBarStyle::subElementRect(SubElement element, 
const QStyleOption *option, 
const QWidget *widget) const
{ 

if (SE_TabBarTabLeftButton == element) { 

return calcIconRect(true, option);
} else if (SE_TabBarTabRightButton == element) { 

return calcIconRect(false, option);
} else { 

return QProxyStyle::subElementRect(element, option, widget);
}
}
QRect QExtTabBarStyle::calcIconRect(bool left, const QStyleOption *option) const
{ 

const QStyleOptionTab *tab_option = qstyleoption_cast<const QStyleOptionTab *>(option);
QSize icon_size = tab_option->iconSize;
const QRect tab_rect = tab_option->rect;
QPoint center_pos;
QRect button_rect;
const int icon_padding = 8;
if (left) { 

center_pos = QPoint(icon_padding+icon_size.width()/2+tab_rect.x(), 
tab_rect.y()+(tab_rect.height()-icon_size.height())/2+icon_size.height()/2);
} else { 

center_pos = QPoint(tab_rect.x()+tab_rect.width()-icon_padding-icon_size.width()/2, 
tab_rect.y()+(tab_rect.height()-icon_size.height())/2+icon_size.height()/2);
}
button_rect = QRect(QPoint(0, 0), icon_size);
button_rect.moveCenter(center_pos);
return button_rect;
}
void QExtTabBarStyle::drawArrow(PrimitiveElement pe, const QStyleOption *option, 
QPainter *painter,
const QWidget *widget) const
{ 

const QToolButton *tool_btn = static_cast<const QToolButton *>(widget);
if (nullptr != tool_btn && !tool_btn->isVisible()) 
return;
painter->save();
const QStyleOptionTab *tab_option = qstyleoption_cast<const QStyleOptionTab *>(option);
QBrush rect_brush;
if (!tool_btn->isEnabled()) { 

rect_brush = Qt::transparent;
} else if (tool_btn->underMouse()) { 

rect_brush = QColor(214, 214, 214);
} else { 

rect_brush = Qt::transparent;
}
QRect draw_rect = QRect(0, 0, 16, 16);
draw_rect.moveCenter(option->rect.center());
RoundShadowHelper round_helper;
round_helper.FillRoundShadow(painter, option->rect,rect_brush.color(), 4);
painter->restore();
QProxyStyle::drawPrimitive(pe, option, painter, widget);
}
  • QTabBar中的paintEvent重写
代码语言:javascript
复制
void QtExtTabBar::paintEvent(QPaintEvent *event)
{ 

QPainter painter(this);
drawTab(&painter);
if (tab_add_button_.draw_plus_btn_)
drawPlusBtn(&painter);
}
void QtExtTabBar::drawTab(QPainter *painter)
{ 

RoundShadowHelper helper(6,4);
int border = helper.GetShadowWidth()/2.0;
painter->save();
int tab_count = tab_add_button_.draw_plus_btn_ ? count()-1 : count();
QStyleOptionTabV3 option;
for (int index = 0; index < tab_count; index++) { 

QRect rect = tabRect(index);
initStyleOption(&option, index);
// draw background 
QRect draw_rect = QRect(QPoint(rect.x()+border, rect.y() + border), QSize(rect.width()-border*2, rect.height()-border*2));
drawTabBg(painter, helper, option, draw_rect, rect);
drawTabText(painter, draw_rect, option);
}
painter->restore();
}
void QtExtTabBar::drawTabText(QPainter *painter, const QRect &draw_rect, const QStyleOptionTabV3 &option)
{ 

// draw text
QColor text_color = tb_text_color_.Normal_;
QRect text_rect = draw_rect.marginsAdded(margins_);
if (QStyle::State_Selected & option.state) { 

text_color = tb_text_color_.Selected_;
} else if (QStyle::State_MouseOver & option.state) { 

text_color = tb_text_color_.Hover_;
}
painter->setPen(text_color);
QString text = fontMetrics().elidedText(option.text, Qt::ElideRight, text_rect.width(), 0); 
painter->drawText(text_rect, Qt::AlignLeft | Qt::AlignVCenter, text);
}
void QtExtTabBar::drawTabBg(QPainter *painter, RoundShadowHelper &helper, 
const QStyleOptionTabV3 &option, QRect draw_rect, QRect real_rect)
{ 

painter->setPen(Qt::NoPen);
if(QStyle::State_Selected & option.state) { 

helper.RoundShadow(painter, real_rect);
helper.FillRoundShadow(painter, draw_rect, tb_bg_color_.Selected_, helper.GetRadius());
} else if(QStyle::State_MouseOver & option.state) { 

helper.FillRoundShadow(painter, draw_rect, tb_bg_color_.Hover_, helper.GetRadius());
}
}
void QtExtTabBar::drawPlusBtn(QPainter *painter)
{ 

painter->save();
int last_index = count()-1;
QStyleOptionTabV3 option;
initStyleOption(&option, last_index);
QRect draw_rect = QRect(QPoint(0, 0), tab_add_button_.tab_add_btn_size_);
draw_rect.moveCenter(tabRect(last_index).center());
DrawCircle::Draw(painter, draw_rect, tab_btn_add_color_);
DrawCharacter::DrawPlus(painter, draw_rect);
painter->restore();
}

4.属性设置

  • 可以自定义tab中的左右button。
  • 可以自定义tab中文字的颜色。
  • 可以设置是否需要绘制“+”按钮。

其他的都可以在代码中找到

5.todo list

  • 不支持tab拖拽
  • 不支持tab, tab button 贴图。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/190078.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月24日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 美化QTabWidget
    • 1.效果展示
      • 2.用法展示
        • 3.原理简介
          • 4.属性设置
            • 5.todo list
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档