首页 > 其他分享 >Qt绘制圆角矩形的内发光或外发光效果

Qt绘制圆角矩形的内发光或外发光效果

时间:2023-11-04 19:44:18浏览次数:30  
标签:pixmap pp pq Qt background 或外 发光 QPainter

Qt没有内置的发光效果,只有一个QGraphicsDropShadowEffect类可以对整个控件产生阴影(可近似为外发光)效果。此处作者整理了如何用QPainter手工绘制形状的内发光或外发光效果。本文主要涉及到QPainter类中的图像混合模式技巧。下面允许我把Qt帮助中的内容复制过来供参考。

调用QPainter::setCompositionMode(...)方法可以对两个图像应用不同的混合方法。Qt默认的是Blend混合。混合过程中完全透明的像素作为“无”处理。请特别注意,CompositionMode是针对两个图像的混合,因此它的Destination和Source都应该是图像,尽量不要是QWidget。否则可能出现一些意外的效果。根据作者的理解应用混合模式的典型代码如下:

void main()
{
    QPixmap background(w, h); /* Destination图片 */
    background.fill(Qt::transparent);
    QPainter pq(&background);
    ...

    QPixmap pixmap(w, h); /* Source图片 */
    pixmap.fill(Qt::transparent);
    QPainter pp(&pixmap);
    ...

    pq.setCompositionMode(QPainter::CompositionMode_DestinationOver); /* 设置混合模式 */
    pq.drawPixmap(0, 0, pixmap);
}

一、内发光效果

这里实现的是一个控件里绘制一个圆角矩形,然后对圆角矩形绘制内发光的效果。整体上是绿色背景,粉色的光影。测试环境是VS2017和Qt5.9。

头文件:

class MLighting : public QWidget
{
    Q_OBJECT

public:
    MLighting(QWidget* parent = 0);

private:
    void paintEvent(QPaintEvent *event) override;
};

CPP文件:

MLighting::MLighting(QWidget* parent) : 
    QWidget(parent)
{
}

void MLighting::paintEvent(QPaintEvent *event)
{
    int w = width();
    int h = height();

    QPixmap background(w, h);
    background.fill(Qt::transparent);
    QPainter pq(&background);
    pq.setRenderHint(QPainter::Antialiasing);
    pq.setPen(Qt::NoPen);
    pq.setBrush(Qt::darkGreen);
    pq.drawRoundedRect(4, 4, w - 8, h - 8, 8, 8);

    QPixmap pixmap(w, h);
    pixmap.fill(Qt::transparent);
    QPainter pp(&pixmap);
    pp.setRenderHint(QPainter::Antialiasing);
    pp.setBrush(Qt::NoBrush);
    for (int p = 8; p >= 1; p -= 2)
    {
        pp.setPen(QPen(QColor(243, 163, 253, 64), p));
        pp.drawRoundedRect(4, 4, w - 8, h - 8, 8, 8);
    }

    pq.setCompositionMode(QPainter::CompositionMode_SourceAtop);
    pq.drawPixmap(0, 0, pixmap);

    QPainter painter(this);
    painter.drawPixmap(0, 0, background);
}

这里采用的混合模式是CompositionMode_SourceAtop,此模式将Source图像放在最上方并且超出Destination图像的范围外的部分会被裁剪掉。

二、外发光效果

整个代码与内发光差不多。效果图如下:

头文件:

class MLighting : public QWidget
{
    Q_OBJECT

public:
    MLighting(QWidget* parent = 0);

private:
    void paintEvent(QPaintEvent *event) override;
};

CPP文件:

MLighting::MLighting(QWidget* parent) : 
    QWidget(parent)
{
}

void MLighting::paintEvent(QPaintEvent *event)
{
    int w = width();
    int h = height();

    QPixmap background(w, h);
    background.fill(Qt::transparent);
    QPainter pq(&background);
    pq.setRenderHint(QPainter::Antialiasing);
    pq.setPen(Qt::NoPen);
    pq.setBrush(Qt::darkGreen);
    pq.drawRoundedRect(4, 4, w - 8, h - 8, 8, 8);

    QPixmap pixmap(w, h);
    pixmap.fill(Qt::transparent);
    QPainter pp(&pixmap);
    pp.setRenderHint(QPainter::Antialiasing);
    pp.setBrush(Qt::NoBrush);
    for (int p = 8; p >= 1; p -= 2)
    {
        pp.setPen(QPen(QColor(243, 163, 253, 64), p));
        pp.drawRoundedRect(4, 4, w - 8, h - 8, 8, 8);
    }

    pq.setCompositionMode(QPainter::CompositionMode_DestinationOver);
    pq.drawPixmap(0, 0, pixmap);

    QPainter painter(this);
    painter.drawPixmap(0, 0, background);
}

这里采用的是CompositionMode_DestinationOver模式。此模式会将Destination图像放在上方,而Source图像放在下面混合。

标签:pixmap,pp,pq,Qt,background,或外,发光,QPainter
From: https://www.cnblogs.com/mengxiangdu/p/17807104.html

相关文章

  • PyQt5-16 屏幕坐标系的了解和基本使用
    (16什么是屏幕坐标系?)1什么是屏幕坐标系?2相关概念屏幕坐标系,即窗口相对于屏幕的坐标。屏幕左上角坐标称为原点坐标(0,0);窗口的坐标,即窗口的左上角相对原来的坐标,如下图示:窗口的宽和高也有两种,一种是工作取的高度,一种菜单栏的高度,比如如下说明:3代码实现创建一个窗口,......
  • Golang使用mqtt
    示例使用使用EMQX提供的免费公共MQTT服务器,该服务基于EMQX的MQTT物联网云平台创建。服务器接入信息如下:Broker:broker.emqx.ioTCPPort:1883WebsocketPort:8083golang代码如下packagemainimport( "fmt" mqtt"github.com/eclipse/paho.mqtt.golang" "time......
  • qt---主进程加载一个子进程的方法以及其中遇到“Calling a private constructor of cl
    .proQT+=coreguigreaterThan(QT_MAJOR_VERSION,4):QT+=widgetsCONFIG+=c++17#YoucanmakeyourcodefailtocompileifitusesdeprecatedAPIs.#Inordertodoso,uncommentthefollowingline.#DEFINES+=QT_DISABLE_DEPRECATED_BEFORE=0......
  • QT + OPENCV + OpenCV_contrib + MINGW编译
    参见  QT+OPENCV+OpenCV_contrib+MINGW编译_东方.既白的博客-CSDN博客注意事项:1. opencv不要采用版本太高的,与mingw730_64编译器不兼容。太多错误2. ......
  • 二十六、QT发送http请求并解析返回的json数据
    1.使用的模块和类模块:network类:QNetworkAccessManager、QNetworkRequest、QNetworkReply、QJsonDocument、QJsonObject、QJsonArrayQSslSocket::sslLibraryBuildVersionString();:查看当前使用的ssl版本,访问HTTPS时需要使用、复制libcrypto-1_1-x64.dll和libssl-1_1......
  • Qt 6.5.2 下 QGraphicsView 中使用触控手势的问题
    自定义的QGraphicsView中加入setScene后,其它Gesture能够触发,但QPanGesture不能在场景中触发。而空白QGraphicsView(QWidget)则可以正常触发PanGesture手势……源码和文档中都已经说明,gesture是给QGraphicsObject使用的……但我们就是想使用PanGesture手势来操作场景拖动……这可......
  • QT使用QML实现地图绘制虚线
    QML提供了MapPolyline用于在地图上绘制线段,该线段是实线,因此我使用Canvas自定义绘制的方式在地图上绘制线段,如图:鼠标在地图上点击后,在点击位置添加图标,当有多个图标被添加到地图上后,计算各个图标间的距离,并创建一个新的虚线线段组件,连接两个图标点,显示距离数值。如果对自定义图标......
  • Qt开发实现字幕滚动效果
    1、效果展示我们经常能够在外面看到那种滚动字幕,那么就拿qt来做一个吧。2、实现思路实现一个窗口部件,这个窗口部件显示了一串文本标语,它会每t毫秒向左移动一个像素。如果窗口部件比文本宽,那么文本将会被多次重复,直到能够填满整个窗口部件的宽度为止。3、滚动窗口部件创建一个滚......
  • Qt3D改变观察视角例程(二)
    本例依旧是改变3D视角。不同的是这个是视野位置不变而只改变观察方向。相当于一个人站在原地不动,旋转脑袋看周围的东西。测试的条件是VS2017和Qt5.9。主要的知识点就是欧拉角的计算。下面是效果图:头文件:classQOpenGLTexture;classQOpenGLBuffer;classMvOpenGLWidget:p......
  • PyQt5-如何设置主窗口居中?退出应用程序如何操作?
    (15如何设置主窗口居中?退出应用程序如何操作?)1如何实现主窗口居中显示?让主窗口居中,其实就是让窗口的左右边缘到左右屏幕距离相等,让窗口的上下边缘到上下屏幕的距离相等;主要是需要进行计算和移动工作;可以使用QDesktopWidget类来获取屏幕的大小和位置信息,然后根据这些信息计......