2014-10-23 4 views
1

У меня есть производный класс из объекта QRunnable. Он выполняет небольшие задачи обработки изображений. Он выглядит следующим образом:QBuffer в QRunnable может или не может генерировать ошибку QObject :: moveToThread: текущий поток не является потоком объекта

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, и он создается локально в исполняемом потоке. Я не понимаю, почему я получаю это.

Любая помощь будет оценена!

Я запускаю это с QT 5.3, под Windows 7 и MSVC2010 32 бит, если он может дать какие-либо подсказки.

Следующая ссылка на пример приложения, который воссоздает проблему. ParallelImageProc.zip Он содержит скриншот, который показывает фактический результат, который я получаю.

Спасибо!

+1

Вы уверены, что описанный код действительно выдаст это предупреждение? – hank

+0

Абсолютно. Как только я прокомментирую rotatedImage.save (...), которые используют объект QBuffer, проблем больше не возникает. Также, если я это сделаю: Object * o = new QObject(); Буфер QBuffer (_resultImage, o) На этот раз я всегда получаю ошибку, а не спорадически. –

+0

Я проверил исходный код QBuffer, и у него нет никаких вызовов moveToThread. Я думаю, вы должны предоставить минимальный пример, который воспроизводит вашу проблему. – hank

ответ

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, предназначенного для форматов изображений.

following thread, даже если это было для другой проблемы, помогло мне указать прямо на начало моего отображаемого сообщения об ошибке.

Поскольку нет прямого доступа к экземпляру, загруженному на заводе, самый простой способ решить проблему - подделка изображения в желаемом формате перед использованием любых потоков. В моем случае, я просто добавил следующие строки в моей основной функции (...):

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

В таком случае QImageIOPlugin будет создан до ниток. Не будет сообщений об ошибках и проблем с сохранением изображений в QBuffer.

Надеюсь, это может помочь кому-то еще. Ура !!

+0

Это также решило мою проблему при вызове 'QCameraImageCapture :: capture()' в Qt5.5.1. – MaciekS