Search code examples
c++multithreadingqt

How to call a function with arguments by QtConcurrent


In my application there is a saving process that blocks my UI. Optimising was not enough, so I want to implement threading with QtConcurrent but I can't get it working, though the syntax is looking easy.

That's how it looks right now (principle):

Traymenu::Traymenu(QApplication *a){
    //...

    void save(){
        //Get the savepath, choose if saving is necessary, and trigger saving
        QString path = getSavePath();
        saveNotes(path);
    }

    void saveNotes(QString savePath){
        //save to the given path, takes quite a while, should be parallel
    }    
}

What I have tried:

Traymenu::Traymenu(QApplication *a){
    //...

    void save(){
        //Get the savepath, choose if saving is necessary, and trigger saving
        QString path = getSavePath();
        QFuture<void> result = QtConcurrent(saveNotes, path); //ERROR
    }

    void saveNotes(QString savePath){
        //save to the given path
    }    
}

Besides, in my header, I am including this:

#include <QtConcurrent/QtConcurrentRun>

The error message is

C:\App\appname\traymenu.cpp:584: Error: no matching function for call 
to 'run(<unresolved overloaded function type>, QString&)'
             QFuture<void> future = QtConcurrent::run(save, outputFilename);
                                                                          ^

I have also tried this:

QFuture<void> future = QtConcurrent::run(this, this->save(outputFilename));

There the erros is

C:\App\appname\traymenu.cpp:584: Error: invalid use of void expression
                 QFuture<void> future = QtConcurrent::run(this, this->save(outputFilename));
                                                                                      ^

My header looks like:

class Traymenu : public QSystemTrayIcon
{
    Q_OBJECT
public:
    Traymenu(QApplication *);
    ~Traymenu();

    void save();        
    void saveNotes(QString);     
    //[...]     

What am I doing wrong?


Solution

  • From the official documentation:

    QtConcurrent::run() also accepts pointers to member functions. The first argument must be either a const reference or a pointer to an instance of the class. Passing by const reference is useful when calling const member functions; passing by pointer is useful for calling non-const member functions that modify the instance.

    That means that you would write this to get this working:

    QtConcurrent::run(this, &Traymenu::saveNotes, outputFileName);