文章目录

  • 前言
  • 一、事件过滤器
  • 二、示例完整代码展示
  • 三、下载链接
  • 总结

前言

本文主要讲述了使用QPainter在QLabel上进行图片的显示,并使用事件过滤器让QLabel捕获QEvent::Paint事件,并结合鼠标事件实现在图片上绘制其它图形。示例代码见文章内容,大家可以参考学习,如有错误之处,欢迎大家批评指正。

项目效果


提示:以下是本篇文章正文内容,下面案例可供参考

一、事件过滤器

Qt的事件过滤器会把控件的绘图事件给过滤,所以不能再任意控件上绘图,为了实现在QLabel上显示图片并在其上进行其它图形的绘制,首先需要给这个控件安装一个事件过滤器,然后重写bool eventFilter(QObject *obj, QEvent *event),代码如下。想要对事件过滤器进行更详细的了解可以参考该博客:Qt 事件过滤器(秒懂)

void Widget::initWidget()
{//...//安装事件过滤器ui->lb_image->installEventFilter(this);
}//重写eventFilter
bool Widget::eventFilter(QObject *watched, QEvent *event)
{if(watched ==ui->lb_image && event->type() == QEvent::Paint){upPaint();}return QWidget::eventFilter(watched,event);
}

二、示例完整代码展示

1.widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QPoint>
#include <QPen>
#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
#include <QDir>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void initWidget();void upPaint();protected:void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);bool eventFilter(QObject *watched, QEvent *event);private slots:void on_pb_line_1_clicked();void on_pb_line_2_clicked();void on_pb_rect_clicked();void on_pb_show_clicked();void on_pb_clear_clicked();private:Ui::Widget *ui;bool isPressed;//line1int lineNum;bool lineFlag1;QPoint linePoint[5];//line2bool lineFlag2;QPoint lineStartPoint;QPoint lineEndPoint;//rectbool rectFlag;int rect[4] = {0};};
#endif // WIDGET_H

2.widget.cpp

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);this->initWidget();
}Widget::~Widget()
{delete ui;
}void Widget::initWidget()
{isPressed = false;lineNum = 0;lineFlag1 = false;for(int i=0;i<5;i++){linePoint[i] = QPoint(0,0);}lineFlag2 = false;lineStartPoint = QPoint(0,0);lineEndPoint = QPoint(0,0);rectFlag = false;ui->lb_image->installEventFilter(this);
}void Widget::upPaint()     //绘图
{    QPainter painter(ui->lb_image);//显示图片QString imagePath = "E:/PhotoTest/drawTest.PNG";   //图片对应路径painter.drawPixmap(0,0,400,300,QPixmap(imagePath));//显示图片的另一种方法:setPixmap,这里不要使用//QImage Image;//Image.load(imagePath);//ui->lb_image->setPixmap(QPixmap::fromImage(Image));QPen pen;pen.setColor(Qt::red);painter.setPen(pen);painter.drawRect(1,1,100,50);painter.drawText(10,30,"测试文字");if(lineFlag1)   //line1{if(lineNum == 2){painter.drawLine(linePoint[0],linePoint[1]);}else if(lineNum == 3){painter.drawLine(linePoint[0],linePoint[1]);painter.drawLine(linePoint[1],linePoint[2]);}else if(lineNum == 4){painter.drawLine(linePoint[0],linePoint[1]);painter.drawLine(linePoint[1],linePoint[2]);painter.drawLine(linePoint[2],linePoint[3]);}else if(lineNum == 5){painter.drawLine(linePoint[0],linePoint[1]);painter.drawLine(linePoint[1],linePoint[2]);painter.drawLine(linePoint[2],linePoint[3]);painter.drawLine(linePoint[3],linePoint[4]);}else if(lineNum == 6){painter.drawLine(linePoint[0],linePoint[1]);painter.drawLine(linePoint[1],linePoint[2]);painter.drawLine(linePoint[2],linePoint[3]);painter.drawLine(linePoint[3],linePoint[4]);painter.drawLine(linePoint[4],linePoint[0]);}}if(lineFlag2)   //line2{painter.drawLine(lineStartPoint,lineEndPoint);}if(rectFlag)   //line2{painter.drawRect(rect[0],rect[1],rect[2],rect[3]);}//p.drawLine(QLine(100,100,100,250));//painter.drawRect(100,100,200,150);
}//鼠标按下
void Widget::mousePressEvent(QMouseEvent *event)
{if(event->button() == Qt::LeftButton){isPressed = true;if(lineFlag2){lineStartPoint = QPoint(event->pos().x()-30,event->pos().y()-30);lineEndPoint = QPoint(event->pos().x()-30,event->pos().y()-30);}else if(rectFlag){rect[0] = event->pos().x()-30;rect[1] = event->pos().y()-30;}}
}//鼠标移动
void Widget::mouseMoveEvent(QMouseEvent *event)
{if(isPressed){if(lineFlag2){lineEndPoint = QPoint(event->pos().x()-30,event->pos().y()-30);}else if(rectFlag){rect[2] = event->pos().x()-30 - rect[0];rect[3] = event->pos().y()-30 - rect[1];}this->update();}
}//鼠标抬起
void Widget::mouseReleaseEvent(QMouseEvent *event)
{qDebug()<<"Release:"<<QPoint(event->pos().x()-30,event->pos().y()-30);if(event->button() == Qt::LeftButton){if(lineFlag1){//多个点(以5个点示例)if(lineNum == 0){lineNum = 1;linePoint[0] = QPoint(event->pos().x()-30,event->pos().y()-30);this->update();}else if(lineNum == 1){lineNum = 2;linePoint[1] = QPoint(event->pos().x()-30,event->pos().y()-30);this->update();}else if(lineNum == 2){lineNum = 3;linePoint[2] = QPoint(event->pos().x()-30,event->pos().y()-30);this->update();}else if(lineNum == 3){lineNum = 4;linePoint[3] = QPoint(event->pos().x()-30,event->pos().y()-30);this->update();}else if(lineNum == 4){lineNum = 5;linePoint[4] = QPoint(event->pos().x()-30,event->pos().y()-30);this->update();}else if(lineNum == 5){lineNum = 6;this->update();}else{lineNum = 0;this->update();}}else if(lineFlag2){isPressed=false;lineEndPoint = QPoint(event->pos().x()-30,event->pos().y()-30);this->update();}else if(rectFlag){isPressed=false;rect[2] = event->pos().x()-30 - rect[0];rect[3] = event->pos().y()-30 - rect[1];this->update();}}else if(event->button() == Qt::RightButton){isPressed=false;lineNum = 0;lineFlag1 = false;lineFlag2 = false;rectFlag = false;this->update();}
}bool Widget::eventFilter(QObject *watched, QEvent *event)
{if(watched ==ui->lb_image && event->type() == QEvent::Paint){upPaint();}return QWidget::eventFilter(watched,event);
}void Widget::on_pb_line_1_clicked()
{lineFlag1 = true;lineFlag2 = false;rectFlag = false;this->update();
}void Widget::on_pb_line_2_clicked()
{lineFlag1 = false;lineFlag2 = true;rectFlag = false;this->update();
}void Widget::on_pb_rect_clicked()
{lineFlag1 = false;lineFlag2 = false;rectFlag = true;this->update();
}void Widget::on_pb_show_clicked()
{lineFlag1 = true;lineFlag2 = true;rectFlag = true;this->update();
}void Widget::on_pb_clear_clicked()
{isPressed = false;lineNum = 0;lineFlag1 = false;for(int i=0;i<5;i++){linePoint[i] = QPoint(0,0);}lineFlag2 = false;lineStartPoint = QPoint(0,0);lineEndPoint = QPoint(0,0);rectFlag = false;for(int i=0;i<4;i++){rect[i] = 0;}this->update();
}

3.widget.ui

三、下载链接

我的示例百度网盘链接:https://pan.baidu.com/s/1wJj8UHgr7Aub-7p8pojnrw
提取码:xxcj


总结

本文示例使用到了Qt的事件过滤器并重写了QPaintEvent、QMouseEvent等事件,这也是比较常见的方式。在我们之后的工作中,要学会灵活使用事件系统来实现自己的需求。示例中要注意的一点,这里在QLabel上显示图片需要使用QPainter中的drawPixmap,而不能使用QLabel的setPixmap方法,不然在进行绘制线条时出现无法显示的情况(其实是绘制出来了,但是被图片挡住了)。


hello:
共同学习,共同进步,如果还有相关问题,可在评论区留言进行讨论。

参考博客:
Qt 事件过滤器(秒懂)
QT中在QLabel显示图片并且利用鼠标点击画线

Qt实现在QLabel上显示图片并进行线条/矩形框/多边形的绘制相关推荐

  1. 【机器视觉】Qt联合Halcon编程之显示图片

    00. 目录 文章目录 00. 目录 01. 概述 02. 编写Halcon程序 03. Halcon程序导出C++文件 04. 创建Qt图形界面项目 05. Qt集成Halcon程序 06. 附录 ...

  2. 鼠标悬停文字上显示图片

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  3. VUE实现前台图片 标注(添加矩形框)、放大、缩小、拖拽 -----个人记录

    VUE实现前台图片 标注(添加矩形框).放大.缩小.拖拽 需求:实现图片上自定义多个矩形选框,选框可移动缩放拖动,图片可以放大缩小.拖拽 ,选框内填充标注文字. 框内填充文字基本都会,不多赘述,后期可 ...

  4. qt读取base64图片数据并在label上显示图片

    项目中有获取到服务器那边发来的base64图片数据在客户端进行显示,取到的数据使用 QPixmap::loadFromData(const QByteArray &buf, const cha ...

  5. python控制摄像头拍照_python+opencv+pyqt5控制摄像头在Qlabel上显示

    import cv2 import numpy as numpy from PIL import * import sys from PyQt5.QtWidgets import * from PyQ ...

  6. pyqt5 qlabel无法显示图片_实战PyQt5: 011-单选框控件QRadioButton

    单选框QRadioButton简介 QRadioButton为单选按钮, 可以选中(打开)或者取消选中(关闭).在一组单选按钮中,一次只能选中其中的一个按钮.选中或者取消选中QRadioButton, ...

  7. 使用libjpeg库在LCD上显示图片

    背景: 网上已经有很多关于利用libjpeg显示图片的文章了,因此本文的技术含量不算高.本文是使用libjpeg的v8版本,在开发板的LCD上显示jpg格式图片,关于libjpeg,可到其官方网站下载 ...

  8. Qt——P26 Label控件显示图片

    先把图片资源添加到Qt ui界面创建label //利用lable 显示图片ui->label_image->setPixmap(QPixmap(":/picture/abc.p ...

  9. html泳道连线图插件,mxGraph之在流程图上显示图片及泳道

    mxGraph开发过程中,显示流程图相信好多朋友通过fileio.html那个示例已经都能熟练操作了,至于为什么客户端Graph换出来的流程图上面的图片为什么在web层面上不显示,这是个很麻烦的问题, ...

最新文章

  1. js ZeroClipboard 拷贝文本到剪贴板
  2. python画三维温度散点图-python 绘制三维图形、三维数据散点图
  3. Spring的静态代理和动态代理
  4. 关于虚函数的应用(10个例子)
  5. qnx bsp 编译
  6. keepalived主要模块
  7. pdf导入ps颜色太浅_分享五个免费的pdf转换器,你更想选择哪一款?
  8. 计算机视觉与深度学习 | 基于边缘与形态学的细胞检测
  9. JDK8新特性:函数式接口@FunctionalInterface的使用说明
  10. 【Python文件处理】递归批处理文件夹子目录内所有txt数据
  11. 工信部推动第二批“5G+工业互联网”实践的通知
  12. 币氪研报|BNB(Binance Coin)
  13. 大学生学图像处理计算机要求,重点大学计算机教材:数字图像处理
  14. HDU1087 Super Jumping! Jumping! Jumping!【最长上升子序列+DP】
  15. python 选择题 多线程_python多线程练习题
  16. TOC约束理论AUTOCAD技巧
  17. 轻松构建并发送ICMP数据包
  18. spssχ2检验_案例实践:SPSS分层卡方检验
  19. 小数分频器vhdl实现_使用VHDL进行分频器设计(含小数)
  20. wx-微信公众号-静默登陆授权

热门文章

  1. Q版京剧脸谱来喽——状元
  2. npm --save-dev 和 --save的区别
  3. java输出执行开始时间,结束时间和运行时间
  4. Windows11中无法找到Office 2019 application的解决方案
  5. TouchScript中文---The Journey of a Touch Point
  6. CeSi 安装与配置
  7. 【ImportError: cannot import name ‘json‘ from ‘itsdangerous‘】
  8. git使用中遇到的remote:Permission to xxx denied to xxx问题如何解决
  9. 项目运行时报错出现:因为在此系统上禁止运行脚本有关详细信息,请参阅 https。该如何解决
  10. 服务器硬盘识别不到d盘,windows10系统本地磁盘找不到d盘如何解决