首页 > 其他分享 >关于在Qlabel遮罩方面的踩坑实录

关于在Qlabel遮罩方面的踩坑实录

时间:2024-09-18 15:52:28浏览次数:11  
标签:遮罩 mask Mask 实录 label QWidget include painter Qlabel

先看目标效果:

想要实现封面图标的遮罩效果,有两个思路:

一、在鼠标移动到这个item上面时,重新绘制pixmap

例如以下代码:

#include <QApplication>
#include <QWidget>
#include <QPixmap>
#include <QLabel>
#include <QPainter>
#include <QColor>

class TransparentOverlayWidget : public QWidget
{
public:
    TransparentOverlayWidget(QWidget *parent = nullptr) : QWidget(parent)
    {

        // 创建 QLabel 来显示带有半透明矩形的图像
        label = new QLabel(this);
        label->setFixedSize(500,500);
        label->setScaledContents(true);
    }
    void paintEvent(QPaintEvent *event) override {
        QWidget::paintEvent(event);
        pixmap = QPixmap("background.jpg");

        // 创建QPainter并在QPixmap上绘制
        QPainter painter(&pixmap);

        // 设置半透明度,0.0为完全透明,1.0为完全不透明
        painter.setOpacity(0.5);

        // 设置绘制颜色,带有透明度
        painter.setBrush(QColor(255, 0, 0, 127)); // 透明度为127,最大值是255
        painter.setPen(Qt::NoPen);
        if(m_isHover) {
            // 绘制一个半透明矩形
            painter.drawRect(50, 50, 200, 150);
        }

        // 完成绘制
        painter.end();
        label->setPixmap(pixmap);
    }
    void enterEvent(QEnterEvent *event) {
        QWidget::enterEvent(event);
        m_isHover = true;
        qDebug()<<"进入widget";
        update();
    }
    void leaveEvent(QEvent *event) {
        QWidget::leaveEvent(event);
        m_isHover = false;
        qDebug()<<"离开widget";
        update();
    }
private:
    bool m_isHover  = false;
    QLabel *label{};
    QPixmap pixmap;
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    TransparentOverlayWidget widget;
    widget.show();

    return app.exec();
}

值得注意的是:pixmap = QPixmap("background.jpg");这行代码的位置的考究。。。

每次绘制前重新初始化 :若是将这行代码放在构造函数里面就起不到透明的效果。原因如下:
确保在每次 paintEvent 时,QPixmap 都是初始的未被修改的图像,而不是之前被修改的版本。否则你可能会在一个已经绘制了半透明矩形的 QPixmap 上再次绘制半透明矩形,这会导致透明度的叠加不正确。

 二、新建Mask的QWidget类

Mask.h:

//
// Created by WeiWang on 24-9-18.
//

#ifndef MASK_H
#define MASK_H
#include<QWidget>
#include<QPainter>

class Mask : QWidget
{
public:
    Mask(QWidget *parent = nullptr):QWidget(parent) {
        setWindowFlags(Qt::FramelessWindowHint);
        this->setFixedSize(100,100);
    }
    void paintEvent(QPaintEvent *event) {
        QPainter painter(this);
        QColor color(0,0,0,160);
        // 设置绘制颜色,带有透明度
        painter.setBrush(color);
        painter.setPen(Qt::NoPen);
        painter.fillRect(rect(),color);
    }

    void move_(int x,int y){this->move(x,y);};
    void hide_(){ this->hide();};
    void show_(){ this->show();};
    void raise_(){ this->raise();};
};


#endif //MASK_H

main.cpp:

 #include <QApplication>
 #include <QWidget>
 #include <QPixmap>
 #include <QLabel>
 #include <QPainter>
 #include <QColor>
 #include "Mask.h"
 class TransparentOverlayWidget : public QWidget
 {
 public:
     TransparentOverlayWidget(QWidget *parent = nullptr)
     : QWidget(parent)
     {
         this->setFixedSize(500,500);
         // 加载图像
         QPixmap pixmap("F:\\code_review\\Qt-WorkSpace\\fight\\KuGouApp\\KuGouStart\\Res\\tabIcon\\music-cover.jpg");

         // 创建 QLabel 来显示带有半透明矩形的图像
         label = new QLabel(this);
         label->move(100,100);
         label->setScaledContents(true);
         label->setPixmap(pixmap);
         label->setFixedSize(100,100);
         label->setAlignment(Qt::AlignCenter);
         m_mask = new Mask(this);
         m_mask->move_(100,100);
         m_mask->hide_();
     }
     void paintEvent(QPaintEvent *event)override {
         if(this->m_isHover) {
             m_mask->show_();
            //m_mask->raise_();
         }
         else
             m_mask->hide_();
     }
     void enterEvent(QEnterEvent *event) {
         QWidget::enterEvent(event);
         qDebug()<<"进入widget";
         m_isHover = true;
         update();
     }
     void leaveEvent(QEvent *event) {
         QWidget::leaveEvent(event);
         qDebug()<<"离开widget";
         m_isHover = false;
         update();
     }
 private:
     QLabel *label{};
     bool m_isHover = false;

     Mask *m_mask{};
 };

 int main(int argc, char *argv[])
 {
     QApplication app(argc, argv);

     TransparentOverlayWidget widget;
     widget.show();

     return app.exec();
}

注意:此处有两个坑

①mask的初始化位置:

 一旦使用了如上图所示的初始化顺序,即先初始化mask再初始化lab,那么到了后面遮罩会被label挡住,原因如下:

在 Qt 中,子控件的绘制顺序遵循父控件的层次结构和堆叠顺序。默认情况下,父控件的子控件会按照其创建的顺序绘制。因此,如果 MaskTransparentOverlayWidget 的子控件,并且在层次结构中比 QLabel 更早创建或被覆盖,那么 QLabel 会在 Mask 之上绘制,导致 Mask 被遮住。

所以一定要让mask的初始化在label之后。

② 硬要在构造列表初始化

如果一定要在构造列表初始化的话,那么就需要使用

Mask 设置为在最顶层显示: 使用 raise() 函数将 Mask 移到顶层。

标签:遮罩,mask,Mask,实录,label,QWidget,include,painter,Qlabel
From: https://blog.csdn.net/m0_74091159/article/details/142330216

相关文章

  • 震惊!!一男子用尽了各种方式都搜不到这个资源,于是他竟然将手伸向了......!?pyqt pyside
    震惊!!一男子用尽了各种方式都搜不到这个资源,于是他竟然将手伸向了......!?pyqtpyside随窗口自适应、可缩放、拖动QLabel需求场景实现功能和使用1.参数设置2.设置图片3.缩放4.拖动5.小惊喜(裁剪图片)完整使用案例1.使用QtDesigner设计一个简单界面2.引用制......
  • 国产化:springboot项目TongWeb替换tomcat踩坑实录
    前言全流程记录Tongweb替换Tomcat过程,最终实现为使用内嵌的Tongweb依赖替换SpringBoot默认的Tomcat,所以可直接从第5节开始看如何使用内嵌TongWeb替换Tomcat。1背景国产化浪潮下,项目要求实现web服务器的国产化,使用Tongweb替换Tomcat,商业版的Tongweb是单独启动的一个服务,需要......
  • WiFiAp探究实录--功能实现与源码分析
    wifi热点说的是wifiAp相关,所以如果源码开发的话,这个WifiAp算是一个搜索代码的关键字,含义是WifiAccesspoint,wifi接入点。所以下文中的wifi热点统一用WifiAp代替wifiAp打开方式:设置->更多->移动网络共享->便携式wlan热点。wifiAp打开条件:任何情况下均可。只是有内网外网之分......
  • 旧笔记本安装Win8.1实录
    昨天发现一台尘封已久的LenovoideapadY550,给它装上了Windows10然后第二天系统挂掉了挂的原因是半夜万恶之源Windows更新开始造孽了刚好没电文件全坏了真解除封印因为文件已经没了我索性直接重装系统,降级到Win8.1真香!系统是Win8.1withupdate的精简版,开始菜单有关......
  • k8s安装v1.30.2(contanerd容器运行时)实录
    一、主机准备主机名NATIP系统配置k8s-master192.168.1.201ubuntu18.04.62C2Gk8s-node01192.168.1.202ubuntu18.04.62C2Gk8s-node02192.168.1.203ubuntu18.04.62C2G   二、前提主机配置好网络、ntp,关闭ufw,swap,安装好containerd,runc服务三......
  • Qt:10.显示类控件(QLabel-显示文本或图像的控件、QLCDNumber -显示数字的特殊控件、QPr
    目录一、QLabel-显示文本或图像的控件:1.1QLabel介绍:1.2设置文本格式——textFormat属性:1.3设置图片——pixmap属性:1.4自动缩放——scaledContents属性:拓展:resizeEvent方法:1.5内容对齐方式——alignment属性:1.6自动换行——wordWrap属性:1.7 文本缩进——indent属性......
  • [QT入门]标签控件(QLabel)
    一、概述QLabel是Qt中用于显示文本或图像的控件。它通常被用作标签或显示静态信息的区域。QLabel控件是图形用户界面(GUI)开发中的基础元素之一,广泛应用于各种Qt应用程序中。QLabel控件的灵活性和易用性使其成为开发过程中不可或缺的一部分。二、QLabel控件的基本属性和方法1.......
  • 【推研小灶】复旦类脑保研夏令营面试实录:如何突破夏令营的技术壁垒
    欢迎来到【推研小灶】栏目!在这里,我们邀请成功保研的学长学姐们分享他们的宝贵经验和故事。从申请准备到面试技巧,每一位学长学姐都将为你揭示成功保研的秘诀和路径,为你的保研之路提供有力的指导和启发。让我们与你一起追随他们的足迹,共同探索向理想研究生院迈进的道路。更多......
  • RealMAN:大规模真实录制且经过注释的麦克风阵列数据集
        在深度学习驱动的多通道语音增强和声源定位系统的开发中,由于缺乏大规模的真实录制数据集,这些系统的训练在很大程度上依赖于房间脉冲响应(RIR)和多通道扩散噪声的模拟。然而,模拟数据和真实世界数据之间存在的声学失配可能会导致模型在应用于现实场景时性能下降。现有数......
  • UE 不修改源码实现遮罩控件 (Mask Widget)
    本文内容的参考和灵感来自以下链接GitHub-inkiu0/MaskWidget:UE4MaskWidgetGitHub-JanSeliv/CustomShapeButton:Open-sourcepluginthatallowstomakebuttonsofanyshapeinUE5.4在UE有一个很麻烦的地方,Slate事件不是按照堆叠顺序传递的,就会形成以下现象上......