1

我有一个来自 QRunnable 对象的派生类。它正在执行小型图像处理任务。看起来如下:

void ImageProcessor::run()
{
    int bytesPerLine;
    if(_format == QImage::Format_RGB32)
        bytesPerLine = _width * 4;

    QImage img(_buffer, _width, _height, bytesPerLine, _format);

    QTransform transform;
    transform.rotate(90);
    QImage rotatedImage = img.transformed(transform);


    _resultImage->clear();

    QBuffer buffer(_resultImage);

    buffer.open(QIODevice::WriteOnly);
    rotatedImage.save(&buffer, "JPG", 85);
    buffer.close();
}

我的问题是当我执行我的应用程序时,会显示以下错误消息,但并非总是如此。我可能会在其他时间运行它,但没有发现任何特别之处。

QObject::moveToThread: Current thread (0x2012268) is not the object's thread (0x2007dc0). Cannot move to target thread (0x21a6218)

我使用的唯一 QObject 派生类是 QBuffer,这个是在执行线程中本地创建的。我不明白为什么我会得到这个。

任何帮助,将不胜感激!

如果可以提供任何线索,我会在 Windows 7 和 MSVC2010 32 位下使用 QT 5.3 运行它。

以下链接指向重现问题的示例应用程序。ParallelImageProc.zip它包含一个屏幕截图,显示了我得到的实际结果。

谢谢!

4

1 回答 1

4

我终于找到了问题,我正在回答我自己的问题,以防它可以帮助其他人。

因此,问题与我使用 QBuffer 对象这一事实无关。我尝试执行类似于以下的操作,但未记录任何错误消息:

QBuffer buffer;
buffer.open(QBuffer::WriteOnly);
char buf[] = new char[100 * 1024 * 1024;
buffer.write(buf, 100 * 1024 * 1024);
delete [] buf;
buffer.close();

这让我感到困惑,因为从 QObject 派生的唯一类是 QBuffer。同时,我确定问题是由调用引起的:

rotatedImage.save(&buffer, "JPG", 85);

经过多次尝试并深入研究了 Qt 源文件,我发现我错了。还有另一个类继承了 QObject。图像格式使用幕后的插件进行管理。给我带来问题的类是 QImageIOPlugin。在 Qt 源代码中,这些类是从专用于图像格式的 QFactoryLoader 实例加载的。

以下线程,即使是针对不同的问题,也帮助我直接指出了我显示的错误消息的来源。

由于无法直接访问这个工厂加载的实例,解决问题的最简单方法是在使用任何线程之前将图像保存为所需的格式。就我而言,我只是在 main(...) 函数中添加了以下几行:

QImage image(10, 10, QImage::Format_RGB32);
QBuffer buffer;
buffer.open(QBuffer::WriteOnly);    
image.save(&buffer, "JPG", 85);
buffer.close();

在这种情况下,QImageIOPlugin 将在线程之前创建。将图像保存到 QBuffer 中不会出现错误消息,也不会出现问题。

希望这可以帮助别人。干杯!!

于 2014-11-07T20:14:03.317 回答