两个不同线程之间的信号/插槽调用后损坏QImage

时间:2015-07-22 20:57:58

标签: c++ multithreading image qt signals-slots

我通过信号/插槽机制在两个线程(后台数据库线程和GUI线程)之间发送QImage。 GUI插槽接收损坏的图像(某些像素随机损坏)。我已经这样做了,从来没有任何问题。可能有什么不对?

程序太复杂了,不能包含在这里,但这里有一些相关的信息:

  1. 发送线程(DB)是一个常规QThread,带有一个事件循环,运行一个DataBaseInterface QObject类,它被移动到这个线程
  2. 信号/插槽连接在moveToThread之后完成,因此每个对象都在其最终线程中。这意味着明确使用QueuedConnection没有区别,因为情况已经如此。
  3. QImage不是直接在signal / slot参数中发送,而是在包含其他内容(三个QVectors)的结构中发送。此结构使用以下注册:

    qRegisterMetaType<MyStruct>("MyStruct");
    
  4. QImage不是使用外部缓冲区创建的,而是使用(width,height,Format)构造函数创建的。因此,图像缓冲区在内部维护,因此隐含地共享

  5. 如果我在发出信号之后将图像保存到数据库线程中的磁盘上,那就很好了。如果我只是在插槽的开头保存它,它就会损坏。
  6. 有什么想法吗?

    谢谢!

1 个答案:

答案 0 :(得分:0)

好的,如果图像没有损坏,你应该确保以下内容:每个包含正在发送的结构的数据必须有复制构造函数,避免发送数据指针,如果你确定这些数据驻留在内存堆中,那么连接这些情况的类型是Qt :: QueuedConnection,建立图像的标签,您认为应配置如下:

label->setBackgroundRole(QPalette::Base);
label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
label->setScaledContents(true);

图像或结构的插槽应该如下所示,在我的情况下使用opencv和QT是:

void interfaz::actImagenFromVideo(cv::Mat myImage)
{
QImage image(myImage.data,myImage.cols, myImage.rows, myImage.step, QImage::Format_RGB888 );
label->setPixmap(QPixmap::fromImage(image.rgbSwapped()));
}

他运行QThread的功能应该类似于:

void THREAD::run()
{

 while(true){
 {
 QMutexLocker locker(&mutex);
 if (stopped) {
  stopped = false;
  break;
  }
  }

  cap>>videoIn;
  emit image_ready(videoIn.clone()); //the use of cv::Mat::clone() is very   important in openCV

  }

 }