Question

I am writing a code to show a video in a graphicsView QObject. It goes like this:

void MainWindow::UpdateVideo()
{
    cap >> frame;
    cvtColor(frame, frame,CV_BGR2RGB);
    QImage Qframe = QImage((uchar*) frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
    QPointer<QGraphicsScene> VideoScene = new QGraphicsScene;
    VideoScene->addPixmap(QPixmap::fromImage(Qframe));
    ui->VideoView->setScene(VideoScene);
    ui->VideoView->show();
}

void MainWindow::on_pushButton_2_clicked()
{
    cap.open("test1.mpg");
    if(!cap.isOpened())
       cout<<"CANNOT OPEN FILE"<<endl; //or you can put some error message
    QPointer<QTimer> UpdateVideo = new QTimer;
    connect(UpdateVideo, SIGNAL(timeout()), this, SLOT(UpdateVideo()));
    UpdateVideo->start(10);
}

As you can see, the slot on_pushButton_2_clicked() will call slot UpdateVideo() with the timer every 10ms after the first click. I want to get the video to displays flawlessly but after a few seconds the following error appears on the application output of qt creator:

Qimage: out of memory, returning null image.

And then the graphicsView frame goes blank. Can you tell me where is the memory leak?

Était-ce utile?

La solution

I don't think that QPointer does what you think. You are constantly allocating new QGraphicScenes. That's why you are running out of resources.

  1. The scene should be held by the window or outside.
  2. The QGraphicsPixmapItem* returned by addPixmap should be remebered.
  3. The setPixmap (const QPixmap &pixmap ) method of QGraphicsPixmapItem should be called to update the image.

For example:

class PixmapView
: public QGraphicsView
{
public:
    QPlotView( QGraphicsScene *scene) 
    : QGraphicsView( scene )
    , pixmap( 256, 256 )
    {
        pixmapItem = scene->addPixmap( pixmap );
        buffer.resize( 256*256*4 );
        startTimer( 100 );
    }

   void timerEvent( QTimerEvent* )
   {
       QImage image( &buffer[0], 256, 256, QImage::Format_ARGB32 );
       pixmapItem->setPixmap(  QPixmap::fromImage( image ) );
   }

private:
    std::vector<uchar> buffer;
    QPixmap pixmap;
    QGraphicsPixmapItem* pixmapItem;
};

Edit:

You are also constantly allocating new QTimers. A single timer should be a member of the window as it needs to survive the end of the method.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top