【qml】 在QML场景图中使用QPainter 的方法

news2024/11/17 0:42:11

【qml】 在QML场景图中使用QPainter 的方法_qquickpainteditem-CSDN博客

QQuickPaintedItem

1.官方资料

QQuickPaintedItem类提供了一种在QML场景图中使用QPainter API的方法。

QQuickPaintedItem使QPainter API与QML场景图一起使用成为可能。它在场景图中设置了一个纹理矩形,并使用QPainter在纹理上作画。

1)  要编写自己的绘制项,首先要创建QQuickPaintedItem的一个子类,然后实现其惟一的纯虚拟公共函数paint(),该函数实现实际的绘制。绘制将在从0,0到width(),height()的矩形内。

2)调用update()来触发重绘。

3)要使QPainter做抗锯齿渲染,使用setAntialiasing()

4)渲染目标可以是QImage,也可以是使用OpenGL时的QOpenGLFramebufferObject。当渲染目标是一个QImage时,QPainter首先渲染到图像中,然后将内容上传到纹理中。当使用QOpenGLFramebufferObject时,QPainter直接在纹理上作画。

**注意:**重要的是要理解这些项目可能引起的性能影响。
参见QQuickPaintedItem::RenderTarget和QQuickPaintedItem::RenderTarget。

1.1. Public Types

  1) enum QQuickPaintedItem::PerformanceHint
flags QQuickPaintedItem::PerformanceHints
此枚举描述了可以启用的标志,以提高QQuickPaintedItem中的呈现性能。默认情况下,没有设置这些标志。

2) enum QQuickPaintedItem::RenderTarget
渲染目标是QPainter在项目在屏幕上渲染之前绘制的表面。

1.2. Properties

1) fillColor : QColor
背景填充的颜色。默认为Qt::transparent。

2) renderTarget : RenderTarget

3) textureSize : QSize
纹理大小。
改变纹理的大小不会影响paint()中使用的坐标系统。取而代之的是一个比例因子,所以绘画应该仍然发生在0,0到width(),height()。
默认情况下,纹理大小将与此项目相同。
注意:如果项目位于设备像素比不等于1的窗口上,则此缩放因子将隐式应用于纹理大小。

1.3. Public Functions

Mipmapping 是一种图像处理技术,它采用一个原始的、高分辨率的纹理图像或映射和过滤器,并在同一个纹理文件中将其扩展为多个分辨率更小的纹理映射。依据不同精度的要求,而使用不同版本的材质图样进行贴图

1.4. Reimplemented Public Functions

1.5. Signals

 1) void fillColorChanged()

 2) void renderTargetChanged()

 3) void textureSizeChanged()

1.6. Reimplemented Protected Functions

1) virtual void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override

2) virtual void releaseResources() override

3) virtual QSGNode * updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data) override

2. 案例

2.1. QuickPaintedItem 类

2.1.1. QuickPaintedItem.h
#ifndef QUICKPAINTEDITEM_H
#define QUICKPAINTEDITEM_H

#include <QPainterPath>
#include <QtQuick>

class QuickPaintedItem : public QQuickPaintedItem
{
    Q_OBJECT
    Q_PROPERTY(bool draw READ isDraw WRITE setDraw NOTIFY drawChanged)
    Q_PROPERTY(bool antialias READ isAntialias WRITE setAntialias NOTIFY antialiasChanged)

public:
    QuickPaintedItem(QQuickItem *parent = 0);
    void paint(QPainter *painter) override;

    Q_INVOKABLE  void mousePress    (qreal x, qreal y) ;
    Q_INVOKABLE  void mouseMove     (qreal x, qreal y) ;
    Q_INVOKABLE  void mouseRelease  (qreal x, qreal y) ;
    
    bool isDraw() const;
    void setDraw(bool newDraw);
    
    bool isAntialias() const;
    void setAntialias(bool newAntialias);

private:

signals:
    void drawChanged();

    void antialiasChanged();

private:
    bool draw;
    QPainterPath m_path;
    QPolygonF  m_poly;
};

#endif
2.1.2. QuickPaintedItem.cpp
#include "QuickPaintedItem.h"
#include <QDebug>
#define qout if( 1 ) qDebug()

static QPointF startPoint, lastPoint;
QuickPaintedItem::QuickPaintedItem(QQuickItem *parent)
    : QQuickPaintedItem(parent)
    , draw(false)
{
}

void QuickPaintedItem::paint(QPainter *painter)
{
    painter->drawPath(m_path);
    painter->drawPolyline(m_poly);

    if(startPoint.isNull() || lastPoint.isNull())
        return;

    if(draw){
        painter->setPen(Qt::red);
        painter->drawLine(startPoint,lastPoint);
    }
}

void QuickPaintedItem::mousePress(qreal x, qreal y)
{
    startPoint.rx() = x;
    startPoint.ry() = y;
    if(draw){
        m_path.addRect(x-1,y-1,2,2);
        m_poly.append(startPoint);
        update();
    }
}

void QuickPaintedItem::mouseMove(qreal x, qreal y)
{
    lastPoint.rx() = x;
    lastPoint.ry() = y;
    update();
}

void QuickPaintedItem::mouseRelease(qreal x, qreal y)
{
    if(draw){
        lastPoint.rx() = x;
        lastPoint.ry() = y;
    }else{

    }
    update();
}

bool QuickPaintedItem::isDraw() const
{
    return draw;
}

void QuickPaintedItem::setDraw(bool newDraw)
{
    if(newDraw==false) {
        startPoint = lastPoint = QPointF();
        m_path.addPolygon(m_poly);
        m_path.closeSubpath();
        m_poly = QPolygonF();
        update();
    }
    if (draw == newDraw)
        return;
    draw = newDraw;


    emit drawChanged();
}

bool QuickPaintedItem::isAntialias() const
{
    return antialiasing();
}

void QuickPaintedItem::setAntialias(bool newAntialias)
{
    if (antialiasing() == newAntialias)
        return;
    setAntialiasing(newAntialias);
    emit antialiasChanged();
}

2.2. main.qml

import QtQuick 2.0
import QtQml.Models 2.15
import MyQuickPaintedItem 1.0

Item {
    height: 480
    width: 320

    QuickPaintedItem {
        id: drawer
        anchors.fill: parent
        antialias: true
        MouseArea{
            anchors.fill: parent
            acceptedButtons: Qt.LeftButton | Qt.RightButton
            hoverEnabled:true

            onPressed: {
                if(mouse.button == Qt.LeftButton){
                    drawer.draw = true;
                    parent.mousePress(mouseX,mouseY)
                }
                else{
                    drawer.draw = false;
                }
            }
            onPositionChanged: {
                parent.mouseMove(mouseX,mouseY)
            }
            onReleased: {
                if(mouse.button == Qt.LeftButton)
                    parent.mouseRelease(mouseX,mouseY)
            }
        }
    }
}

2.3. main.cpp

#include <QApplication>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "QuickPaintedItem.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQuickView view;
    qmlRegisterType<QuickPaintedItem>("MyQuickPaintedItem",1,0,"QuickPaintedItem");
    view.setSource(QUrl(QStringLiteral("qrc:/painteditem/main.qml")));
    view.show();
    
    return app.exec();
}

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

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

相关文章

【Spring Cloud Alibaba】9 - OpenFeign集成Sentinel实现服务降级

目录 一、简介Sentinel 是什么如何引入Sentinel 二、服务搭建1.安装Sentinel控制台1.1 下载1.2 启动1.3 访问 2.改造服务提供者cloud-provider服务2.1 引入依赖2.2 添加API2.3 添加配置文件 3.改造cloud-consumer-feign服务3.1 引入依赖3.2 添加Feign接口3.3 添加服务降级类3.4…

InnoDB 数据页结构

1.行格式 1.1 Compact行格式 1.1.1 示意图 1.1.2 准备一下 1&#xff09;建表 mysql> CREATE TABLE record_format_demo (-> c1 VARCHAR(10),-> c2 VARCHAR(10) NOT NULL,-> c3 CHAR(10),-> c4 VARCHAR(10)-> ) CHARSETascii ROW_FORMATCOM…

卫星遥感影像如何选择合适的分辨率

​ 卫星遥感影像的分辨率是影响其应用效果的关键因素之一。分辨率越高&#xff0c;所获取的图像细节越丰富&#xff0c;能够更准确地反映地物的特征和变化。因此&#xff0c;在选择卫星遥感影像时&#xff0c;需要根据实际需求和数据可获取性来选择合适的分辨率。 一、分辨…

大语言模型上下文窗口初探(下)

由于篇幅原因&#xff0c;本文分为上下两篇&#xff0c;上篇主要讲解上下文窗口的概念、在LLM中的重要性&#xff0c;下篇主要讲解长文本能否成为LLM的护城河、国外大厂对长文本的态度。 3、长文本是护城河吗&#xff1f; 毫无疑问&#xff0c;Kimi从一开始就用“长文本”占领…

162 Linux C++ 通讯架构实战16,UDP/TCP协议的优缺点,使用环境对比。UDP 服务器开发

UDP/TCP协议的优缺点 TCP :面向连接的&#xff0c;可靠数据包传输。对于不稳定的网络层&#xff0c;采取完全弥补的通信方式。丢包重传 优点&#xff1a;稳定&#xff0c;数据流量稳定&#xff0c;速度稳定&#xff0c;顺序稳定 缺点&#xff1a;传输速度慢&…

大语言模型上下文窗口初探(上)

由于篇幅原因&#xff0c;本文分为上下两篇&#xff0c;上篇主要讲解上下文窗口的概念、在LLM中的重要性&#xff0c;下篇主要讲解长文本能否成为LLM的护城河、国外大厂对长文本的态度。 1、什么是上下文窗口&#xff1f; 上下文窗口&#xff08;context window&#xff09;是…

【已解决】ZIP压缩文件如何设置密码?

ZIP是常用的压缩格式之一&#xff0c;对于重要的ZIP文件&#xff0c;我们还可设置密码保护&#xff0c;那ZIP压缩文件怎么设置密码呢&#xff1f;不清楚的小伙伴一起来看看吧&#xff01; 给ZIP文件设置密码&#xff0c;我们需要用到支持ZIP格式的解压缩软件&#xff0c;比如7…

数字乡村:科技引领新时代农村发展

随着信息技术的迅猛发展和数字化浪潮的推进&#xff0c;数字乡村作为新时代农村发展的重要战略&#xff0c;正日益成为引领农村现代化的强大引擎。数字乡村不仅代表着农村信息化建设的新高度&#xff0c;更是农村经济社会发展的重要支撑。通过数字技术的深入应用&#xff0c;农…

41.基于SpringBoot + Vue实现的前后端分离-校园网上店铺管理系统(项目 + 论文PPT)

项目介绍 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。本课题研究和开发校园网上店铺&#xff0c;让安装在计算机上的该系统变成管理人员的小帮手&#xff0c;提高校园店铺商品销售信息处…

C语言——详解字符函数和字符串函数(二)

Hi,铁子们好呀&#xff01;之前博主给大家简单地介绍了部分字符和字符串函数&#xff0c;那么这次&#xff0c;博主将会把这些字符串函数给大家依次讲完&#xff01; 今天讲的具体内容如下: 文章目录 6.strcmp函数的使用及模拟实现6.1 strcmp函数介绍和基本使用6.1.1 strcmp函…

还在担心报表不好做?不用怕,试试这个方法(三)

系列文章&#xff1a; 《还在担心报表不好做&#xff1f;不用怕&#xff0c;试试这个方法》&#xff08;一&#xff09; 《还在担心报表不好做&#xff1f;不用怕&#xff0c;试试这个方法》&#xff08;二&#xff09; 概要 在上一篇文章《还在担心报表不好做&#xff1f;…

python爬虫学习第十五天-------ajax的get和post请求

嗨嗨嗨&#xff01;兄弟姐妹大家好哇&#xff01;今天我们来学习ajax的get和post请求 一、了解ajax Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;是一种在 Web 开发中用于创建交互式网页应用程序的技术。通过 Ajax&#xff0c;网页可以在不重新加载整个页面…

C语言——#define的使用

#define定义常量 基本语法 #define name stuff //&#xff08;#define&#xff09;&#xff08;变量名&#xff09;&#xff08;定义的数值&#xff09; 这里记得&#xff0c;是不加分号的 定义常量&#xff08;这里 就要涉及我们经常说的宏定义&#xff09; 定义常量的使…

langchain 学习笔记-FunctionCalling三种方式

ChatGPT 基于海量的训练数据生成答案&#xff0c;所以它无法回答训练数据中没有的信息或搜索信息 。人们希望 ChatGPT 具有对话以外的各种功能&#xff0c;例如“我想管理我的待办事项列表”。 函数调用是对此类请求的响应。 通过使用函数调用&#xff0c;ChatGPT 现在可以在生…

牛客 2024春招冲刺题单 ONT98 牛牛猜节点【中等 斐波那契数列 Java,Go,PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/6a3dfb5be4544381908529dc678ca6dd 思路 斐波那契数列参考答案Java import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规…

Nestjs中使用MQTT

准备工作&#xff0c;首先就得硬件的小伙伴自己吧硬件部分配置好&#xff0c;成功连通云端&#xff0c;并成功推送数据。然后就是服务器装好Nestjs 。做好这些准备工作就可以开始了&#xff01;&#xff01;&#xff01; 然后直接开始工作&#xff1a; 一、安装 # 直接安装最…

Spring boot框架Rouyi Cloud入门之token

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 往期热门专栏回顾 专栏…

Android Glide配置AppGlideModule定制化线程池,Kotlin(1)

Android Glide配置AppGlideModule定制化线程池&#xff0c;Kotlin&#xff08;1&#xff09; plugins {id org.jetbrains.kotlin.kapt }implementation com.github.bumptech.glide:glide:4.16.0kapt com.github.bumptech.glide:compiler:4.16.0 import android.content.Context…

布局图纸电子管理系统,布局图纸电子管理系统哪个好?

布局图纸电子管理系统是一个涉及多个步骤和策略的过程&#xff0c;旨在优化图纸的存储、检索、共享和安全性。下面是一个可能的布局图纸电子管理系统的框架和关键要素&#xff1a; 一、需求分析 明确电子管理系统的具体需求&#xff0c;包括用户群体、功能模块、安全性要求等。…

竞赛 交通目标检测-行人车辆检测流量计数 - 竞赛

文章目录 0 前言1\. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 毕业设计…