0

我不知道我是否可以在不发布大量代码的情况下解释这个问题,但是这里有。

我有一个 Qt 应用程序,它应该显示一系列图像。每个图像都使用 QLabel 显示在 Qt 主窗口中。为了显示每个图像,我编写了一个名为 DisplayImg(int i) 的子程序,其中整数 i 是帧号。它适用于显示单个图像。

然后我创建了一个“播放”按钮(在 Qt 中),它应该播放一系列图像。播放按钮连接到名为 on_Play_clicked() 的插槽。这是一个执行此操作的子程序:

for (i = 0 ; i < N ; i++) 
    DisplayImg(i);

问题是显示仅针对序列中的最终图像发生变化。尽管我知道(从 printf() 中)所有中间图像都调用了 DisplayImg(),但没有显示任何中间图像。

这些信息足以解释问题吗?我是否误解了插槽的工作原理?Qt 主窗口在子例程 on_Play_clicked() 返回之前不会更新吗?

4

3 回答 3

3

是的。只有当控制流回到事件循环中时,Qt 才会执行绘制。您应该创建一个QTimer,将其timeout信号连接到一个插槽并以所需的间隔(以毫秒为单位)启动计时器。在插槽中,您应该显示下一个图像,例如DisplayImg(i); i++;。当前图像编号 (i) 应存储在类成员变量中。显示最后一张图像时,停止计时器。

于 2013-08-09T17:28:14.593 回答
0

您的图像在 Qt 主窗口上似乎没有发生变化的原因是您在更改每个图像之间没有延迟。如果你把你的代码改成这样,你应该会得到想要的效果:

for (i = 0 ; i < N ; i++)   
    QTimer::singleShot(5000 * i, this, SLOT(DisplayImg(i))); // sleep 5 seconds and then call display image

您需要将 DisplayImage 方法声明为类中的插槽,如下所示:
yourclass.h

#include <QtCore>

class YourClass : public QObject
{
    Q_OBJECT
private slots:
    void DisplayImage(int i);

// private members
// public members

};
于 2013-08-09T17:28:49.637 回答
0

只是为了完整性。通常对于像这样的问题 QCoreApplication::processEvents() 是一个解决方案。所以你的代码看起来像:

for (i = 0 ; i < N ; i++) {
    QCoreApplication::processEvents();
    DisplayImg(i);
}

但是......在这种特殊情况下,计时器解决方案显然优于 processEvent 解决方案。您只需更好地控制您的显示器。

于 2013-08-10T23:14:54.847 回答