我正在使用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仍然保持响应。
有人可以解释发生了什么,以及可能的解决方案是什么?
答案 0 :(得分:3)
Win32版本调用MsgWaitForMultipleObjects
。正如其名称所暗示的那样,它等待指定的对象用信号通知或用于窗口消息(并且因为它用QS_ALLINPUT
,任何来调用窗口消息)。据推测,代码之后也会调度窗口消息。
您的版本调用WaitForSingleObject
。正如其名称所暗示的那样,它只等待 指定的对象。它不会在窗口消息上解锁。