Qt程序挂起(不响应),直到函数结束,然后再次开始工作

Qt Program Hangs (Not Responding) Until Function ends then starts working again

本文关键字:然后 结束 工作 开始 函数 挂起 程序 不响应 Qt      更新时间:2023-10-16

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

当运行此查询的按钮被点击时,UI窗口只是立即变为"不响应",但是我可以从控制台输出中看到,所有内容实际上仍然在后台运行。一旦函数结束,数据就会按预期呈现,UI也会再次响应,并且功能齐全。

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

哦,我也认为这不是内存泄漏,因为当我点击那个按钮时,任务管理器显示只有几个MB的内存用于这个进程,处理器也绝不是最大的

在应用程序中,有一个线程负责处理UI事件,消息,无论你想叫它们什么。假设您有一个按钮单击事件。只要你不从回调函数返回,没有其他UI事件可以被触发(重画,更新等),UI变得无响应。

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

比使用线程更简单的解决方案是使用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查询本身需要花费很多时间(几秒钟),这就没有帮助了。那么你应该考虑单独的线程