[Qt学习笔记]Qt鼠标事件mouseMoveEvent实时获取图像的坐标和像素值

news2024/11/28 6:44:56

目录

  • 1、介绍
  • 2、效果展示
  • 3、实现过程
    • 3.1 图像的加载和显示
    • 3.2 设置鼠标跟踪事件激活
    • 3.3 实现代码
  • 4、源码展示

1、介绍

上一篇介绍了使用OpenCV的setMouseCallback回调函数实现获取鼠标点击点的图像坐标和像素值,本篇使用鼠标事件mouseMoveEvent函数来实现实时获取鼠标的坐标和对应图像点的像素值,并将结果实时显示在label控件上。

2、效果展示

123.gif

3、实现过程

3.1 图像的加载和显示

这里加载图像并在QLabel控件上显示,我这里使用OpenCV的imread函数加载了图像,然后把图像转换成QPixmap显示在QLabel上。

    img = imread("lena.png");
    cvtColor(img, img, COLOR_BGR2RGB);
    QImage disImage = QImage((const unsigned char*)(img.data), img.cols, img.rows, QImage::Format_RGB888);
    QPixmap pix = QPixmap::fromImage(disImage);

    pix.scaled(ui->lbl_pic->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
    ui->lbl_pic->setPixmap(pix);  // label 显示图像

这里也可以直接用QPixmap的load函数加载图像和显示,然后在mouseMoveEvent函数中要通过OpenCV获取图像的像素值时,将QPixmap格式再转换成Mat类型。

3.2 设置鼠标跟踪事件激活

激活控件内鼠标跟随属性,调用setMouseTracking(true)激活后在鼠标点击控件内区域进入mouseMoveEvent函数实现鼠标跟随。
如果想不点击鼠标在控件内移动触发mouseMoveEvent函数,就需要同时设置控件和窗口的setMouseTracking(true),这样鼠标在控件内移动时可以实时跟踪鼠标事件。

    /*激活控件鼠标跟随属性,激活后在点击鼠标后进入mouseMoveEvent函数*/
    /*如果不点击鼠标时想要在控件上触发mouseMoveEvent函数,就需要同时激活控件和窗口*/
    ui->lbl_pic->setMouseTracking(true);
    setMouseTracking(true);
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    QPoint pt = event->pos();
    QRect rect = ui->lbl_pic->geometry();
    if(rect.contains(pt)){
        QPoint PicPoint = QPoint(pt.x()-rect.x(), pt.y()- rect.y());
        QString str = QString("(x:%1,y:%2)").arg(PicPoint.x()).arg(PicPoint.y());
        ui->lbl_pos->setText(str);
        if(img.channels() == 1){
            int grayValue;
            switch (img.type())
            {
            case 0:
                grayValue = static_cast<int>(img.at<uchar>(Point(PicPoint.x(), PicPoint.y())));
                break;
            case 1:
                grayValue = static_cast<int>(img.at<char>(Point(PicPoint.x(), PicPoint.y())));
                break;
            case 2:
                grayValue = static_cast<int>(img.at<ushort>(Point(PicPoint.x(), PicPoint.y())));
                break;
            case 3:
                grayValue = static_cast<int>(img.at<short>(Point(PicPoint.x(), PicPoint.y())));
                break;
            case 4:
                grayValue = static_cast<int>(img.at<int>(Point(PicPoint.x(), PicPoint.y())));
                break;
            case 5:
                grayValue = static_cast<int>(img.at<float>(Point(PicPoint.x(), PicPoint.y())));
                break;
            case 6:
                grayValue = static_cast<int>(img.at<double>(Point(PicPoint.x(), PicPoint.y())));
                break;
            }
        }
        else
        {
            int value_B = static_cast<int>(img.at<Vec3b>(Point(PicPoint.x(), PicPoint.y()))[0]);
            int value_G = static_cast<int>(img.at<Vec3b>(Point(PicPoint.x(), PicPoint.y()))[1]);
            int value_R = static_cast<int>(img.at<Vec3b>(Point(PicPoint.x(), PicPoint.y()))[2]);
            QString str = QString("B:%1, G:%2, R:%3").arg(value_B).arg(value_G).arg(value_R);
            ui->lbl_pix->setText(str);
        }
    }
}

3.3 实现代码

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QMouseEvent>
#include "opencv2/opencv.hpp"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

using namespace cv;
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

protected:
    void mouseMoveEvent(QMouseEvent *event);
private:
    Ui::Widget *ui;
    Mat img;
};
#endif // WIDGET_H

widget.cpp

#pragma execution_character_set("utf-8")
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("坐标像素实时监控");
    img = imread("lena.png");
    cvtColor(img, img, COLOR_BGR2RGB);
    QImage disImage = QImage((const unsigned char*)(img.data), img.cols, img.rows, QImage::Format_RGB888);
    QPixmap pix = QPixmap::fromImage(disImage);

    pix.scaled(ui->lbl_pic->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
    // label 显示图像
    ui->lbl_pic->setPixmap(pix);
    /*激活控件鼠标跟随属性,激活后在点击鼠标后进入mouseMoveEvent函数*/
    /*如果不点击鼠标时想要在控件上触发mouseMoveEvent函数,就需要同时激活控件和窗口*/
    ui->lbl_pic->setMouseTracking(true);
    setMouseTracking(true);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    QPoint pt = event->pos();
    QRect rect = ui->lbl_pic->geometry();
    if(rect.contains(pt)){
        QPoint PicPoint = QPoint(pt.x()-rect.x(), pt.y()- rect.y());
        QString str = QString("(x:%1,y:%2)").arg(PicPoint.x()).arg(PicPoint.y());
        ui->lbl_pos->setText(str);
        if(img.channels() == 1){            //单通道图像
            int grayValue;
            switch (img.type())
            {
            case 0:
                grayValue = static_cast<int>(img.at<uchar>(Point(PicPoint.x(), PicPoint.y())));
                break;
            case 1:
                grayValue = static_cast<int>(img.at<char>(Point(PicPoint.x(), PicPoint.y())));
                break;
            case 2:
                grayValue = static_cast<int>(img.at<ushort>(Point(PicPoint.x(), PicPoint.y())));
                break;
            case 3:
                grayValue = static_cast<int>(img.at<short>(Point(PicPoint.x(), PicPoint.y())));
                break;
            case 4:
                grayValue = static_cast<int>(img.at<int>(Point(PicPoint.x(), PicPoint.y())));
                break;
            case 5:
                grayValue = static_cast<int>(img.at<float>(Point(PicPoint.x(), PicPoint.y())));
                break;
            case 6:
                grayValue = static_cast<int>(img.at<double>(Point(PicPoint.x(), PicPoint.y())));
                break;
            }
            QString str = QString("Gray Value:%1").arg(grayValue);
            ui->lbl_pix->setText(str);
        }
        else                                //多通道图像
        {
            int value_B = static_cast<int>(img.at<Vec3b>(Point(PicPoint.x(), PicPoint.y()))[0]);
            int value_G = static_cast<int>(img.at<Vec3b>(Point(PicPoint.x(), PicPoint.y()))[1]);
            int value_R = static_cast<int>(img.at<Vec3b>(Point(PicPoint.x(), PicPoint.y()))[2]);
            QString str = QString("B:%1, G:%2, R:%3").arg(value_B).arg(value_G).arg(value_R);
            ui->lbl_pix->setText(str);
        }
    }
}

4、源码展示

本小例程的代码放到我的开源gitte项目里,欢迎一起学习,也希望能收获你的小星星。
项目源码PixelPos_MouseFollow

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1530273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3+element Plus form 作为子组件,从父组件如何赋值?

刚开始接触vue3时&#xff0c;碰到一个很low的问题&#xff0c;将form作为子组件&#xff0c;在页面中给form表单项输入内容&#xff0c;输入框不显示值&#xff0c;知道问题出在哪&#xff0c;但因为vue3组合式api不熟悉&#xff0c;不知从哪下手... 效果图&#xff1a; 父组…

如何在iOS系统抓取log

前言&#xff1a;因为作者目前工作领域和苹果智能家居有关&#xff0c;然后发现一些bug其实是apple sdk原生code的问题&#xff0c;所以需要给apple提radar单&#xff0c;就需要抓ios端Log充当证据给apple看&#xff0c;其实ios抓log非常简单&#xff0c;大家感兴趣可以学习下哦…

Python条件语句深度解析:从基础到应用的全面指南

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 &#x1f4d8; 一、引言 &#x1f4dd; 二、…

【Flutter】导航组件 NavigationRail 的用法简介

​​Material Design 3 定义了三种导航模式&#xff0c;其用法和对应的 Flutter 组件如下所示&#xff1a; MD3 导航Flutter 组件用途Navigation barBottomNavigationBar小型屏&#xff08;宽度小于640&#xff09;Navigation drawerDrawer大型屏&#xff08;宽度大于960&…

Java基础 学习笔记四

标识符 标识符是在源代码中程序员自己有权利命名的单词标识符可以标识 变量名&#xff0c;方法名&#xff0c;类名 标识符命名规则 标识符只能由数字&#xff0c;字符&#xff08;java支持所有国家语言&#xff09;&#xff0c;_&#xff0c; $ 组成&#xff0c;不能含有其他…

基于树莓派实现 --- 智能家居

最效果展示 演示视频链接&#xff1a;基于树莓派实现的智能家居_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Tr421n7BM/?spm_id_from333.999.0.0 &#xff08;PS&#xff1a;房屋模型的搭建是靠纸板箱和淘宝买的家居模型&#xff0c;户型参考了留学时短租的公寓~&a…

软考高级:软件测试阶段概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

Linux课程____进程管理

记录工作日志 script 240319.log CTRLd 退出 cat 240319.log //查看 一、查看进程 1.静态 ps -aux ps -elf 2.动态 top 3.pgrep 查看特定条件的进程 pgrep -l “log” pgrep -l "ssh" pgrep -l -U redhat 4.pstree 查看进程树 pstree -aup 所有…

Flutter 在 Windows 下的开发环境搭建(Flutter SDK 3.19.2)【图文详细教程】

Git 下载与安装 对于 Flutter 3.19&#xff0c;Git 版本需要 2.27 及以上 Git 下载&#xff1a; Git 官网&#xff1a;https://git-scm.com/Git 下载淘宝镜像&#xff1a;https://registry.npmmirror.com/binary.html?pathgit-for-windows/ 对于 Git 的安装教程&#xff0c;…

Go 1.22 - 更加强大的 Go 执行跟踪

原文&#xff1a;Michael Knyszek - 2024.03.14 runtime/trace 包含了一款强大的工具&#xff0c;用于理解和排查 Go 程序。这个功能可以生成一段时间内每个 goroutine 的执行追踪。然后&#xff0c;你可以使用 go tool trace 命令&#xff08;或者优秀的开源工具 gotraceui&a…

Unable to load host key: /etc/ssh/ssh_host_rsa_key

Unable to load host key: /etc/ssh/ssh_host_rsa_key 启动docker镜像时报错 Unable to load host key: /etc/ssh/ssh_host_rsa_key Unable to load host key: /etc/ssh/ssh_host_ecdsa_key Unable to load host key: /etc/ssh/ssh_host_ed25519_key sshd: no hostkeys availa…

多特征变量序列预测(11) 基于Pytorch的TCN-GRU预测模型

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较-CSDN博客 风速预测&#xff08;一&#xff09;数据集介绍和预处理-CSDN博客 风速预测&#xff08;二&#xff09;基于Pytorch的EMD-LSTM模型-CSDN博客 风速预测&#xff…

什么是子网掩码、ip地址的网段?如何区分?

IP地址优化网写了很多相关的文章。 有些朋友对于子网掩码、IP地址网段等还不太了解&#xff0c;我们来看看网友经常问到的一些相关问题。 255.255.255.192 的位掩码是什么&#xff1f; 1.什么是子网掩码&#xff1f; 在了解IP地址的网段之前&#xff0c;我们先来了解一下子网…

【RabbitMQ | 第四篇】基于RabbitMQ实现延迟队列

文章目录 4.基于RabbitMQ实现延迟队列4.1延迟队列定义4.2基于DLX&#xff08;死信交换机&#xff09;实现延迟队列4.2.1实现思路4.2.2主要流程4.2.3实战&#xff08;1&#xff09;创建两个消息队列&#xff1a;原始消息队列、死信队列 and 为原始消息队列关联私信交换机&#x…

高精度AI火灾烟雾检测算法,助力打造更加安全的楼宇环境

一、方案背景 近日&#xff0c;南京居民楼火灾事故导致15人死亡的新闻闹得沸沸扬扬&#xff0c;这一事件又激起了大家对楼宇火灾隐患的进一步担忧。事后我们除了思考政府、消防及物业部门应对此事的解决办法&#xff0c;我们还应该思考如何利用现有的技术帮助人们减少此类事情的…

蓝桥杯模块综合——高质量讲解AT24C02,BS18B20,BS1302,AD/DA(PCF8591),超声波模块

AT24C02——就是一个存储的东西&#xff0c;可以给他写东西&#xff0c;掉电不丢失。 void EEPROM_Write(unsigned char * EEPROM_String,unsigned char addr , unsigned char num) {IIC_Start();IIC_SendByte(0xA0);IIC_WaitAck();IIC_SendByte(addr);IIC_WaitAck();while(nu…

非正向图片如何在OCR技术层面去解决?

在OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;技术中&#xff0c;非正向的图片一般是指倒过来或者没有固定版式的图片&#xff0c;要识别好这类图片确实是一个挑战。这类问题通常涉及到图像预处理、特征提取和识别算法等多个环节。以下…

SpringBoot项目前端Vue访问后端(图片静态资源) 配置

静态资源配置 Configuration public class WebMvcConfig extends WebMvcConfigurationSupport {Value("${file.save-path}")private String fileSavePath;Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {//映射本地文件夹registry…

python大学生健身爱好者交流网站flask-django-nodejs-php

任何系统都要遵循系统设计的基本流程&#xff0c;本系统也不例外&#xff0c;同样需要经过市场调研&#xff0c;需求分析&#xff0c;概要设计&#xff0c;详细设计&#xff0c;编码&#xff0c;测试这些步骤&#xff0c;基于python技术、django/flask框架、B/S机构、Mysql数据…

每日一练:LeeCode-167. 两数之和 II - 输入有序数组【双指针】

给你一个下标从 1 开始的整数数组 numbers &#xff0c;该数组已按 非递减顺序排列 &#xff0c;请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] &#xff0c;则 1 < index1 < index2 < numbers.…