以下是鼠标绘制矩形最全的一种用法,完整源码将会放在最后面。
QT版本:5.15.2
VS版本:2019
1、在界面加载一张图片
界面的搭建选用QGraphicsView,自定义类GraphicsView继承QGraphicsView,在主程序中点击按钮打开 图片,相关代码如下:
cpp
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类的鼠标事件中设置绘制矩形时鼠标按下,移动,释放操作。
cpp
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中的滚轮事件中
cpp
void GraphicsView::wheelEvent(QWheelEvent* ev)
{
//放大图元
m_graphicsViewTool->ScaleImage(ev);
//图元放大,在图元上画的矩形不会放大,下面方法是让画的矩形和图元同比例放大,这里的画框是用QPainter方式,画出的东西不会随QGraphicsItem图元改变而改变
//如果在图元上依然用QGraphicsItem图元来画框,那他们会一起改变,自动同比例放大缩小,因为都是属于QGraphics系列
m_drawROI->ScaleROIS(ev, m_graphicsViewTool->GetScale());
}
4、绘制多个矩形并进行删除保存
绘制多个矩形需要做如下设置:
cpp
m_drawROI->isDrawMultipleROIs(true); //是否允许画多个矩形
对矩形进行右键删除和保存需要用到GraphicsView的右键菜单事件
cpp
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();
}
=====================
📢博客主页: 主页
📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📢本文由 梦回阑珊 原创,首发于 CSDN,转载注明出处🙉
📢代码改变世界,你来改变代码!✨