在QTCreator GUI中播放视频

Bla*_*Box 2 c++ user-interface opencv nokia qt-creator

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

我这样做的方法是将每个帧设置为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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

任何帮助将不胜感激.

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

Lol*_*4t0 5

简而言之:

您的代码在视频播放期间不会更新UI,因此程序挂起.

详细

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

你该怎么办

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

因此,要开始播放,您应该初始化video流蚂蚁启动计时器.显示最后一帧后,您应该停止计时器.