主窗口是否仅在插槽子例程返回后更新?

时间:2013-08-09 17:06:47

标签: qt

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

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

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

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

问题是显示只会改变序列中的最终图像。即使我知道(来自printf())所有中间图像都调用了DisplayImg(),也没有显示任何中间图像。

是否有足够的信息来解释这个问题?我误解了插槽是如何工作的吗?在子程序on_Play_clicked()返回后,主Qt窗口是否不会更新?

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分: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

};

答案 2 :(得分:0)

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

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

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