简体   繁体   中英

Qt updating displayed QImage

I acquire images from a camera by using a SDK which returns the data in an unsigned char array. However this SDK doesn't offer functionality to display the data, so I tried to implement this by using Qt 4.8 under Ubuntu 12.04.

At the moment my code looks like this:

#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();
    }
}

This works like expected, the images are displayed properly. However a.exec() blocks the main thread until I close the QtWindow.

Is there any easy way to modify this, so the window stays open all the time and just updates the displayed image? Performance doesn't matter at all at the moment, but I need to keep the code simple.

While a call to QApplication::processEvents will work, it's just a hack and not the best solution.

Ideally the image grabber should run on a separate thread as an object derived from QObect. This object emits signals of the images that it receives, which are received by an object on the main thread.

The receiving object can then set the image on the QGraphicsPixmapItem object.

Note that the code in the question creates a new QGraphicsPixmapItem for every image that is received from the grabber. Assuming you're wanting to create an animated image, you should only be creating and adding a single QGraphicsPixmapItem to the scene.

Using QThread is very easy and if you've not done it before, I suggest you read this article , which clearly explains what to do, with example code.

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM