Qt,小部件刷新和ui交互性

时间:2011-06-05 08:00:33

标签: c++ qt user-interface opencv

我是Qt的全新品牌,我觉得它非常有价值。我正在尝试将一些现有的C ++代码与新的Qt GUI合并。基本上,我们的想法是在后端处理从.avi文件中提取的图像,然后在屏幕上QLabel显示。我设法得到以下代码来正确显示帧:

while (frame = cvQueryFrame(capture))
{
    // Some processing code...

    QImage qImageFrame((uchar*) frame->imageData, frame->width, frame->height, frame->widthStep, QImage::Format_RGB888);
    qImageFrame = qImageFrame.rgbSwapped();
    QPixmap qFrame;

    qFrame.convertFromImage(qImageFrame);
    label->setPixmap(qFrame);
    label->repaint();

    cvWaitKey(10);
}

然而,现在,这显然意味着UI停止响应用户输入,直到显示电影的所有帧。怎么样这样呢?

注意:我正在使用openCV库执行处理,该库需要特定格式的图像。例如,我认为我不能做的一件事就是直接在Qt域中使用.avi文件。

4 个答案:

答案 0 :(得分:3)

我不同意Tamás的建议,即他的答案是“最简单”的解决方案。

对您的问题最快,最少侵入性的解决方案是将qApp->processEvents();添加到您的循环中。我会在label->repaint();之后放弃它,看看会发生什么。

答案 1 :(得分:1)

你应该看看Qt Phonon multimedia framework。可能无法通过媒体文件获得OpenCV的控制级别,但值得深入研究。

对于您的原始问题:您必须在不同的主题中进行处理。这很棘手,因为你只能从UI线程调用GUI函数,而你(我想)不想过多地复制图像数据。

要获得良好的破败(以及指向Qt文档的提示),请查看Qt signaling across threads, one is GUI thread?。请注意,如果您想直接传递QImage,则需要额外的工作。

答案 2 :(得分:1)

有时最简单的解决方案是最好的。通过继承QRunnable来创建工作线程,以解码帧并将信号发送回GUI以更新帧。当Qt信号通过线程发出时,它们会被排队并正确分派。特别是在单个工作线程的情况下,由于并发问题,您不会感到头痛。复制QImage不是问题,因为它使用implicit sharing。要编写自己的隐式共享数据类,请使用QSharedDataPointer(据我所知,Qt也在内部使用它。)

答案 3 :(得分:0)

使用线程并不是唯一(或者确实是必然首选)方法。

您的UI正在阻止,因为您正在使用阻止睡眠(cvWaitKey)。如果您使用QTimer并将其超时信号连接到绘制下一帧的插槽,那么您的UI应保持响应。