提问者:小点点

QT5.15:如何从QtConcurrent函数访问小部件对象


我希望从QtConcurrent函数更新一个进度条小部件,但遇到以下问题:

a)如果我将此功能声明为:

void myRunFunction(QString str)

然后,我成功地通过以下方法将其编程为并发:

QFuture<void> t1 = QtConcurrent::run(myRunFunction, QString("A"));

但是我不能从函数内部访问GUI的任何Qt小部件(“无法解析标识符'widget'”)。

b)如果我宣布这一职能为:

void mainForm::myRunFunction(QString str)

然后,我成功地访问了它内部的小部件,但不能再将其编程为并发,从而得到编译器错误:

error: invalid use of non-static member function ‘void mainForm::myRunFunction(QString)’

在行:

QFuture<void> t1 = QtConcurrent::run(myRunFunction, QString("A"));

我怎样才能解决问题呢? 多谢你,马可


共1个答案

匿名用户

我建议使用闭包(带有捕获的lambda)。 但是要小心你的对象的寿命。

还要使用异步信号/插槽连接在线程之间通信-Qt::QueuedConnection。 最好不要直接调用小部件,而是调用提供必要数据的特定插槽,这样就可以对它们执行任何您想要的操作。

// mainwindow.h
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow() {};

private:
    void function_slot(int data) {
        // update widget
    }

signals:
    void function_signal(int data);
};

和。cpp文件中的某个位置:

// declare a lambda
auto f = [this] (QString str) 
{
    for (int i = 0; i < 100; ++i) {
        // do some job
        // ...
        // job is done
        // send progress data to mainwidget
            emit function_signal(i);
    }
};

// queued thread-safe connection
connect(this, &MainWindow::function_signal, this, &MainWindow::function_slot, Qt::QueuedConnection);

auto t1 = QtConcurrent::run(f, "string");