qt-C++笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphicsRectItem的区别

qt-C++笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphicsRectItem的区别

在这里插入图片描述

code review!

参考笔记
1.qt-C++笔记之重写QGraphicsItem的paint方法(自定义QGraphicsItem)

文章目录

  • qt-C++笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphicsRectItem的区别
    • 一、QLine、QPainterPath、QGraphicsPathItem、自定义 QGraphicsPathItem 的区别与使用场景
      • 表格:类的比较
      • 简洁对比示例
        • 示例 1:使用 QLine 绘制简单直线
        • 示例 2:使用 QPainterPath 绘制复杂路径
        • 示例 3:在 QGraphicsScene 中使用 QGraphicsPathItem
        • 示例 4:自定义 QGraphicsPathItem 并实现特殊交互
    • 二、QRect、QGraphicsRectItem、自定义 QGraphicsRectItem 的区别与使用场景
      • 表格:类的比较
      • 简洁对比示例
        • 示例 1:使用 QRect 进行布局计算
        • 示例 2:在 QGraphicsScene 中使用 QGraphicsRectItem
        • 示例 3:自定义 QGraphicsRectItem 并实现特殊功能
    • 三、总结比较
      • 表格:关键区别和适用场景
    • 四、自定义 QGraphicsRectItem、自定义 QGraphicsPathItem 与自定义 QGraphicsItem 的区别
      • 4.1 继承层次与基础功能
      • 4.2 差异对比
    • 五、使用场景与示例
      • 5.1 自定义 QGraphicsRectItem
      • 5.2 自定义 QGraphicsPathItem
      • 5.3 自定义 QGraphicsItem
    • 六、总结与选择建议
      • 6.1 何时选择自定义 QGraphicsRectItem / QGraphicsPathItem
      • 6.2 何时选择自定义 QGraphicsItem
      • 6.3 选择建议

一、QLine、QPainterPath、QGraphicsPathItem、自定义 QGraphicsPathItem 的区别与使用场景

表格:类的比较

类名定义特点使用场景
QLine表示由两点定义的直线段- 轻量级
- 整数精度
- 几何计算
- 基本绘制
QPainterPath描述复杂绘图路径的类- 灵活构建任意复杂路径
- 浮点精度
- 支持布尔运算
- 复杂形状绘制
- 路径动画
QGraphicsPathItem在 QGraphicsScene 中显示 QPainterPath 的图形项- 可视化复杂路径
- 支持交互和变换
- 图形编辑器
- 数据可视化
自定义 QGraphicsPathItem继承 QGraphicsPathItem,实现自定义行为- 可扩展性强
- 重写事件处理和绘制方法
- 定制交互
- 特定功能组件

简洁对比示例

示例 1:使用 QLine 绘制简单直线
QLine line(0, 0, 100, 100);
QPainter painter(this);
painter.drawLine(line);
  • 使用场景:当需要在窗口上绘制简单的直线时。
示例 2:使用 QPainterPath 绘制复杂路径
QPainterPath path;
path.moveTo(0, 0);
path.lineTo(50, 100);
path.cubicTo(80, 0, 120, 100, 150, 0);

QPainter painter(this);
painter.drawPath(path);
  • 使用场景:当需要绘制复杂的曲线和形状时。
示例 3:在 QGraphicsScene 中使用 QGraphicsPathItem
QPainterPath path;
path.addEllipse(0, 0, 100, 100);

QGraphicsScene *scene = new QGraphicsScene(this);
QGraphicsView *view = new QGraphicsView(scene, this);

QGraphicsPathItem *item = new QGraphicsPathItem(path);
scene->addItem(item);
  • 使用场景:当需要将复杂路径添加到场景中以支持交互时。
示例 4:自定义 QGraphicsPathItem 并实现特殊交互
class MyPathItem : public QGraphicsPathItem {
public:
    MyPathItem(const QPainterPath &path) : QGraphicsPathItem(path) {}

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {
        // 实现自定义的鼠标按下事件处理
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override {
        // 实现自定义的绘制
        QGraphicsPathItem::paint(painter, option, widget);
    }
};

// 使用自定义项
QPainterPath path;
// ... 构建路径 ...

MyPathItem *item = new MyPathItem(path);
scene->addItem(item);
  • 使用场景:当需要自定义图形项的交互行为或绘制外观时。

二、QRect、QGraphicsRectItem、自定义 QGraphicsRectItem 的区别与使用场景

表格:类的比较

类名定义特点使用场景
QRect表示矩形区域的类- 轻量级
- 整数精度
- 布局计算
- 区域检测
QGraphicsRectItem在 QGraphicsScene 中显示矩形的图形项- 可视化矩形
- 支持交互和变换
- 图形元素
- 绘图工具
自定义 QGraphicsRectItem继承 QGraphicsRectItem,实现自定义行为- 可扩展性强
- 重写事件处理和绘制方法
- 特定交互
- 组件封装

简洁对比示例

示例 1:使用 QRect 进行布局计算
QRect rect(0, 0, 100, 50);
QPoint point(50, 25);

if (rect.contains(point)) {
    // 点在矩形内
}
  • 使用场景:用于界面元素的位置和布局计算。
示例 2:在 QGraphicsScene 中使用 QGraphicsRectItem
QGraphicsScene *scene = new QGraphicsScene(this);
QGraphicsView *view = new QGraphicsView(scene, this);

QGraphicsRectItem *item = new QGraphicsRectItem(0, 0, 100, 50);
item->setBrush(Qt::blue);
scene->addItem(item);
  • 使用场景:当需要在场景中显示矩形并支持交互时。
示例 3:自定义 QGraphicsRectItem 并实现特殊功能
class MyRectItem : public QGraphicsRectItem {
public:
    MyRectItem(qreal x, qreal y, qreal w, qreal h) : QGraphicsRectItem(x, y, w, h) {}

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {
        // 实现自定义的鼠标按下事件处理
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override {
        // 实现自定义的绘制,例如绘制渐变填充
        QLinearGradient gradient(rect().topLeft(), rect().bottomRight());
        gradient.setColorAt(0, Qt::white);
        gradient.setColorAt(1, Qt::blue);
        painter->setBrush(gradient);
        painter->drawRect(rect());
    }
};

// 使用自定义项
MyRectItem *item = new MyRectItem(0, 0, 100, 50);
scene->addItem(item);
  • 使用场景:当需要自定义矩形的交互行为或绘制外观时。

三、总结比较

表格:关键区别和适用场景

类别QLine / QRectQPainterPathQGraphicsPathItem / QGraphicsRectItem自定义 QGraphicsItem
定义基础几何类,表示直线段和矩形区域绘图路径类,描述复杂路径图形项类,在场景中显示图形继承图形项,添加自定义行为
特点轻量级,整数精度,不支持交互灵活构建复杂路径,浮点精度,支持布尔运算可视化,支持交互和变换,属性可设置可扩展性强,重写事件和绘制方法
使用场景几何计算,基本绘制,布局计算复杂形状绘制,路径动画,精确碰撞检测图形编辑器,数据可视化,游戏开发定制交互,特定功能组件,动画效果
交互性不支持交互,需要手动处理不支持交互,需要手动处理支持交互,如选择、移动、缩放支持自定义交互,重写事件处理
绘制方式使用 QPainter 在小部件上绘制使用 QPainter 绘制复杂形状在 QGraphicsScene 中绘制在 QGraphicsScene 中绘制,自定义绘制

通过以上对比,可以根据具体需求选择合适的类:

  • 需要简单的几何计算或基本形状的数据表示时,使用 QLine 和 QRect。
  • 需要绘制复杂路径或形状时,使用 QPainterPath。
  • 需要在图形场景中显示和操作图形对象时,使用 QGraphicsPathItem 或 QGraphicsRectItem。
  • 当标准图形项无法满足需求,需要特殊行为或外观时,通过继承创建自定义的 QGraphicsItem。

四、自定义 QGraphicsRectItem、自定义 QGraphicsPathItem 与自定义 QGraphicsItem 的区别

4.1 继承层次与基础功能

  • 自定义 QGraphicsRectItem / QGraphicsPathItem:

    • 继承关系:QGraphicsRectItem 和 QGraphicsPathItem 都是 QGraphicsItem 的子类。
    • 基础功能:
      • 默认实现:它们已经实现了 QGraphicsItem 的一些纯虚函数,如 boundingRect()、paint()、shape() 等。
      • 几何形状:自带特定的几何形状(矩形或路径),并提供了相应的属性和方法操作这些形状。
      • 绘制逻辑:默认实现了绘制逻辑,可直接用于显示。
  • 自定义 QGraphicsItem:

    • 继承关系:直接继承自 QGraphicsItem。
    • 基础功能:
      • 需要自行实现:必须实现所有纯虚函数,包括 boundingRect()、paint()、shape() 等。
      • 完全自定义:具有最大的灵活性,可以定义任意的形状、绘制逻辑和交互行为。

4.2 差异对比

方面自定义 QGraphicsRectItem / QGraphicsPathItem自定义 QGraphicsItem
开发复杂度- 较低:因为继承自已有的形状类,省去了实现基本功能的工作量。
- 快速上手:只需重写需要定制的部分。
- 较高:需要从零开始实现所有必要的函数,包括几何计算和绘制逻辑。
灵活性- 有限:受到父类形状的限制,只能操作矩形或路径。
- 定制范围:适合在已有形状基础上稍作修改。
- 最大:完全自主定义形状、外观和交互行为,可实现复杂和独特的图形项。
性能- 较优:父类已经对常见操作进行了优化。
- 资源占用:较低的资源消耗。
- 视实现而定:需要注意优化,避免不必要的性能开销。
适用场景- 简单定制:当图形项是矩形或路径,并需要在此基础上增加少量功能或修改。
- 快速开发:节省时间和精力。
- 复杂需求:当需要实现特殊形状或复杂的交互行为,无法通过继承现有类来实现时。

五、使用场景与示例

5.1 自定义 QGraphicsRectItem

使用场景:

  • 当需要在矩形基础上增加特定功能,例如:
    • 添加鼠标交互,响应点击、拖动等事件。
    • 改变绘制方式,绘制特殊的边框或填充效果。
    • 增加属性,例如关联数据等。

示例:创建一个可拖动的矩形,并在被点击时改变颜色。

class CustomRectItem : public QGraphicsRectItem {
public:
    CustomRectItem(const QRectF &rect) : QGraphicsRectItem(rect) {
        setFlags(ItemIsSelectable | ItemIsMovable);
        setBrush(Qt::blue);
    }

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {
        setBrush(Qt::red); // 点击时变为红色
        QGraphicsRectItem::mousePressEvent(event); // 调用父类处理
    }

    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override {
        setBrush(Qt::blue); // 释放时变回蓝色
        QGraphicsRectItem::mouseReleaseEvent(event);
    }
};

5.2 自定义 QGraphicsPathItem

使用场景:

  • 当需要在路径基础上增加功能,例如:
    • 实现路径的动画效果。
    • 根据数据动态生成路径形状。
    • 增加交互,支持节点的拖动、编辑等。

示例:创建一个可编辑的折线路径,支持节点拖动。

class EditablePathItem : public QGraphicsPathItem {
public:
    EditablePathItem(const QPainterPath &path) : QGraphicsPathItem(path) {
        setFlags(ItemIsSelectable | ItemIsMovable);
    }

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {
        // 实现节点选择和拖动逻辑
    }

    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override {
        // 更新路径形状
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override {
        // 自定义绘制,例如在节点处绘制控制点
        QGraphicsPathItem::paint(painter, option, widget);
    }
};

5.3 自定义 QGraphicsItem

使用场景:

  • 当需要完全自定义的图形项,无法通过继承现有形状类实现。
  • 需要特殊的形状、复杂的交互,或独特的绘制效果。

示例:创建一个自定义形状的图形项,例如五角星形状,并实现旋转动画。

class StarItem : public QGraphicsItem {
public:
    StarItem() {
        // 启动定时器,实现旋转动画
        angle = 0;
        timer = new QTimer(this);
        connect(timer, &QTimer::timeout, this, &StarItem::rotate);
        timer->start(100);
    }

    QRectF boundingRect() const override {
        return QRectF(-50, -50, 100, 100); // 定义边界矩形
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override {
        painter->save();
        painter->rotate(angle); // 旋转
        painter->setBrush(Qt::yellow);
        painter->drawPolygon(starPolygon()); // 绘制五角星
        painter->restore();
    }

    QPainterPath shape() const override {
        QPainterPath path;
        path.addPolygon(starPolygon());
        return path;
    }

private:
    QPolygonF starPolygon() const {
        QPolygonF polygon;
        // 计算五角星的顶点坐标
        for (int i = 0; i < 5; ++i) {
            qreal theta = (i * 72 - 90) * M_PI / 180;
            qreal x = 40 * cos(theta);
            qreal y = 40 * sin(theta);
            polygon << QPointF(x, y);
        }
        return polygon;
    }

    void rotate() {
        angle += 5;
        if (angle >= 360) angle = 0;
        update();
    }

    qreal angle;
    QTimer *timer;
};

六、总结与选择建议

6.1 何时选择自定义 QGraphicsRectItem / QGraphicsPathItem

  • 优势:

    • 快速开发:利用已有的形状和功能,减少编码量。
    • 简单可靠:继承自经过测试的类,稳定性有保障。
    • 易于维护:代码结构清晰,易于理解和修改。
  • 适用情况:

    • 形状固定:图形项的基本形状是矩形或路径,不需要改变。
    • 功能扩展:在现有功能上增加少量特性,如交互或绘制效果。
    • 性能要求高:利用父类的优化,确保性能。

6.2 何时选择自定义 QGraphicsItem

  • 优势:

    • 无限灵活:可完全自定义形状、绘制和交互。
    • 满足特殊需求:能够实现复杂和独特的图形效果。
    • 深度优化:可以针对特定需求进行性能优化。
  • 适用情况:

    • 形状特殊:图形项的形状无法由现有类描述,需要完全自定义。
    • 复杂交互:需要实现复杂的事件处理和用户交互逻辑。
    • 独特绘制:需要超出常规的绘制效果,如动态变化、特效等。

6.3 选择建议

  • 若图形项是现有形状的扩展,且只需增加少量功能,建议继承 QGraphicsRectItem 或 QGraphicsPathItem。

    • 示例:在矩形上添加点击事件,或在路径上增加动画效果。
  • 若图形项需求复杂,无法通过继承现有形状类来满足,建议直接继承 QGraphicsItem。

    • 示例:创建复杂的自定义形状,或需要完全控制绘制和交互行为。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

浏览器IndexedDB占用大

使用鲁大师清理后&#xff0c;用 SpaceSniffer 查看C盘占用情况&#xff0c;发现浏览器的 IndexedDB 有3个文件夹占用特别大&#xff0c;从文件名看是 youku&#xff0c;bilibili&#xff0c;v.qq.com&#xff0c;浏览器的数据库并不需要长期保存&#xff0c;删除这3个文件夹&a…

MongoDB部署模式

目录 单节点模式&#xff08;Standalone&#xff09; 副本集模式&#xff08;Replica Set&#xff09; 分片集群模式&#xff08;Sharded Cluster&#xff09; MongoDB有多种部署模式&#xff0c;可以根据业务需求选择适合的架构和部署方式。 单节点模式&#xff08;Standa…

将 OneLake 数据索引到 Elasticsearch - 第二部分

作者&#xff1a;来自 Elastic Gustavo Llermaly 及 Jeffrey Rengifo 本文分为两部分&#xff0c;第二部分介绍如何使用自定义连接器将 OneLake 数据索引并搜索到 Elastic 中。 在本文中&#xff0c;我们将利用第 1 部分中学到的知识来创建 OneLake 自定义 Elasticsearch 连接器…

Formality:时序变换(三)(相位反转)

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 一、引言 时序变换在Design Compiler的首次综合和增量综合中都可能发生&#xff0c;它们包括&#xff1a;时钟门控(Clock Gating)、寄存器合并(Register Merging)、…

php代码审计2 piwigo CMS in_array()函数漏洞

php代码审计2 piwigo CMS in_array()函数漏洞 一、目的 本次学习目的是了解in_array()函数和对项目piwigo中关于in_array()函数存在漏洞的一个审计并利用漏洞获得管理员帐号。 二、in_array函数学习 in_array() 函数搜索数组中是否存在指定的值。 in_array($search,$array…

房租管理系统的智能化应用助推租赁行业高效运营与决策优化

内容概要 在现代租赁行业中&#xff0c;房租管理系统的智能化应用正在逐步成为一个不可或缺的工具。通过整合最新技术&#xff0c;这些系统为租赁管理的各个方面提供了极大的便利和效率提升。从房源管理到合同签署再到财务监控&#xff0c;智能化功能能够帮助运营者在繁琐的事…

Hive关于数据库的语法,warehouse,metastore

关于数据库的语法 在default数据库下,查看其他数据库的表 in 打开控制台 字体大小的设置 Hive默认的库: default, 1/4说明一共有4个库,现在只展示了1个,单击>>所有架构 数据库的删除 方法一: 语法 删除有表的数据库,加cascade 方法二 当前连接的数据库 切换当前数据库…

【React】PureComponent 和 Component 的区别

前言 在 React 中&#xff0c;PureComponent 和 Component 都是用于创建组件的基类&#xff0c;但它们有一个主要的区别&#xff1a;PureComponent 会给类组件默认加一个shouldComponentUpdate周期函数。在此周期函数中&#xff0c;它对props 和 state (新老的属性/状态)会做一…

AI赋能医疗:智慧医疗系统源码与互联网医院APP的核心技术剖析

本篇文章&#xff0c;笔者将深入剖析智慧医疗系统的源码架构以及互联网医院APP背后的核心技术&#xff0c;探讨其在医疗行业中的应用价值。 一、智慧医疗系统的核心架构 智慧医疗系统是一个高度集成的信息化平台&#xff0c;主要涵盖数据采集、智能分析、决策支持、远程医疗等…

HTML-新浪新闻-实现标题-样式1

用css进行样式控制 css引入方式&#xff1a; --行内样式&#xff1a;写在标签的style属性中&#xff08;不推荐&#xff09; --内嵌样式&#xff1a;写在style标签中&#xff08;可以写在页面任何位置&#xff0c;但通常约定写在head标签中&#xff09; --外联样式&#xf…

【学习笔记】深度学习网络-深度前馈网络(MLP)

作者选择了由 Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 三位大佬撰写的《Deep Learning》(人工智能领域的经典教程&#xff0c;深度学习领域研究生必读教材),开始深度学习领域学习&#xff0c;深入全面的理解深度学习的理论知识。 在之前的文章中介绍了深度学习中用…

如何在IDEA社区版Service面板中管理springboot项目

1、开启service仪表盘 2、在service仪表盘中&#xff0c;添加启动类配置项&#xff0c;专业版是SpringBoot 、社区版是application。 3、控制台彩色日志输出 右键启动类配置项&#xff0c;添加虚拟机参数 -Dspring.output.ansi.enabledALWAYS

如何在data.table中处理缺失值

&#x1f4ca;&#x1f4bb;【R语言进阶】轻松搞定缺失值&#xff0c;让数据清洗更高效&#xff01; &#x1f44b; 大家好呀&#xff01;今天我要和大家分享一个超实用的R语言技巧——如何在data.table中处理缺失值&#xff0c;并且提供了一个自定义函数calculate_missing_va…

.NET9增强OpenAPI规范,不再内置swagger

ASP.NETCore in .NET 9.0 OpenAPI官方文档ASP.NET Core API 应用中的 OpenAPI 支持概述 | Microsoft Learnhttps://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/openapi/overview?viewaspnetcore-9.0https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/ope…

【redis初阶】redis客户端

目录 一、基本介绍 二、认识RESP&#xff08;redis自定的应用层协议名称&#xff09; 三、访问github的技巧 四、安装redisplusplus 4.1 安装 hiredis** 4.2 下载 redis-plus-plus 源码 4.3 编译/安装 redis-plus-plus 五、编写运行helloworld 六、redis命令演示 6.1 通用命令的…

蓝桥杯3518 三国游戏 | 排序

题目传送门 这题的思路很巧妙&#xff0c;需要算出每个事件给三国带来的净贡献&#xff08;即本国士兵量减其他两国士兵量&#xff09;并对其排序&#xff0c;根据贪心的原理累加贡献量直到累加结果不大于0。最后对三国的胜利的最大事件数排序取最值即可。 n int(input()) a …

基于vue框架的的信用社业务管理系统设计与实现4gnx5(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,用户销户,用户存款,用户取款,用户转账,理财类型,投资理财,理财订单,金属类别,贵金属,金属订单,产品分类,保险产品,保险订单 开题报告内容 基于Vue框架的信用社业务管理系统设计与实现开题报告 一、研究背景与意义 随着金融科技的…

自然语言处理——从原理、经典模型到应用

1. 概述 自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;是一门借助计算机技术研究人类语言的科学&#xff0c;是人工智能领域的一个分支&#xff0c;旨在让计算机理解、生成和处理人类语言。其核心任务是将非结构化的自然语言转换为机器可以…

微信小程序1.1 微信小程序介绍

1.1 微信小程序介绍 内容提要 1.1 什么是微信小程序 1.2 微信小程序的功能 1.3 微信小程序使用场景 1.4 微信小程序能取代App吗 1.5 微信小程序的发展历程 1.6微信小程序带来的机会

【已解决】OSS配置问题

OSS SDK快速入门_对象存储(OSS)-阿里云帮助中心 阿里官方的SDK使用方法还得配置环境变量access Key、access Secret &#xff0c;我没有配置&#xff0c;仅把access Key和access Secret写到了yml文件读取&#xff0c;结果上传图片时还是出现下面的问题。 [ ERROR ] [ com.s…