QGraphicsItem图元旋转缩放和自定义图元(三)
系列文章目录
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图元旋转缩放和自定义图元(三)相关推荐
- AutoCAD .Net 使用 DrawJig 来动态地移动、旋转、缩放多个图元
本实例展示使用 DrawJig 技术,动态交互模式地移动.旋转.缩放多个图元. 如下图所示: 翻译自: AutoCAD .NET: Use DrawJig to Dynamically Move Ro ...
- woff字体图元结构剖析,自定义字体的制作与匹配和识别
前面我在<2万字硬核剖析网页自定义字体解析>一文中,讲解了通过图像识别来解析自定义字体,但是图像识别的缺点在于准确率并不能达到100%,还需要二次修改. 前面将字体的称为点阵图,其实根据T ...
- Qt基于QGraphicsObject自定义图元并实现简单的动画
文章目录 Qt基于QGraphicsObject自定义图元并实现简单的动画 举例; Qt基于QGraphicsObject自定义图元并实现简单的动画 Qt 图形的绘制 可以是QPainter方法直接绘 ...
- 201114阶段二qt自定义图元类
目录 一.学习的知识点 一)自定义视图.场景.图元类 一)1 创建类 一)2 图元类的实现 一)3 advance槽函数 一)3 collidingItems()碰撞检测函数 二.上课没有听懂或者没有 ...
- 继承QGraphicsObject自定义图元
QGraphicsObject继承自 QObject 和 QGraphicsItem,使用 QObject 的信号/槽和属性机制扩展了 QGraphicsItem. 创建自定义图元时,最重要的是重写 ...
- QGraphicsItem基本图元的添加以及闪烁图元和移动图元的添加
基本图元有:椭圆,多边形,长方形,文字,图片等图元 通过代码演示各种图元的添加: ①主窗口头文(QMainWindow): #ifndef MAINWINDOW_H #define MAINWINDO ...
- 【Qt】Scene中获取指定类型的自定义图元
通过阅读 Qt 官方文档中的"Elastic Nodes Example"例子,学习到如何在场景(Scene)中获取某个类型的自定义图元. 官方Demo运行效果: 该文档中,作者自 ...
- DeepEarth自定义图元的中心位置纠偏
DeepEarth为B/S的地图应用开发提供了非常完善的解决方案,对于不熟悉Silverlight的同学来说,在开发中难免遇到各种大大小小的问题,本篇借鉴于最近网上一个朋友给我发邮件提出的问题,详细介 ...
- 图片(旋转/缩放/翻转)变换效果(ccs3/滤镜/canvas)
以前要实现图片的旋转或翻转,只能用ie的滤镜来实现,虽然canvas也实现,但ie不支持而且不是html标准. css3出来后,终于可以用标准的transform来实现变换,而canvas也已成为ht ...
最新文章
- 计算机科学和Python编程导论(一) 计算机相关理论
- 分布式缓存DistributedCache的使用
- 机器学习-数据科学库(第五天)
- 一天就能上线音乐教学APP?网易云信首推音乐教学解决方案!
- 101_Power Pivot DAX 累计至今,历史累计至今
- BZOJ3171:[TJOI2013]循环格
- 扫码点菜系统代码_一顿火锅吃出474万天价?扫码点餐时,千万不要这样做
- OpenGL ES之3D模型加载和渲染
- 苏州大学计算机专业考研报录比,【图片】18年苏州大学计算机872考研经验分享【苏州大学研究生吧】_百度贴吧...
- 推荐电视剧 大秦帝国之裂变 2008
- 2019.5.summary
- JAVA实现 PDF转换 常用工具类(html转PDF、PDF添加页码、PDF文件下载、PDF添加印章或者水印)
- 论文的参考文献格式怎么弄呢?
- 安全计算:使用ClamWin为高级用户提供免费病毒防护
- 管道/过滤器架构风格的优点和不足
- 【工具】复制别人的CSDN博客文章到本地
- Linux网络 远程访问及控制
- 转一篇很好的AD转换设计中的基本问题整理
- 如何在java中获取JVM的各种系统参数
- extjs 修改官方主题
热门文章
- Android QQ 登录接入详细介绍
- lisp调用天正命令参数修改_在lisp中模拟运行CAD的command命令函数
- 缺血性中风和肠道菌群之间的桥梁:短链脂肪酸
- Leetcode_206_Reverse Linked List
- 服务器启动显示防火墙,宝塔面板防火墙怎么打开
- 電腦機房空調氣流設計與節能
- LabWindows的TEXTBOX和TABLE操作
- linux某服务启动失败,提示Authorization not available. Check if polkit...问题解决
- python荣联云通讯短信平台
- 【计算机网络】因特网和互联网的区别