Qt绘制chrome风格的Tab标签

本文介绍如何使用Qt的QStyle自定义多标签浏览器的Tab样式,实现类似Chrome风格的标签栏,包括修改控件大小、绘制样式等细节。

前言

Qt中改变现有的控件的外观有多种方式,最常见的是使用样式表,根据样式表中的各种选择器并对属性、状态和sub-control进行样式的修改,也是比较方便的方式。最近由于要使用cef进行一个多标签浏览器的开发,需要修改tab的外观,这里使用QStyle来进行修改。

QStyle

Qt中对于QStyle的简单描述
简单来说就是Qstyle是一个抽象类,封装了不同平台上的GUI的外观。对于QStyle的详细介绍,请参考其他的资料或者Qt的帮助文档,百度一大堆。
QProxyStyle实现了QStyle所有的抽象接口,并且默认保持系统风格。

这里我们继承一个QProxStyle,然后实现其中两个接口便可实现。
第一个是sizeFromContent,返回控件的大小,函数原型如下:


virtual QSize sizeFromContents(ContentsType type, const QStyleOptio *option, const QSize &size, const QWidget *widget) const

第二个是drawControl,用于绘制控件的元素。函数原型如下:


virtual void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = Q_NULLPTR) const

效果图

设置后的效果图
效果图2

绘制代码中的思路

比较笨的控制大小,数格子!!
由windows自带的画图数格子,然后用整体的大小确定比例,用比例绘制比较妥。
在这里插入图片描述

方式1

很明显了吧,
方式1

方式2

其实和方式1一样,只是椭圆不一样。高度比较小的时候,两者看着都差不多,我都试过。
方式2

方式3

二次贝塞尔曲线,就很简单。绘制出来可以说和chome基本一样
效果:
方式3效果
代码:

void Widget::drawShape1(QPainter *p, const QRect &drawRect)
{
   
   
    QRectF r(drawRect);

    qreal per = r.height() / 8.0;
    qreal topMargin = 4.0;

    QPainterPath path;
    path.moveTo(r.bottomLeft() - QPointF(per, 0));
    path.quadTo(QPointF(r.left(), r.bottom()),
                QPointF(r.left(), r.bottom() - per));
    path.lineTo(r.left(), r.top() + per + topMargin);
    path.quadTo(QPointF(r.left() , r.top() + topMargin),
                QPointF(r.left() +  per, r.top() + topMargin));
    path.lineTo(r.right() - per, r.top() + topMargin);
    path.quadTo(QPointF(r.right(), r.top() + topMargin),
                QPointF(r.right(), r.top() + per + topMargin));
    path.lineTo(r.right(), r.bottom() - per);
    path.quadTo(QPointF(r.right(), r.bottom()),
                r.bottomRight() + QPointF(per, 0));

    p->setRenderHint(QPainter::Antialiasing);
    p->setBrush(Qt::green);
    p->drawPath(path);
}

void Widget::drawShape2(QPainter *p, const QRect &drawRect)
{
   
   
    QRectF r(drawRect);

    qreal per = r.height() / 8.0;
    qreal topMargin = 4.0;

    QPainterPath path;
    path.moveTo(r.bottomLeft() + QPointF(per, 0));
    path.quadTo(QPointF(r.left(), r.bottom()),
                QPointF(r.left(), r.bottom() - per));
    path.lineTo(r.left(), r.top() + per + topMargin);
    path.quadTo(QPointF(r.left(), r.top()
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值