Qt更新显示QImage

时间:2014-01-24 14:41:08

标签: c++ linux qt

我使用SDK从相机获取图像,该SDK返回unsigned char数组中的数据。但是,此SDK不提供显示数据的功能,因此我尝试使用Ubuntu 12.04下的Qt 4.8实现此功能。

目前我的代码看起来像这样:

#include <QtGui/QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene scene;
    QGraphicsView view(&scene);

    while (..) // condition which breaks after a number of images where grabbed
    {
        // Get the image from the third party SDK into an unsigned char array
        // named pImageBuffer

        QImage image ((unsigned char *) pImageBuffer, 
            GetWidth(), 
            GetHeight(), 
            QImage::Format_Indexed8);

        QVector<QRgb> colorTable(256);
        for(int i=0;i<256;i++)
            colorTable[i] = qRgb(i,i,i);
        image.setColorTable(colorTable);

        QPixmap pixmap = QPixmap::fromImage(image);
        QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
        scene.addItem(item);

        view.show();
        a.exec();
    }
}

这与预期一样,图像显示正常。但是,在关闭QtWindow之前,a.exec()会阻塞主线程。

有没有简单的方法来修改它,所以窗口始终保持打开状态,只是更新显示的图像?性能目前根本不重要,但我需要保持代码简单。

2 个答案:

答案 0 :(得分:3)

虽然对QApplication :: processEvents的调用可行,但它只是一个黑客而不是最佳解决方案。

理想情况下,图像采集器应作为从QObect派生的对象在单独的线程上运行。此对象发出它接收的图像的信号,这些信号由主线程上的对象接收。

接收对象然后可以在QGraphicsPixmapItem对象上设置图像。

请注意,问题中的代码会为从抓取工具接收的每个图像创建一个新的QGraphicsPixmapItem。假设您想要创建一个动画图像,您应该只创建一个QGraphicsPixmapItem并将其添加到场景中。

使用QThread非常简单,如果您以前没有这样做,我建议您read this article,它通过示例代码清楚地解释了该怎么做。

答案 1 :(得分:0)

class ImageGrabber
{
   Q_OBJECT
public:
   ImageGrabber(QPixmapItem* item) : _item(item)
   {
      connect( &timer, SIGNAL(timeout()), this, SLOT(grabImage()) )
      _timer.start(33); // 33 ms between timeouts.
   }

public slots:
   void grabImage()
   {
      // Update image
      QImage image(...);

      _item->setPixmap( QPixmap::fromImage(image) );
   }

private:
   QPixmapItem* _item;
   QTimer _timer;
};

int main(...)
{
   QApplication a(argc,argv);
   ...
   view.show();
   QGraphicsPixmapItem* pixmapItem = scene.addPixmap(QPixmap());

   ImageGrabber ig(pixmapItem);

   return a.exec();
}