如何防止在 Qt 中完成后台任务和 UI 之间的生命周期问题

How to prevent lifetime issues between completion of background task and UI in Qt

当使用QtConcurrent::run到运行代码时,后台代码来自UI QFuture::then(QObject *context, Function &&function) 可用于更新 UI,因为您可以将 window 对象作为上下文传递,以使 function 在 GUI 线程上执行。这很方便,但是有一个问题。当 window 关闭并在后台任务完成之前被释放时,程序将在任务完成时崩溃,因为传递给 thencontext 不再有效。

有没有简单的方法来防止这个问题?我知道可以使用 QFutureWatcher 但该对象需要添加到 window class 并且 window 可以执行的每个异步任务都需要一个对象麻烦。

一个简单的选择是使用 QPointer 到 track/monitor 感兴趣的 QWidgetQPointer 的副本可以被 QtConcurrent::runQFuture::then 使用的任何 lambda 或仿函数捕获。

/*
 * Set up the QWidget that we need to monitor.
 */
auto w = std::make_unique<QLabel>("Working...");
w->show();

/*
 * Create a QPointer that that we can use to check the validity of 'w'.
 */
auto qp = QPointer<QWidget>(w.get());

/*
 * We can now bind qp into any lambdas.
 */
auto f = QtConcurrent::run(
    []
    {

        /* Time consuming stuff goes here. */
    })
    .then(
        qApp,
        [qp]
        {
            if (qp) {

                /*
                 * qp reports that 'w' is still valid so do whatever we
                 * need to do with it.
                 */
                qp.data()->setText("Done");
            } else {

                /*
                 * 'w' is no longer valid.
                 */
            }
        });

[注意:以上内容未经测试,因为我现在正在处理的盒子上没有 Qt6。]