4

我正在使用 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);
    }
}

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

现在,这可以正常工作,但只要在下一帧可用之前可以处理单个帧即可。

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

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

4

1 回答 1

3

Win32 版本调用MsgWaitForMultipleObjects. 正如它的名字所暗示的那样,它等待指定的对象发出信号等待窗口消息(并且因为它是用 调用的QS_ALLINPUT所以任何窗口消息)。大概代码之后还会发送窗口消息。

您的版本调用WaitForSingleObject. 顾名思义,它只等待指定的对象。它不会在窗口消息上解锁自己。

于 2013-04-20T06:35:10.380 回答