👀 前言
十字标辅助线是3D
雷达点云标注和2D
分类中常用的辅助标注工具。这个效果在经典的CAD
软件中很常用,还有一些股票软件,也有这种十字线定位线,有时候需要在十字交叉地方获取对应点的数据来显示等。如下,是海康相机客户端MVS
中的十字标辅助线效果,本文仿照其效果使用Qt
来进行实现。
💨 方式一:重构drawForeground()函数
这种方法主要是在继承基类QGraphicsView
的子类MF_GraphicsView
中完成,通过重写drawForeground()
函数功能,运行时系统会自动调用该函数,最终实现QWidget窗体中绘制红色十字前景函数的自动触发。
核心代码:
//.h——头文件 class MF_GraphicsView :public QGraphicsView { public: MF_GraphicsView(QWidget* _parent = nullptr); ~MF_GraphicsView(); protected: //QGraphicsView重构函数 virtual void drawForeground(QPainter *painter, const QRectF &rect); }
//.cpp——源文件 void MF_GraphicsView::drawForeground(QPainter *painter, const QRectF &rect) { QRectF rt = scene()->sceneRect(); //获取场景大小的绘制面积 QPen _pen; _pen.setColor(QColor(255,0,0)); _pen.setWidth(2); painter->setPen(_pen); //绘制两条红色十字交叉线 painter->drawLine(QLine(QPoint(rt.center().x(), 0), QPoint(rt.center().x(), rt.height()))); painter->drawLine(QLine(QPoint(0, rt.center().y()), QPoint(rt.width(), rt.center().y()))); }
强调:该函数drawForeground()
所在的类需要继承基类QGraphicsView。其声明函数前写不写virtual
都可以,因为基类中的drawForeground()
函数是虚函数,所以子类同名函数默认是虚函数。
💨 方式一:效果展示
参考帖子中的问答:https://bbs.csdn.net/topics/392435787
问题:重写QGraphicsView类,在类中重写paintEvent调用Qpainter的drawRect方法绘制矩形,单步调试,确定执行了drawRect, 但是发现绘制无效,哪位可以解答这是为什么?
解答:
1、别使用它的paintEvent(),要绘制图形需要重写GGraphicsItem中的paint()纯虚函数。或者也可以覆盖写QGraphicsView的drawBackground()或drawForeground()函数。
2、为什么要在view中重写paintEvent…一般是在scene上加item,然后重写item的paint 。
💦 方式二:手动添加辅助线——addLine
方式一是系统运行时,自动执行drawForeground
函数来添加辅助线的,后面我想的是通过右键菜单的方式来手动添加和取消,所以我又换了一种方式
核心代码:
//.h public: void dispCrossLine(); private: QGraphicsLineItem *m_HLineItem = nullptr; QGraphicsLineItem *m_VLineItem = nullptr;
//.cpp void MF_GraphicsView::dispCrossLine() { if (m_HLineItem == nullptr && m_VLineItem == nullptr) { m_HLineItem = new QGraphicsLineItem; m_VLineItem = new QGraphicsLineItem; m_HLineItem = m_scene->addLine(-m_view->viewport()->width(), 0, m_view->viewport()->width(), 0, QPen(Qt::red, 1)); //左右线 m_VLineItem = m_scene->addLine(0, -(m_view->viewport()->height()), 0, m_view->viewport()->height(), QPen(Qt::red, 1)); //上下线 } else { m_scene->removeItem((QGraphicsItem*)m_HLineItem); m_scene->removeItem((QGraphicsItem*)m_VLineItem); delete m_HLineItem; m_HLineItem = nullptr; delete m_VLineItem; m_VLineItem = nullptr; } }
强调:该函数也是在自定义的QGraphicsView的子类中完成的。这样,通过在菜单相应槽函数中直接调动实现函数dispCrossLine可实现手动添加/取消十字标辅助线。
💦 方式二:效果展示
戳戳小手帮忙点个免费的赞和关注吧,嘿嘿。 |