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。

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C动态库的生成与在Python和QT中的调用方法

目录 一、动态库生成 1&#xff09;C语言生成动态库 2&#xff09;c类生成动态库 二、动态库调用 1&#xff09;Python调用DLL 2&#xff09;QT调用DLL 三、存在的一些问题 1&#xff09;python调用封装了类的DLL可能调用不成功 2&#xff09;DLL格式不匹配的问题 四、…

.NET MAUI进行UDP通信(二)

上篇文章有写过一个简单的demo&#xff0c;本次对项目进行进一步的扩展&#xff0c;添加tabbar功能。 1.修改AppShell.xaml文件&#xff0c;如下所示&#xff1a; <?xml version"1.0" encoding"UTF-8" ?> <Shellx:Class"mauiDemo.AppShel…

什么是Maxscript?为什么要学习Maxscript?

MAXScript是Autodesk 3ds Max的内置脚本语言,它是一种与3dsMax对话并使3dsMax执行某些操作的编程语言。它是一种脚本语言,这意味着您不需要编译代码即可运行。通过使用一系列基于文本的命令而不是使用UI操作,您可以完成许多使用UI操作无法完成的任务。 Maxscript是一种专有…

适配器模式

目录 一、概念 1、定义 2、涉及到的角色 二、类适配器 1、类图 2、代码示例 &#xff08;1&#xff09;水饺&#xff08;源角色&#xff09; &#xff08;2&#xff09;烹饪&#xff08;目的角色&#xff09; &#xff08;3&#xff09;食品适配器&#xff08;适配器角…

YOLO11/ultralytics:环境搭建

前言 人工智能物体识别行业应该已经饱和了吧&#xff1f;或许现在并不是一个好的入行时候。 最近看到了各种各样相关的扩展应用&#xff0c;为了理解它&#xff0c;我不得不去尝试了解一下。 我选择了git里非常受欢迎的yolo系列&#xff0c;并尝试了最新版本YOLO11或者叫它ultr…

SQL注入漏洞之绕过[前端 服务端 waf]限制 以及 防御手法 一篇文章给你搞定

目录 绕过手法 前端代码绕过 后端代码绕过 各种字段进行验证 union 大小写绕过 双写逃过 强制类型判断 引号特殊编码处理。 内联注释绕过 注释符绕过 or/and绕过 空格绕过 防御SQL注入的方法 使用预编译语句 使用存储过程 检查数据类型 绕过手法 前端代码绕过…

使用冒泡排序模拟实现qsort函数

1.冒泡排序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h>int main() {int arr[] { 0,2,5,3,4,8,9,7,6,1 };int sz sizeof(arr) / sizeof(arr[0]);//冒泡排序一共排序 sz-1 趟for (int i 0; i < sz - 1; i){//标志位&#xff0c;如果有序&#xff0c;直接…

【Linux】线程互斥与同步

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;Linux系统编程 这里将会不定期更新有关Linux的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目…

【数据结构】二叉树

二叉树 1. 树型结构&#xff08;了解&#xff09;1.1 概念1.2 概念&#xff08;重要&#xff09;1.3 树的表示形式&#xff08;了解&#xff09;1.4 树的应用 2. 二叉树&#xff08;重点&#xff09;2.1 概念2.2 两种特殊的二叉树2.3 二叉树的性质2.4 二叉树的存储2.5 二叉树的…

1.五子棋对弈python解法——2024年省赛蓝桥杯真题

问题描述 原题传送门&#xff1a;1.五子棋对弈 - 蓝桥云课 "在五子棋的对弈中&#xff0c;友谊的小船说翻就翻&#xff1f;" 不&#xff01;对小蓝和小桥来说&#xff0c;五子棋不仅是棋盘上的较量&#xff0c;更是心与心之间的沟通。这两位挚友秉承着"友谊第…

Origami Agents:AI驱动的销售研究工具,助力B2B销售团队高效增长

在竞争激烈的B2B市场中,销售团队面临着巨大的挑战——如何高效地发现潜在客户并进行精准的外展活动。Origami Agents通过其创新的AI驱动研究工具,正在彻底改变这一过程。本文将深入探讨Origami Agents的产品特性、技术架构及其快速增长背后的成功因素。 一、一句话定位 Ori…

Java---猜数字游戏

本篇文章所实现的是Java经典的猜数字游戏 , 运用简单代码来实现基本功能 目录 一.题目要求 二.游戏准备 三.代码实现 一.题目要求 随机生成一个1-100之间的整数(可以自己设置区间&#xff09;&#xff0c;提示用户猜测&#xff0c;猜大提示"猜大了"&#xff0c;…

NLP深度学习 DAY5:Seq2Seq 模型详解

Seq2Seq&#xff08;Sequence-to-Sequence&#xff09;模型是一种用于处理输入和输出均为序列任务的深度学习模型。它最初被设计用于机器翻译&#xff0c;但后来广泛应用于其他任务&#xff0c;如文本摘要、对话系统、语音识别、问答系统等。 核心思想 Seq2Seq 模型的目标是将…

数据结构 队列

目录 前言 一&#xff0c;队列的基本知识 二&#xff0c;用数组实现队列 三&#xff0c;用链表实现队列 总结 前言 接下来我们将学习队列的知识&#xff0c;这会让我们了解队列的基本概念和基本的功能 一&#xff0c;队列的基本知识 (Queue) 我们先来研究队列的ADT&#xff0c…

Git 版本控制:基础介绍与常用操作

目录 Git 的基本概念 Git 安装与配置 Git 常用命令与操作 1. 初始化本地仓库 2. 版本控制工作流程 3. 分支管理 4. 解决冲突 5. 回退和撤销 6. 查看提交日志 前言 在软件开发过程中&#xff0c;开发者常常需要在现有程序的基础上进行修改和扩展。但如果不加以管理&am…

Java 大视界 -- Java 大数据在量子通信安全中的应用探索(69)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

国产碳化硅(SiC)MOSFET模块在电镀电源中全面取代进口IGBT模块

国产碳化硅&#xff08;SiC&#xff09;MOSFET模块在电镀电源中全面取代进口IGBT模块&#xff0c;倾佳电子杨茜分析以下几方面的技术、经济和政策优势&#xff1a; 倾佳电子杨茜致力于推动SiC碳化硅模块在电力电子应用中全面取代IGBT模块&#xff0c;助力电力电子行业自主可控…

linux用户管理

创建用户&#xff1a;useradd &#xff08;创建用户命令的详细使用&#xff1a;如何创建用户-CSDN博客&#xff09; &#xff08;如何创建具有重复uid的用户&#xff1a;如何创建具有重复uid的用户-CSDN博客&#xff09; 删除用户&#xff1a;userdel &#xff08;删除用户命…

【C++动态规划 离散化】1626. 无矛盾的最佳球队|2027

本文涉及知识点 C动态规划 离散化 LeetCode1626. 无矛盾的最佳球队 假设你是球队的经理。对于即将到来的锦标赛&#xff0c;你想组合一支总体得分最高的球队。球队的得分是球队中所有球员的分数 总和 。 然而&#xff0c;球队中的矛盾会限制球员的发挥&#xff0c;所以必须选…

【安全测试】测开方向学习遇到的问题记录

【问题一】springboot如何访问静态资源文件 springboot启动根路径位置 F:\untitled05\demo4\src\main\resources\static 例如图片位置存放在F:\untitled05\demo4\src\main\resources\static即可 配置文件配置 spring.web.resources.static-locationsfile:/F:/untitled05/de…