为什么消息循环不会阻止Windows应用程序中的GUI,但在Qt中呢?

时间:2013-04-20 00:57:16

标签: c++ multithreading qt winapi loops

我正在使用Qt编写程序,我的一些代码基于Windows示例。我遇到的问题,以及我不太明白的问题是,相同的代码将阻止我的Qt GUI,而它在Windows应用程序中完全正常工作。

这是一个例子。我有一个程序从相机中获取一些数据,对其进行一些处理,然后将其显示在屏幕上。在Windows示例中,有类似这样的内容:

// Create an event with these self-explanatory parameters
// This event signals when the next frame is ready to process
HANDLE frameEvent  = CreateEvent(nullptr, TRUE, FALSE, nullptr)

// Now run a while loop which magically doesn't block
HANDLE hEvents[1];

while (WM_QUIT != msg.message)
{
  hEvents[0] = frameEvent;

  DWORD dwEvent = MsgWaitForMultipleObjects(1, hEvents, FALSE, INFINITE, QS_ALLINPUT);

  // If we have our event run some processing
  if (WAIT_OBJECT_0 == dwEvent)
  {
    update();
  }
  // Else handle input or whatever
}

更新功能如下所示:

if (WAIT_OBJECT_0 = WaitForSingleObject(frameEvent, 0)
{
  getTheFrame();
  processTheFrame();
  drawTheFrame();
}

如果我尝试在Qt中以相同的方式实现它,一切都将冻结,而while循环将永远运行。我得到的解决方案是在单独的线程(QThread)中运行循环,并在新帧准备就绪时发出信号,如下所示:

void Worker::run()
{
    running_ = true;

    while (running_)
    {
        if (WaitForSingleObject(frameEvent, 0) == WAIT_OBJECT_0)
        {
            emit signalFrame();
        }

        // This is necessary or it will still freeze!
        usleep(15);
    }
}

然后将信号连接到一个插槽,该插槽与windows示例中的Update()方法的作用类似。

现在,这种方法很好,但只要处理单个帧可以在下一帧可用之前完成。

由于我的处理变得更复杂并且比相机帧速率慢,程序只是停止响应。 Windows样本中的完全相同的代码仍然可以正常工作,帧速率只是下降,但所有内容都被绘制,GUI仍然保持响应。

有人可以解释发生了什么,以及可能的解决方案是什么?

1 个答案:

答案 0 :(得分:3)

Win32版本调用MsgWaitForMultipleObjects。正如其名称所暗示的那样,它等待指定的对象用信号通知用于窗口消息(并且因为它用QS_ALLINPUT任何窗口消息)。据推测,代码之后也会调度窗口消息。

您的版本调用WaitForSingleObject。正如其名称所暗示的那样,它只等待 指定的对象。它不会在窗口消息上解锁。