Qt程序挂起(无响应)直到功能结束然后再次开始工作

时间:2013-04-22 14:28:59

标签: c++ qt

我在Qt中有一个UI应用程序,我有几个运行大规模SQL查询的函数,可以返回数千个结果。

当单击运行此查询的按钮时,UI窗口立即进入“无响应”但是我可以从控制台输出中看到所有内容实际上仍在后台运行。一旦函数结束,数据就会按预期显示,并且UI再次响应并完全正常运行。

我知道这是因为由于大量的结果,函数循环了数千次,但我希望我可以放入一个加载条,随着搜索的进行而不仅仅是锁定窗口使它看起来像程序已崩溃。 AFAIK我没有内存泄漏所以有人有任何建议吗?

哦,我也认为它不是内存泄漏,因为当我点击该按钮任务管理器显示只有几MB的内存用于此过程而处理器绝不是最大化

2 个答案:

答案 0 :(得分:5)

在一个应用程序中,有一个线程负责处理UI事件,消息,以及你想要调用它们的任何内容。假设您有一个按钮单击事件。只要您不从回调函数返回,就不会触发其他UI事件(重新绘制,更新等),并且UI变得无法响应。

为了缓解这种情况,您应该考虑在单独的线程中执行耗时的任务,一旦完成,就相应地更新UI。如果您需要在处理任务时阻止UI,您可以禁用控件,显示弹出进度条等等,但保持UI线程相对空闲以避免“无响应”问题。

答案 1 :(得分:5)

比使用线程更简单的解决方案是使用QCoreApplication::processEvents()。如果您的代码是这样的:

void slowFunction()
{
    lostOfResults = makeSqlQuery(...); // quite fast
    for (r in lostOfResults)
        doSomethingWithResult(r); // one call is quite fast
}

如果一个SQL查询或一个doSomethingWithResult()不占用太多时间,您可以使用QCoreApplication :: processEvents()处理挂起事件,如下所示:

void slowFunction()
{
    lostOfResults = makeSqlQuery(...);
    for (r in lostOfResults) 
    {
        doSomethingWithResult(r);
        QCoreApplication::processEvents();
    }
}

现在处理GUI事件并且程序不会冻结。但是,如果单独的SQL查询需要花费很多时间(几秒钟),这无济于事。那你应该考虑单独的线程。