求助大神!!QT通过信号和槽传递照图像指针,无法在label上显示

weixin_53157219 2021-02-01 09:03:45
void Widget::showImage(QImage *image)
{
ui->label_show->setScaledContents(true);
ui->label_show->setPixmap(QPixmap::fromImage(*image));
}

上面是槽函数,通过传递过来的信号进行UI显示,如果把上面两个都注释运行没有问题,可是一但开启就卡死,

下面是代码:

主函数.h文件
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QThread>
#include <QImage>
#include "MvCameraControl.h"
#include "camthread.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
Q_OBJECT

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

signals:
void needDeviceListSignal();//发送信号获取设备列表
void needGrabImage(int Id,MV_CC_DEVICE_INFO_LIST list);

private slots:
void getDeviceList(QString *text,MV_CC_DEVICE_INFO_LIST list);//获取设备列表并显示
void showImage(QImage *image);//显示图片槽函数

private slots:
void on_pushButton_seachDevice_clicked();
void on_pushButton_grabImage_clicked();

private:
QThread *thread;
CamThread *cam1;
MV_CC_DEVICE_INFO_LIST stDeviceList;//设备列表全局函数

private:
Ui::Widget *ui;
};
#endif // WIDGET_H


.cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QMetaType>


Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
qRegisterMetaType<MV_CC_DEVICE_INFO_LIST>("MV_CC_DEVICE_INFO_LIST");

/* * 初始化对象* */
cam1 = new CamThread();
thread = new QThread(this);
cam1->moveToThread(thread);

/* * 信号槽 * */
connect(this,&Widget::needDeviceListSignal,cam1,&CamThread::EnumDevice);//调用线程查询设备列表
connect(cam1,&CamThread::sendDeviceListSignal,this,&Widget::getDeviceList,Qt::DirectConnection);//根据线程查询列表返回信息调用显示槽函数
connect(this,&Widget::needGrabImage,cam1,&CamThread::connectDevice);//调用连接设备及取图函数
connect(cam1,&CamThread::sendImageSignal,this,&Widget::showImage);//通过传递回的信号调用图像显示函数
}

Widget::~Widget()
{
delete ui;
cam1->isOpen = false;
thread->quit();
thread->wait();
}

void Widget::getDeviceList(QString *text,MV_CC_DEVICE_INFO_LIST list)
{
stDeviceList = list;
ui->comboBox_DeviceList->addItem(*text);
}

void Widget::showImage(QImage *image)
{
ui->label_show->setScaledContents(true);
ui->label_show->setPixmap(QPixmap::fromImage(*image));
}

void Widget::on_pushButton_seachDevice_clicked()//按下查询设备列表按钮
{
thread->start();
emit needDeviceListSignal();
qDebug()<< "发送查询信号";
}

void Widget::on_pushButton_grabImage_clicked()//按下采集按钮
{
int Id = ui->comboBox_DeviceList->currentIndex();
emit needGrabImage(Id,stDeviceList);
}


下面是线程中发送信号的部分
void CamThread::GetImage(void *handle,MV_FRAME_OUT_INFO_EX stImageInfo,unsigned char * pData)//循环取图
{

while (isOpen)
{
int nRet = MV_CC_GetOneFrameTimeout(handle, pData, g_nPayloadSize, &stImageInfo, 100);
if (nRet == MV_OK)
{
cv::Mat dstImga;
dstImga = Convert2Mat(&stImageInfo, pData);
//cv::imshow("image",dstImga);
cv::cvtColor(dstImga,dstImga,cv::COLOR_BGR2RGB);
QImage Qtemp = QImage((const unsigned char*)(dstImga.data), dstImga.cols, dstImga.rows, dstImga.step, QImage::Format_RGB888);
emit sendImageSignal(&Qtemp);
}
else
{
QString text = QString("无图像数据!nRet [%1]").arg(nRet);
qDebug() << text;
free(pData);
pData = NULL;
return;
}
//qDebug()<< "循环取图";
QThread::msleep(500);
qDebug()<<"子线程"<<QThread::currentThread();
}
}
...全文
1827 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
熊猫呀 2021-02-03
  • 打赏
  • 举报
回复
引用 5 楼 weixin_53157219 的回复:
我咋感觉是这个有点问题呢 QImage Qtemp = QImage((const unsigned char*)(dstImga.data), dstImga.cols, dstImga.rows, dstImga.step, QImage::Format_RGB888); emit sendImageSignal(&Qtemp); Qtemp 这个传递信号后 如果是默认的AutoConnet 他应该会放到队列循环中。然后 Qtemp 应该会消失,你把这个 Qimage 变成 指针试试
不是这个的问题 像3楼说的一样 就是没有采样直连,导致信号在队列等待连接,结果连接上的时候原地址改变了,所有导致野指针,报错了,报的是跟什么c盘sougou文件的问题一样,网上查的资料都说这个就是野指针造成的[/quote] QImage Qtemp 在栈上 当你发出信号以后 AutoConnet 连接 就会把 Qtemp 的栈地址 扔到消息队列中,然后程序继续执行。Qtemp生命周期结束。所以然你autoConnet 时用个指针 new 。这不跟 windows 的postmessage 和 sendmessage 一样的嘛?
  • 打赏
  • 举报
回复
直连就直接在执行的时候跑到槽函数里,图片指针指向的数据还在 如果是多线程会自适应成队列方式,就是先把信号和参数缓存,扔事件循环里,等事件循环的下一轮来了再执行,这时候图片指针在原线程可能已经释放或者改变地址了。 多线程也可以开一个buffer然后用阻塞队列的连接方式,这样不会导致崩溃。
熊猫呀 2021-02-02
  • 打赏
  • 举报
回复
引用 1 楼 weixin_53157219 的回复:
随便试了试 原来是connect(cam1,&CamThread::sendImageSignal,this,&Widget::showImage);//通过传递回的信号调用图像显示函数 通过信号传递回来的图片要显示必须使用最后一个参数,调整为connect(cam1,&CamThread::sendImageSignal,this,&Widget::showImage,Qt::DirectConnection); 这样就可以了 希望对同样遇到此问题的人一点帮助
我咋感觉是这个有点问题呢 QImage Qtemp = QImage((const unsigned char*)(dstImga.data), dstImga.cols, dstImga.rows, dstImga.step, QImage::Format_RGB888); emit sendImageSignal(&Qtemp); Qtemp 这个传递信号后 如果是默认的AutoConnet 他应该会放到队列循环中。然后 Qtemp 应该会消失,你把这个 Qimage 变成 指针试试
weixin_53157219 2021-02-02
  • 打赏
  • 举报
回复
我咋感觉是这个有点问题呢 QImage Qtemp = QImage((const unsigned char*)(dstImga.data), dstImga.cols, dstImga.rows, dstImga.step, QImage::Format_RGB888); emit sendImageSignal(&Qtemp); Qtemp 这个传递信号后 如果是默认的AutoConnet 他应该会放到队列循环中。然后 Qtemp 应该会消失,你把这个 Qimage 变成 指针试试 [/quote] 不是这个的问题 像3楼说的一样 就是没有采样直连,导致信号在队列等待连接,结果连接上的时候原地址改变了,所有导致野指针,报错了,报的是跟什么c盘sougou文件的问题一样,网上查的资料都说这个就是野指针造成的
weixin_53157219 2021-02-02
  • 打赏
  • 举报
回复
引用 1 楼 weixin_53157219 的回复:
随便试了试 原来是connect(cam1,&CamThread::sendImageSignal,this,&Widget::showImage);//通过传递回的信号调用图像显示函数 通过信号传递回来的图片要显示必须使用最后一个参数,调整为connect(cam1,&CamThread::sendImageSignal,this,&Widget::showImage,Qt::DirectConnection); 这样就可以了 希望对同样遇到此问题的人一点帮助
引用 3 楼 这是一个正经昵称 的回复:
直连就直接在执行的时候跑到槽函数里,图片指针指向的数据还在 如果是多线程会自适应成队列方式,就是先把信号和参数缓存,扔事件循环里,等事件循环的下一轮来了再执行,这时候图片指针在原线程可能已经释放或者改变地址了。 多线程也可以开一个buffer然后用阻塞队列的连接方式,这样不会导致崩溃。
是的 我看了看海康的事例代码,里面就做了一个用作缓存的buffer,这样就不会在出现类似野指针的报错了
weixin_53157219 2021-02-01
  • 打赏
  • 举报
回复 1
随便试了试 原来是connect(cam1,&CamThread::sendImageSignal,this,&Widget::showImage);//通过传递回的信号调用图像显示函数 通过信号传递回来的图片要显示必须使用最后一个参数,调整为connect(cam1,&CamThread::sendImageSignal,this,&Widget::showImage,Qt::DirectConnection); 这样就可以了 希望对同样遇到此问题的人一点帮助
池皓辰 2022-04-12
  • 举报
回复
@weixin_53157219 我那个是在槽函数里用label直接显示不了图,自己电脑里的图也显示不了,放在槽函数外面就可以显示,你知道为什么吗?
内容概要:本文研究基于粒子群算法(PSO)优化模糊C均值聚类(FCM)的居民用电行为分析方法,提出一种改进的FCM聚类算法,通过引入粒子群优化机制,有效提升聚类性能与收敛效率,克服传统FCM算法易陷入局部最优、对初始聚类中心敏感等缺陷。研究基于Matlab平台实现算法代码,对居民用电负荷数据进行聚类分析,识别不同用户的典型用电模式与行为特征,进而支持电力系统的需求侧精细化管理、用户分群运营、个性化用电服务推荐以及中长期负荷预测。该方法在智能电网与大数据背景下展现出良好的应用前景,特别适用于大规模居民用电数据的行为挖掘与模式识别任务。; 适合人群:具备一定电力系统基础知识、数据挖掘或智能优化算法背景的科研人员及工程技术人员,尤其适合从事智能电网、负荷特性分析、需求响应、用户行为研究等方向的硕士、博士研究生及高校教师。; 使用场景及目标:①实现居民用户用电行为的有效分类与典型负荷曲线提取;②优化电力客户细分策略,支撑差异化电价、需求响应激励政策的设计与实施;③为负荷预测、电网规划、配电台区管理提供数据驱动的决策依据;④作为高水平学术论文(如EI、SCI期刊)的研究基础,用于算法复现、性能对比与创新改进。; 阅读建议:建议读者结合提供的Matlab代码深入理解PSO-FCM算法的具体实现流程,重点关注粒子编码方式、适应度函数构建、聚类有效性评价指标(如轮廓系数、误差平方和)的应用,鼓励在真实用电数据集上进行实验验证,并尝试引入其他优化策略或评估维度以进一步提升模型鲁棒性与实用性。
【重要提示】本资源设置为0积分下载,若非0积分请勿轻易下载 亲爱的CSDN用户: 首先感谢你点进这个资源页面。我需要提前说明一个重要情况: 本资源原本已设置为“0积分下载”,即作者希望完全免费共享。但CSDN平台有时会根据文件的下载热度、文件大小、用户权限等因素,自动将部分资源的积分调整为非0数值(如1积分、2积分、5积分等)。这是平台系统的自动行为,而非作者本人的设定。 因此,如果你当前看到该资源的下载所需积分不是0(例如显示为1、2、3……),请谨慎决定是否下载。 如果你按照非0积分支付并下载后发现资源内容不符合预期、链接失效,或者实际上该资源本应是免费的,作者无法为此承担积分损失或退还操作。强烈建议:仅在页面显示为0积分时进行下载。 另外,本资源描述中并未直接提供具体的下载地址或外部链接,因为它本身是一个通过CSDN官方上传通道提交的文件/内容包。如果你看到描述中没有外部网盘地址,这是正常的——资源文件应通过CSDN内置的“下载”按钮获取。若因平台积分显示异常导致你支付了积分,请优先联系CSDN客服咨询积分退还政策,作者没有权限修改平台自动设定的积分值。 感谢你的理解与支持。技术分享本应开放,但受限于平台规则,特此提醒如上。祝学习进步!
代码转载自:https://pan.quark.cn/s/a1913ccaa47a 在信息技术领域中,图像处理占据着核心地位,特别是在嵌入式系统以及移动设备上,由于受到资源条件的制约,常常需要将高分辨率的图像格式转化为低分辨率的格式,以此来提升显示效能和存储容量。"bmp格式转为rgb565格式图片转换工具"正是为了应对这种需求而研发的。BMP(Bitmap)是一种广泛应用的位图格式,它完整地记录了图像的每一个像素点信息,涵盖了色彩深度、透明度等参数。然而,这种格式在内存消耗和处理速率方面并不具备优势,尤其是在需要高速渲染的情境下。RGB565是一种16位的色彩编码格式,普遍应用于嵌入式系统,例如由微控制器控制的LCD显示屏。它通过分配5位红色、6位绿色以及5位蓝色分量来表现色彩,总共能够呈现2^16 = 65536种色彩,尽管其色彩数量(约1670万种)少于BMP的24位色彩,但足以满足绝大多数显示场景,并且显著降低了数据存储和传输的负担。这种转换工具的运作机制在于读取BMP文件中的每一个像素点,然后依照RGB565的编码规范重新组织色彩信息。在BMP文件中,像素数据一般以行为单位进行存储,遵循从左到右、自下而上的顺序。而在RGB565格式中,每个像素点由两个字节构成,其中红色和蓝色各占5位,绿色占据6位,这样的布局旨在提升内存中的对齐效率。转换流程通常包括以下几个环节:1. 分析BMP文件头部:BMP文件头部包含了图像的宽度、高度、色彩深度等关键数据,这是进行转换的依据。2. 获取像素数据:按照BMP文件的结构读取每一行的像素点信息。3. 色彩转换:将每个24位RGB色彩点转换为16位RGB565格式。4. 输出新格式:将转换后的RGB565数据写入新的...

65,212

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧