8

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

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

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

哦,我也认为它不是内存泄漏,因为当我单击该按钮时,任务管理器显示此进程仅使用了几 MB 内存,并且处理器也绝不会最大化

4

2 回答 2

6

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

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

于 2013-04-22T14:37:42.133 回答
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 查询需要大量时间(几秒钟),这将无济于事。那么你应该考虑单独的线程。

于 2013-04-22T15:34:34.450 回答