在QTCreator GUI中播放视频

时间:2011-12-07 18:54:07

标签: c++ user-interface opencv qt-creator nokia

我目前正在使用QTCreator版本4.7.4来编写一个在应用程序中播放AVI文件的GUI应用程序。

我这样做的方法是将每个帧设置为QLabel内的QPixmap。

         video.load("lk",video.EXT_AVI);
         if(video.hasLoaded()){
              while(!video.hasFinished()){
                  frame = video.getCurrentFrame();
                  cv::cvtColor(frame, frame, CV_BGR2RGB);
                  QImage myImage = QImage( (const unsigned char*) (frame.data),frame.cols, frame.rows, frame.step1(),QImage::Format_RGB888 );
                  ui->displayLabel->setPixmap((QPixmap::fromImage(myImage)));
                  video.nextFrame();
    }
}

由于我使用opencv API中的VideoCapture类来获取每个帧,因此帧最初被检索为CV :: MAT对象,因此我将它们转换为QImages。

如果我在一个简单的控制台程序中使用opencv API中的CV :: imshow()函数,我可以正常播放文件,但是当我在循环中运行上面的代码时,我的程序本质上崩溃直到最后一帧,然后它将返回到显示最后一帧的稳定状态。

我对C ++很陌生,但对Java有很好的经验,所以我对这个问题的初步猜测是一切都在事件线程上完成,因此占用了所有资源,导致应用程序停止回应一段时间。

任何帮助将不胜感激。

注意:视频是我自己的类,它封装了opencv API中的VideoCapture类。

1 个答案:

答案 0 :(得分:5)

简而言之:

您的代码在视频播放过程中不会更新UI,因此程序会挂起。

详细

主要问题是,在您对代码中的窗口小部件状态进行任何更改后,Qt不会更新UI。 Qt使用events来更新小部件。并且在常见情况下处理的所有事件都在单线程中运行。您的代码也是事件处理程序(可能它是按钮单击事件的处理程序)。您的代码会更改循环中窗口小部件的状态,但仅在窗口小部件处理事件后才会显示更改。但是小部件只能在处理当前事件后处理事件,即代码。因此,您的代码确实会阻止处理直到完成。当它完成后,你会看到最后一帧。

你应该做什么

你不能在这里使用循环(好吧,你真的可以,但不需要) 你应该创建一个函数,它显示一个单独的框架,然后完成让Qt处理事件。 并且Qt应该在一定的时间间隔内调用此函数,该时间间隔由帧速率确定 使Qt以指定的时间间隔调用某个函数的最佳方法是使用timer

因此,要开始播放,您应该初始化video stream ant启动一个计时器。显示最后一帧后,您应该停止计时器。