系列文章目录

QGraphicsItem图元的简单使用(一)
QGraphicsItem图元拖动绘制(二)

文章目录

  • 系列文章目录
  • 前言
  • 一、缩放和旋转
  • 二、自定义图元
  • 总结

前言

接上一章,图元绘制出来了,但有时候需要对图元进行缩放或旋转处理,这章先讲解如何调用图元自带函数来对图元进行缩放、旋转等操作;

一、缩放和旋转

先讲解下如何使用图元自带的缩放和旋转函数,后面自己派生QGraphicsItem时就可以通过鼠标拖动选中图元来实现缩放和旋转了;
简单处理,通过重写场景类的鼠标滑轮事件来实现,具体代码如下:

void GraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *event)
{// 获取当前选中的图元QList<QGraphicsItem *> listItem = this->selectedItems();foreach (QGraphicsItem *item, listItem){// 返回转轮旋转的距离,以八分之一度(1/8秒)为单位。正值表示滚轮向前旋转,远离用户;负值表示滚轮向用户方向向后旋转int iDelta = event->delta();if (item->type() == QGraphicsEllipseItem::Type)     // 椭圆进行缩放处理{QGraphicsEllipseItem* pEllipse = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);if(pEllipse != nullptr){// 获取图元绘图区域的矩阵,也就是图元被选中时那个虚线框QRectF rect = pEllipse->boundingRect();// 因为图元默认的缩放原点为(0,0),放大时图元朝着右下脚偏移,缩小时图元朝着左上角偏移// 所以设置图元中心点为缩放原点pEllipse->setTransformOriginPoint(rect.center());if(iDelta > 0)  // 放大{qreal dRate = 1.1;  // 每次放大10%pEllipse->setScale(pEllipse->scale() * dRate);}else if(iDelta < 0) // 缩小{qreal dRate = 0.9;  // 每次缩小10%pEllipse->setScale(pEllipse->scale() * dRate);}}}else if(item->type() == QGraphicsLineItem::Type)    // 直线进行旋转处理{QGraphicsLineItem* pLine = qgraphicsitem_cast<QGraphicsLineItem*>(item);if(pLine != nullptr){QRectF rect = pLine->boundingRect();// 因为图元默认的旋转原点为(0,0),所以设置图元中心点为缩放原点pLine->setTransformOriginPoint(rect.center());if(iDelta > 0)  // 逆时针{// 鼠标滑轮每滑动一次,直线旋转10°pLine->setRotation(pLine->rotation() + 10);}else if(iDelta < 0) // 顺时针{pLine->setRotation(pLine->rotation() - 10);}}}}return QGraphicsScene::wheelEvent(event);
}

二、自定义图元

通过继承QGraphicsItem图元类,来实现一个矩形图元,演示图如下:

头文件示例代码如下:

// .h文件
#include <QObject>
#include <QGraphicsItem>// 根据自己需要是否继承QObject,如果需要信号和槽则必须继承;另外,QObject必须放在前面
class RectItem : public QObject, public QGraphicsItem
{Q_OBJECT
public:RectItem(const QRectF& rect = QRectF(), QGraphicsItem *parent = nullptr);// 图元边界函数,必须实现QRectF boundingRect() const override;void setRect(const QRectF& rect){ m_rect = rect; this->update(); }// 设置绘制标志void SetDrawFlag(bool bDrawFlag){ m_bDrawFlag = bDrawFlag; }protected:void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;// 鼠标移动事件,需要特殊处理,防止鼠标拖动绘制时图元移动void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;private:// 需要绘制的矩形QRectF m_rect;// 绘制标志,防止第一次鼠标拖动绘制时,图元的鼠标移动事件触发,使得图元移动bool m_bDrawFlag = false;
};

源文件示例代码如下:

// .cpp文件
#include "RectItem.h"
#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include <QGraphicsSceneMouseEvent>RectItem::RectItem(const QRectF &rect, QGraphicsItem *parent): QGraphicsItem(parent), m_rect(rect)
{// 设置可移动、可选择、接收焦点等属性this->setFlags(QGraphicsItem::ItemIsMovable |
//                   QGraphicsItem::ItemIsFocusable |QGraphicsItem::ItemIsSelectable);
}QRectF RectItem::boundingRect() const
{// 设置图元绘制边界距离图元两个像素qreal dAdjust = 5;return m_rect.adjusted(-dAdjust, -dAdjust, dAdjust, dAdjust);
}void RectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{// 重绘函数,绘制矩形Q_UNUSED(widget);// 设置画笔和画刷painter->setPen(QPen(Qt::black, 1));painter->setBrush(Qt::green);// 绘制矩形painter->drawRect(m_rect);// 绘制选中时的虚框if (option->state & QStyle::State_Selected){// 获取图元绘制区域QRectF rect = this->boundingRect();// 绘制虚线框painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));painter->setBrush(Qt::NoBrush);// 设置虚线框距离绘图区域的间距,因为画笔有宽度const qreal pad = painter->pen().widthF() / 2;painter->drawRect(rect.adjusted(pad, pad, -pad, -pad));}
}void RectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{// 左键按下,并且当前处于绘制状态if (event->buttons() == Qt::LeftButton && m_bDrawFlag){return;}return QGraphicsItem::mouseMoveEvent(event);
}

直接添加到之前创建的工程,替换QGraphicsRectItem图元类即可,另外需要在场景的鼠标按下时,调用图元的设置绘制标志SetDrawFlag函数设置标志为true,鼠标释放时设置标志为false;

关于为什么QGraphicsRectItem在鼠标拖动绘制时,图元不会跟着移动,我看了下Qt源码,没找到具体原因,知道的大佬可以评论区留言


总结

下一节,将介绍如何使用鼠标拖动缩放图元

QGraphicsItem图元旋转缩放和自定义图元(三)相关推荐

  1. AutoCAD .Net 使用 DrawJig 来动态地移动、旋转、缩放多个图元

    本实例展示使用 DrawJig 技术,动态交互模式地移动.旋转.缩放多个图元. 如下图所示: 翻译自: AutoCAD .NET: Use DrawJig to Dynamically Move Ro ...

  2. woff字体图元结构剖析,自定义字体的制作与匹配和识别

    前面我在<2万字硬核剖析网页自定义字体解析>一文中,讲解了通过图像识别来解析自定义字体,但是图像识别的缺点在于准确率并不能达到100%,还需要二次修改. 前面将字体的称为点阵图,其实根据T ...

  3. Qt基于QGraphicsObject自定义图元并实现简单的动画

    文章目录 Qt基于QGraphicsObject自定义图元并实现简单的动画 举例; Qt基于QGraphicsObject自定义图元并实现简单的动画 Qt 图形的绘制 可以是QPainter方法直接绘 ...

  4. 201114阶段二qt自定义图元类

    目录 一.学习的知识点 一)自定义视图.场景.图元类 一)1 创建类 一)2 图元类的实现 一)3 advance槽函数 一)3 collidingItems()碰撞检测函数 二.上课没有听懂或者没有 ...

  5. 继承QGraphicsObject自定义图元

    QGraphicsObject继承自 QObject 和 QGraphicsItem,使用 QObject 的信号/槽和属性机制扩展了 QGraphicsItem. 创建自定义图元时,最重要的是重写 ...

  6. QGraphicsItem基本图元的添加以及闪烁图元和移动图元的添加

    基本图元有:椭圆,多边形,长方形,文字,图片等图元 通过代码演示各种图元的添加: ①主窗口头文(QMainWindow): #ifndef MAINWINDOW_H #define MAINWINDO ...

  7. 【Qt】Scene中获取指定类型的自定义图元

    通过阅读 Qt 官方文档中的"Elastic Nodes Example"例子,学习到如何在场景(Scene)中获取某个类型的自定义图元. 官方Demo运行效果: 该文档中,作者自 ...

  8. DeepEarth自定义图元的中心位置纠偏

    DeepEarth为B/S的地图应用开发提供了非常完善的解决方案,对于不熟悉Silverlight的同学来说,在开发中难免遇到各种大大小小的问题,本篇借鉴于最近网上一个朋友给我发邮件提出的问题,详细介 ...

  9. 图片(旋转/缩放/翻转)变换效果(ccs3/滤镜/canvas)

    以前要实现图片的旋转或翻转,只能用ie的滤镜来实现,虽然canvas也实现,但ie不支持而且不是html标准. css3出来后,终于可以用标准的transform来实现变换,而canvas也已成为ht ...

最新文章

  1. 计算机科学和Python编程导论(一) 计算机相关理论
  2. 分布式缓存DistributedCache的使用
  3. 机器学习-数据科学库(第五天)
  4. 一天就能上线音乐教学APP?网易云信首推音乐教学解决方案!
  5. 101_Power Pivot DAX 累计至今,历史累计至今
  6. BZOJ3171:[TJOI2013]循环格
  7. 扫码点菜系统代码_一顿火锅吃出474万天价?扫码点餐时,千万不要这样做
  8. OpenGL ES之3D模型加载和渲染
  9. 苏州大学计算机专业考研报录比,【图片】18年苏州大学计算机872考研经验分享【苏州大学研究生吧】_百度贴吧...
  10. 推荐电视剧 大秦帝国之裂变 2008
  11. 2019.5.summary
  12. JAVA实现 PDF转换 常用工具类(html转PDF、PDF添加页码、PDF文件下载、PDF添加印章或者水印)
  13. 论文的参考文献格式怎么弄呢?
  14. 安全计算:使用ClamWin为高级用户提供免费病毒防护
  15. 管道/过滤器架构风格的优点和不足
  16. 【工具】复制别人的CSDN博客文章到本地
  17. Linux网络 远程访问及控制
  18. 转一篇很好的AD转换设计中的基本问题整理
  19. 如何在java中获取JVM的各种系统参数
  20. extjs 修改官方主题

热门文章

  1. Android QQ 登录接入详细介绍
  2. lisp调用天正命令参数修改_在lisp中模拟运行CAD的command命令函数
  3. 缺血性中风和肠道菌群之间的桥梁:短链脂肪酸
  4. Leetcode_206_Reverse Linked List
  5. 服务器启动显示防火墙,宝塔面板防火墙怎么打开
  6. 電腦機房空調氣流設計與節能
  7. LabWindows的TEXTBOX和TABLE操作
  8. linux某服务启动失败,提示Authorization not available. Check if polkit...问题解决
  9. python荣联云通讯短信平台
  10. 【计算机网络】因特网和互联网的区别