Qt 将某控件、图案绘制在最前面的方法,通过QGraphicsScene模块实现

news2025/1/14 9:38:49

文章目录

  • 前言
  • 一、效果
  • 二、代码实现
    • 1.工程文件夹结构
    • 2.BackWidget类
      • 2.1 backwidget.h
      • 2.2 backwidget.cpp
  • 总结


前言

  在用Qt做一些应用的时候,有可能遇到和“绘制顺序”相关的问题,即要控制一些控件之间的显示前后问题,在常用的QWidget体系中,设置前后位置是主要是通过raise(),underStack(),hide()函数,但这种操作对本人遇到的问题可能不太好办。
  本人需要处理的问题,可以直接看本博客的图1的效果,即“实现有一个黑点在八个黄色的QWidget子部件前方自由移动”的效果,黑点要完全在黄色方块之前出现。
  如果按照常规对当前的QWidget对象重写paintEvent函数的做法,去绘制那个黑点,那么可能会得到图2的效果。
  本文要做的是去实现图1而不是图2的效果。


一、效果

  为了简便演示,本人在ui文件中直接布置8个方块,为了说明一些问题,左边四块方块为完全不透明的方块,右边四块方块为半透明方块。
图1
             图1 黑点完全在黄色框上方绘制

图2
             图2 黑点在黄色框下方绘制

二、代码实现

1.工程文件夹结构

  本项目工程结构如下图,和显示相关的类如下:一个Widget界面类用于最底层的容器,一个BackWidget界面类用于实现业务逻辑代码。BackWidget占据Widget的整幅界面。
在这里插入图片描述

  这里还有一个UdpServer类是用来确定“黑色圆点”的当前位置的,与显示问题没有直接关系,因此本篇博客不展开详细说明,有兴趣的博友可以移步此篇博客。
代码如下(示例):

2.BackWidget类

2.1 backwidget.h

#ifndef BACKWIDGET_H
#define BACKWIDGET_H

#include <QWidget>
#include <QPainter>
#include <QDebug>
#include <QGraphicsScene>
#include <QGraphicsEllipseItem>
#include <QGraphicsView>

namespace Ui {
class BackWidget;
}

class BackWidget : public QWidget
{
    Q_OBJECT

public:
    explicit BackWidget(QWidget *parent = nullptr);
    ~BackWidget();

    void paintEvent(QPaintEvent *event);
    void draw_point(QPainter& painter, const QPointF& point);
    void draw_point(const QPointF& point);

    void showEvent(QShowEvent* event);
    void resizeEvent(QResizeEvent* event);

    QGraphicsScene* scene;
    QGraphicsEllipseItem* circleItem;
    QGraphicsView* view;

public slots:
    void point_update(QList<QPointF>* points);

private:
    Ui::BackWidget *ui;
    QList<QPointF>* pointsInWidget;
};

#endif // BACKWIDGET_H

2.2 backwidget.cpp

  对绘制黑点这块,通过修改输入参数的形式实现函数的重载(方式比较简单,没仔细考虑,介意的人可以自己改函数名称),下面两个函数,只能运行一条,另一条注释掉。

	//QWiget方式绘制
    draw_point(painter, point);
    
	//用QGraphicsScene方式绘制
    draw_point(point);
#include "backwidget.h"
#include "ui_backwidget.h"

BackWidget::BackWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::BackWidget)
{
    ui->setupUi(this);
    pointsInWidget = new QList<QPointF>;


    scene = new QGraphicsScene(this);
    circleItem = new QGraphicsEllipseItem;
    scene->addItem(circleItem);

    view = new QGraphicsView(scene, this);
    view->setGeometry(0, 0, width(), height());
    view->setStyleSheet("background: transparent");
    view->setRenderHint(QPainter::Antialiasing);
    view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
}

BackWidget::~BackWidget()
{
    delete ui;
}


void BackWidget::point_update(QList<QPointF>* points)
{
    delete pointsInWidget;
    pointsInWidget = new QList<QPointF>(*points);
    delete points;

    update();
}


void BackWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    uint i =0;
    for (const QPointF& point : *pointsInWidget)
    {
        if(i==9)
        {	
        	//QWiget方式绘制
            draw_point(painter, point);
            
			//用QGraphicsScene方式绘制
            draw_point(point);
        }

        i++;
    }
}


void BackWidget::showEvent(QShowEvent* event)
{
    QWidget::showEvent(event);
    view->show();
}

void BackWidget::resizeEvent(QResizeEvent* event)
{
    QWidget::resizeEvent(event);
    view->setGeometry(0, 0, width(), height());
}


void BackWidget::draw_point(const QPointF& point)
{
    circleItem->setRect(QRectF(point.x() * width() - 15, point.y() * height() - 15, 80, 80));

    QBrush brush(Qt::black);
    circleItem->setBrush(brush);
    scene->update();
}


void BackWidget::draw_point(QPainter& painter, const QPointF& point)
{
    painter.setBrush(QBrush(Qt::black));
    painter.drawEllipse(QPointF(point.x()*width(),point.y()*height()), 40, 40);
}


总结

  本文为,Qt 将某控件、图案绘制在最前面的方法,通过QGraphicsScene模块实现的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/679198.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构与算法】力扣:翻转二叉树

翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1] 示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出&#xff1a;[2,…

云HIS是什么?HIS系统为什么要上云?云HIS有哪些优点?

一、当前医疗行业HIS的现状与发展趋势 1.医院信息系统&#xff08;HIS&#xff09;经历了从手工到单机再到局域网的两个阶段&#xff0c;随着云计算、大数据新技术迅猛发展&#xff0c;基于云计算的医院信息系统将逐步取代传统局域网HIS , 以适应人们对医疗卫生服务越来越高的要…

BI-SQL丨角色和用户

角色和用户 在数仓的运维工作中&#xff0c;经常需要为用户开通不同权限的账号&#xff0c;使用户可以正常访问不同的数据&#xff0c;那么这就需要我们了解SQL Server的权限体系。 名词解释 登录名&#xff1a; 用来登录服务器的用户账号&#xff0c;例&#xff1a;sa&…

String类型

前言 之所以介绍是因为基本数据类型是系统中一切操作的基础&#xff0c;就像物理世界中的原子&#xff0c;高楼大厦中的砖瓦。当咱们整明白了这些基本数据类型&#xff0c;使用层面就是挑选和组合的问题了。本文小结下Redis中数据结构和使用场景&#xff0c;如果你有更骚气的挑…

Python中文件的读取

在Python中可以通过内置函数open()、read()和readline()实现文件的读取。 1 打开文件函数 1.1 open()函数的基本用法 open()是Python的内置函数&#xff0c;用来打开指定文件。该函数使用代码如下所示&#xff1a; fin open(words.txt) 其中&#xff0c;参数指定了要打开…

【软件设计师暴击考点】计算机网络知识高频考点暴击系列

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;软件…

NodeJS Request下载图片文件到本地⑩⑦

文章目录 ✨文章有误请指正&#xff0c;如果觉得对你有用&#xff0c;请点三连一波&#xff0c;蟹蟹支持&#x1f618;前言使用模块创建文件删除文件写入图片案例效果总结 ✨文章有误请指正&#xff0c;如果觉得对你有用&#xff0c;请点三连一波&#xff0c;蟹蟹支持&#x1f…

网页前端制作需要哪些基础知识?

&#x1f482; 个人网站:【海拥】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 目录 前言HTML基础知识1 HTM…

存款进阶“10万元门槛”,年轻人为何遭遇困境?

文章目录 ❗❗ 前言&#x1f48c;目前的存款在哪一个区间&#xff1f;你觉得存款难吗&#xff1f;&#x1f622;存钱到底有多难&#xff1f;&#x1f90d;为存款做出过哪些努力&#xff1f;&#x1f9e7;没钱更要理财吗&#xff1f;&#x1f194;影响年轻人存款能力和存款意愿的…

C++多态 动态联编 静态联编 虚函数 抽象类 final override关键字

C多态 多态多态原理 动态联编和静态联编纯虚函数和抽象类C11的final override关键字重载 隐藏 重写的区别 多态 1.派生类中定义虚函数必须与基类中的虚函数同名外&#xff0c;还必须同参数表&#xff0c;同返回类型。 否则被认为是同名覆盖&#xff0c;不具有多态性。 如基类中…

NCI Architecture

2.1 组成部分 NCI 可分为以下逻辑组件&#xff1a;  NCI 核心 NCI 核心定义了设备主机 (DH) 和 NFC 控制器 (NFCC) 之间通信的基本功能。 这使得 NFCC 和 DH 之间能够进行控制消息&#xff08;命令、响应和通知&#xff09;和数据消息交换。  传输映射 传输映射定义 N…

Excel百万级别数据的导入和导出【详细代码】

代码层级结构 DurationAspect package com.zhouyu.aspect;import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.A…

MFC 截图功能实现(2)

上篇文章里面所用的截图是点击按钮就截取当前打开的界面&#xff0c;链接&#xff1a; MFC 截图功能实现_春蕾夏荷_728297725的博客-CSDN博客 这里所用的截图是可以选中区域&#xff0c;另存为目录等的操作&#xff1a; 效果&#xff1a; 选中区域&#xff1a; 菜单&#xf…

javaee 任务调度,定时任务 多个任务同时执行

错误的写法 如果按照下图的写法&#xff0c;两个任务不会同时执行&#xff0c;因为是一个线程&#xff0c;两个任务是串行的关系。 可以看到第二个任务是等第一个任务执行完以后&#xff0c;才执行的。 正确的写法 使用线程池&#xff0c;为每一个任务创建一个线程 可以看…

Markdown中使用 LaTeX 编辑数学公式

Markdown中使用 LaTeX 编辑数学公式 1 介绍TeX&#xff08;计算机排版系统&#xff09;LaTeX&#xff08;TeX宏集&#xff09;KaTeX 和 MathJax 2 注意点单双美元符号包裹问题KaTeX 有些不支持 3 语法保留字符希腊字母希伯来字母二元运算符二元关系符几何符号逻辑符号集合符号箭…

Linux下一切皆文件的理解

目录 一. 回顾上文 Linux底层进程和被打开文件的映射关系图&#xff1a; Linux部分源代码示意图如下&#xff1a; ​编辑 二.Linux下一切皆文件的核心理解 一. 回顾上文 在前两篇文章中&#xff0c;我论述了Linux系统中关于文件基础IO的一些内容&#xff1a; 1.有关于文件…

RT-Thread-05-空闲线程和两个常用的钩子函数

空闲线程和两个钩子函数 空闲线程是一个比较特殊的系统线程&#xff0c;它具备最低优先级&#xff0c;当系统中无其他就绪线程可运行时&#xff0c;调度器将调度到空闲线程&#xff1b;空闲线程还负责一些系统资源回收以及将一些处于关闭状态的线程从线程调度列表中移除&#x…

Nautilus Chain:模块化Layer3架构为RWA赛道构建基础设施

DeFi Summer后&#xff0c;加密行业经历了新一轮的爆发、增长后&#xff0c;整体的发展逐渐陷入滞缓。传统金融是一个经过了上百年发展的成熟市场&#xff0c;将800万亿美元体量的传统金融不断引入到链上有望推动加密行业迎来新一轮的质变。将传统资产以加密代币化的形式引入到…

【从零开始学习JAVA | 第十七篇】抽象类与抽象方法

目录 前言&#xff1a; 抽象类与抽象方法&#xff1a; 抽象类&#xff1a; 抽象方法&#xff1a; 特点&#xff1a; 抽象类 抽象方法 注意事项 抽象类 与 抽象方法的意义 抽象类 抽象方法 前言&#xff1a; 在之前&#xff0c;如果我们要构建两个相同类型的类的时候&…

【C++】泛型编程——模板进阶

文章目录 前言1. 模板参数的分类2. 非类型模板参数2.1 非类型模板参数的概念2.2 铺垫2.2 非类型模板参数的使用2.4 注意2.5 array的了解 3. 模板的特化3.1 概念3.2 函数模板特化3.3 类模板特化3.3.1 全特化3.3.2 偏特化部分特化参数更进一步的限制 4. 模板分离编译4.1 什么是分…