【问题标题】:Qt updating displayed QImageQt 更新显示的 QImage
【发布时间】:2014-01-24 14:41:07
【问题描述】:

我使用 SDK 从相机获取图像,该 SDK 以无符号字符数组的形式返回数据。但是这个 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();
    }
}

这可以正常工作,图像显示正确。但是 a.exec() 会阻塞主线程,直到我关闭 QtWindow。

有什么简单的方法可以修改它,让窗口一直保持打开状态,只更新显示的图像?目前性能根本不重要,但我需要保持代码简单。

【问题讨论】:

  • 为什么要退出主事件循环?在大多数情况下,这意味着您可以终止您的应用程序。
  • 将 a.exec() 移出循环
  • 这不会阻塞主线程,但是显示只有在while循环结束后才会更新。这不是我想要的。
  • 然后使用QtConcurent或者QThread
  • 为什么不是 QApplication ::processEvents?

标签: c++ linux qt


【解决方案1】:

虽然调用 QApplication::processEvents 会起作用,但这只是一种技巧,并不是最佳解决方案。

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

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

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

使用 QThread 非常简单,如果你以前没有使用过,我建议你read this article,它清楚地说明了如何做,并附有示例代码。

【讨论】:

    【解决方案2】:
    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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-09
      • 1970-01-01
      • 1970-01-01
      • 2019-09-16
      • 1970-01-01
      • 2011-05-27
      相关资源
      最近更新 更多