'How to run a member function in QtConcurrent in QT6

i try to run a member function with QtConcurrent. I am just learning c++ and qt and i used the way i found in their official documentation: https://wiki.qt.io/QtConcurrent-run-member-function

mainWindow.cpp

#include "mainwindow.h"
#include "./ui_mainwindow.h"

#include "testclass.h"

#include <QtConcurrent>
#include <QFuture>
#include <QDebug>
#include <QThread>

void testFunction()
{
    qDebug() << "runs";
}


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{

    TestClass testClass;

    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    QtConcurrent::run(&this->testClass, &TestClass::start);
}

testClass.h

#ifndef TESTCLASS_H
#define TESTCLASS_H

#include <QObject>

class TestClass : public QObject
{
    Q_OBJECT
public:
    explicit TestClass(QObject *parent = nullptr);

public:
    void start();

};

#endif // TESTCLASS_H

testClass.cpp

#include "testclass.h"

#include <QThread>
#include <QDebug>

TestClass::TestClass(QObject *parent) : QObject(parent)
{

}

void TestClass::start()
{
    qDebug() << "run" << QThread::currentThread();
}

I do not know where the problem is, but when i try to build i get following errors:

error: 'operator()' is not a member of 'std::decay<TestClass*>::type' {aka 'TestClass*'}
 struct ArgResolver : ArgResolver<decltype(&std::decay_t<F>::operator())>

error: no type named 'IsPromise' in 'struct QtPrivate::ArgResolver<TestClass*>'

error: no type named 'PromiseType' in 'struct QtPrivate::ArgResolver<TestClass*>'

error: no type named 'PromiseType' in 'struct QtPrivate::ArgResolver<TestClass*>'
         return (new StoredFunctionCallWithPromise<Function, PromiseType, Args...>(std::move(args)))

mainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "testclass.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    TestClass testClass;

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

Thanks a lot



Solution 1:[1]

Yes, I also encountered the same problem. Some changes have taken place in QT6 qtconcurrent. The parameter order of class member function calls should be like this:

QFuture<void> future = QtConcurrent::run(&QImage::invertPixels, &image, QImage::InvertRgba);

Solution 2:[2]

In Qt6 , Changes to Qt Concurrent says

QtConcurrent::run() has been improved to work with a variable number of arguments, so the signatures are changed to:

// run template

QFuture run(Function &&f, Args &&...args)

As a side effect, if f is a pointer to a member function, the first argument of args should be the object for which that member is defined (or a reference, or a pointer to it). So instead of writing:

QImage image = ...;

QFuture future = QtConcurrent::run(&image, &QImage::invertPixels, QImage::InvertRgba); You have to write:

QFuture future = QtConcurrent::run(&QImage::invertPixels, &image, QImage::InvertRgba);

So as commented , the right call syntax is to pass the object name after the function pointer:

QtConcurrent::run(&TestClass::start, &this->testClass);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 sknt
Solution 2 Mohammad Kanan