以下是鼠标绘制矩形最全的一种用法,完整源码将会放在最后面。
QT版本:5.15.2
VS版本:2019
1、在界面加载一张图片
界面的搭建选用QGraphicsView,自定义类GraphicsView继承QGraphicsView,在主程序中点击按钮打开 图片,相关代码如下:
void testString::on_button_clicked() { QString fileName = QFileDialog::getOpenFileName(this, "open", QStandardPaths::writableLocation(QStandardPaths::PicturesLocation), "image (*.bmp *.png *.jpg)"); if (fileName.isEmpty()) { return; } QImage image(fileName); gview->setBackImage(image); }
2、创建矩形绘制对象,并绘制、移动矩形
在GraphicsView类中创建矩形绘制对象,并初始化该对象用于绘制矩形。在GraphicsView类的鼠标事件中设置绘制矩形时鼠标按下,移动,释放操作。
DrawROI* m_drawROI; m_drawROI = new DrawROI(this); m_drawROI->isDrawMultipleROIs(false); //是否允许画多个矩形 void GraphicsView::mousePressEvent(QMouseEvent* event) { QPoint nViewPoint = event->pos(); m_drawROI->changeROIBegin(nViewPoint); QGraphicsView::mousePressEvent(event); } void GraphicsView::mouseMoveEvent(QMouseEvent* event) { //鼠标按住左键移动 if (event->buttons() & Qt::LeftButton) { //绘制矩形时鼠标移动处理 m_drawROI->changeROIInProgress(event->pos()); } //设置鼠标形状 m_drawROI->changeMouseShape(event->pos()); QGraphicsView::mouseMoveEvent(event); } void GraphicsView::mouseReleaseEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { //矩形绘制结束 m_drawROI->changeROIEnd(event->pos()); } QGraphicsView::mouseReleaseEvent(event); }
3、对绘制的矩形长宽进行修改和界面缩放
矩形长宽的拖动会在DrawROI类中实现,界面的缩放把DrawROI类中的功能放入GraphicsView中的滚轮事件中
void GraphicsView::wheelEvent(QWheelEvent* ev) { //放大图元 m_graphicsViewTool->ScaleImage(ev); //图元放大,在图元上画的矩形不会放大,下面方法是让画的矩形和图元同比例放大,这里的画框是用QPainter方式,画出的东西不会随QGraphicsItem图元改变而改变 //如果在图元上依然用QGraphicsItem图元来画框,那他们会一起改变,自动同比例放大缩小,因为都是属于QGraphics系列 m_drawROI->ScaleROIS(ev, m_graphicsViewTool->GetScale()); }
4、绘制多个矩形并进行删除保存
绘制多个矩形需要做如下设置:
m_drawROI->isDrawMultipleROIs(true); //是否允许画多个矩形
对矩形进行右键删除和保存需要用到GraphicsView的右键菜单事件
m_pOptMenu = new QMenu(this); m_pDelAction = new QAction(QStringLiteral("删除"), this); connect(m_pDelAction, &QAction::triggered, m_drawROI, &DrawROI::DeleteCurrentROI); m_pSaveAction = new QAction(QStringLiteral("保存"), this); connect(m_pSaveAction, &QAction::triggered, m_drawROI, &DrawROI::saveAllROIImage); m_pOptMenu->addAction(m_pDelAction); m_pOptMenu->addAction(m_pSaveAction); void GraphicsView::contextMenuEvent(QContextMenuEvent* ev) { QPoint mousePos = ev->pos(); //QRect.contains被给的点在矩形内部返回true //场景坐标 QPointF fScenePoint = this->mapToScene(mousePos); //图形项坐标 QGraphicsItem* pItem = this->scene()->itemAt(fScenePoint, QTransform()); if (NULL != pItem) { QPointF fItemPoint = pItem->mapFromScene(fScenePoint); //获取图形项坐标 QPoint itemPoint(fItemPoint.x(), fItemPoint.y()); for (int i = 0; i < m_drawROI->getRoiRect().size(); i++) { if (m_drawROI->getRoiRect()[i].contains(itemPoint)) { m_pOptMenu->exec(QCursor::pos()); break; } } } ev->accept(); }