Qt异步:QFuture

 

有时候一个功能特别耗时,容易卡主进程,这个时候就需要上异步操作了。

 

# Pro

QT += concurrent
# .h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QDebug>

// 异步,qmake: QT += concurrent
#include <QFutureWatcher>
#include <QFuture>
#include <QtConcurrent>


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

public slots:
    void fn_pushButton_click();
    void fn_future_return(const QString& text);

private:
    Ui::Widget *ui;
    QFutureWatcher<void> m_futureWatcher;
};
#endif // WIDGET_H

 

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    connect(ui->pushButton, &QPushButton::clicked, this, &Widget::fn_pushButton_click);

    // 链接 future 完成信号
    connect(&m_futureWatcher, &QFutureWatcher<void>::finished, this, [this](){
        if(m_futureWatcher.future().isCanceled())
        {
            qDebug() << "clicked canceled";
        }
        else
        {
            qDebug() << "future finish:";
        }
    });

}

Widget::~Widget()
{
    delete ui;

    // 确保后台任务完成
    m_futureWatcher.cancel();
    m_futureWatcher.waitForFinished();
}

void Widget::fn_pushButton_click()
{
    QFuture<void> future = QtConcurrent::run([this](){
        QString text = "123";
        QThread::sleep(3);
        QMetaObject::invokeMethod(this, "fn_future_return", Qt::QueuedConnection, Q_ARG(QString, text));
    });
    m_futureWatcher.setFuture(future);
}

void Widget::fn_future_return(const QString &text)
{
    qDebug() << "fn:" << text;
}

 

posted @ 2025-06-03 16:33  十一的杂文录  阅读(42)  评论(0)    收藏  举报