美化QTabWidget[通俗易懂]

美化QTabWidget[通俗易懂]美化QTabWidget1.效果展示2.用法展示MainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui->setupUi(this);setupUI();ui->tabWidget->addTab2(newQWidget(),tr(“thisisfirsttab”));}MainWindo

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

美化QTabWidget

在这里插入图片描述

1.效果展示

在这里插入图片描述

2.用法展示

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
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重写
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 贴图。

关注微信公众号,获取源码。

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • FineCMS介绍

    FineCMS介绍

  • java 零拷贝_java深拷贝

    java 零拷贝_java深拷贝在传统的数据IO模式中,读取一个磁盘文件,并发送到远程端的服务,就共有四次用户空间与内核空间的上下文切换,四次数据复制,分别是两次CPU数据复制,两次DMA数据复制。零拷贝指在进行数据IO或传输时,数据在用户态下经历了零次拷贝,并非不拷贝数据。通过减少数据传输过程中内核缓冲区和用户进程缓冲区间不必要的CPU数据拷贝与用户态和内核态的上下文切换次数,降低CPU在这两方面的开销,释放CPU执行其他任务,更有效的利用系统资源,提高传输效率,同时还减少了内存的占用,提升应用程序的性能

  • python 字符串去空格

    python 字符串去空格一、去除字符串空格,在Python里面有它的内置方法lstrip:删除左边的空格这个字符串方法,会删除字符串s开始位置前的空格。>>>s.lstrip()’string’rstrip:删除右连的空格这个内置方法可以删除字符串末尾的所有空格,看下面演示代码:>>>s.rstrip()’string’strip:删除两端的空格有的时候我们读取文件中的内容,每行2边都有空

  • 获取和分析Dump的几种工具简介[通俗易懂]

    获取和分析Dump的几种工具简介[通俗易懂]最近在进一步学习support技能的时候,了解到分析Dump的重要性,经过学习,做一些笔记。一、什么是Dump文件。Dump文件时进程的内存镜像。可以把程序的执行状态保存到Dump文件中。Dump文件分为内核模式Dump和用户模式Dump。其中内核模式Dump是操作系统创建的崩溃转储,例如蓝屏Dump。而在我们调试或Troubleshooting过程中使用的Dump是用户模式Dump,又分为F…

  • 推荐一个好的Redis GUI 客户端工具

    推荐一个好的Redis GUI 客户端工具

  • windows 设置定时锁屏

    windows 设置定时锁屏设置间隔指定时间电脑自动锁屏CreateTime–2017年7月3日10:16:14Author:Marydon参考地址:电脑爱好者杂志举例:实现每间隔45分钟,电脑自动锁屏实现思路:  第一步:编写锁屏命令;  第二步:制定计划。实践:  1.编写锁屏命令    新建一个txt文件,重命名为:lockScreen(名字随意)–>打开该文件添…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号