Problem In Calling local function with QtConcurrent inside MainWindow



  • Hello My Friends
    I have GUI QT application. i can run QtConcurrent::Run for calling function inside other classes and it works perfectly.
    for example the bellow line works:

    MainWindow.cpp

    WipeBrowsers wb;
    QtConcurrent::run(&this->wb,&WipeBrowsers::wipe,QStringList(MyList));
    

    now i need to insert some QStringList datas to QTreeWidget, and it may take long time and hang my app. so i need a thread. for first try i decide to create a new class and sending MyList and Ui>TreeWidget as parameter. after 1 days and getting many errors, i decide to create myFunction inside MainWindow and just sending QStringList(MyList) as parameter so i have directly access the TreeWidget but every things i do have too many errors.
    In This Document showing a simple example but why my code has to many errors.
    this is my showTree function that i need to call.

    void MainWindow::showTree(QStringList datas)
    {
        for(int i=0;i< datas.size();i++){
              qDebug() << datas[i];  
            }
    }
    

    and i call it with multiple tries like

    QtConcurrent::run(&MainWindow::showTree,QStringList(filename));
    
    QtConcurrent::run(showTree,QStringList(filename));
    
    QtConcurrent::run(&MainWindow::showTree,filename);
    
    QtConcurrent::run(this,&MainWindow::showTree,QStringList(filename));
    

    and .... .

    for example with the bellow code:

    QtConcurrent::run(&MainWindow::showTree,QStringList(filename));
    

    i got many errors like bellow:

    C:\Users\vahid\Documents\qt projects\Emha\mainwindow.cpp:239: error: C2893: Failed to specialize function template 'QtPrivate::QEnableIf<!QtPrivate::HasResultType<T>::Value,QFuture<unknown-type>>::Type QtConcurrent::run(Functor,const Arg1 &)'
    With the following template arguments:
    'Functor=void (__cdecl MainWindow::* )(QStringList)'
    'Arg1=QStringList'
    
    C:\Users\vahid\Documents\qt projects\Emha\mainwindow.cpp:239: error: C2780: 'QtPrivate::QEnableIf<!QtPrivate::HasResultType<T>::Value,QFuture<unknown-type>>::Type QtConcurrent::run(Functor)' : expects 1 arguments - 2 provided
    
    C:\Users\vahid\Documents\qt projects\Emha\mainwindow.cpp:239: error: C2780: 'QFuture<T> QtConcurrent::run(T (__cdecl *)(Param1,Param2,Param3,Param4),const Arg1 &,const Arg2 &,const Arg3 &,const Arg4 &)' : expects 5 arguments - 2 provided
    

    please help. what i must to do.
    thank you very much



  • Hi

    Maybe some help can be found here:
    http://doc.qt.io/qt-5/qtconcurrentrun.html
    (see section Additional API Features - Using Member Functions)

    "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."


  • Moderators

    First of all remember that you can't access any widgets in non-ui thread, so you shouldn't access QTreeWidget in showTree(). Btw. this name becomes very misleading as you can't show anything in a non-ui thread.

    Next, since showTree is a method of MainWindow it needs an instance it can be run on. Thus you need to use a a QtConcurrent::run variant that takes an object pointer and pointer to member function. The last one should work if you run it from a method of MainWindow class, otherwise you need to change this to a valid pointer to your MainWindow instance.



  • Thank you @ttuna
    Maybe you right but my problem not resolved. I'm not pro in QT but based on what you said i try this simple example. but failed.do you know what is my problem?

    const QString hi = "hello";
    QtConcurrent::run(&MainWindow::showTree,QString(hi));
    void MainWindow::showTree(QString datas)
    {
        qDebug() << "just show something please!!!";
    }
    

    it has 8 errors.

    C:\Users\vahid\Documents\qt projects\Emha\mainwindow.cpp:240: error: C2893: Failed to specialize function template 'QtPrivate::QEnableIf<!QtPrivate::HasResultType<T>::Value,QFuture<unknown-type>>::Type QtConcurrent::run(Functor,const Arg1 &)'
    With the following template arguments:
    'Functor=void (__cdecl MainWindow::* )(QString)'
    'Arg1=QString'
    
    C:\Users\vahid\Documents\qt projects\Emha\mainwindow.cpp:240: error: C2780: 'QtPrivate::QEnableIf<!QtPrivate::HasResultType<T>::Value,QFuture<unknown-type>>::Type QtConcurrent::run(Functor)' : expects 1 arguments - 2 provided
    
    C:\Users\vahid\Documents\qt projects\Emha\mainwindow.cpp:240: error: C2780: 'QFuture<T> QtConcurrent::run(T (__cdecl *)(Param1,Param2,Param3,Param4,Param5),const Arg1 &,const Arg2 &,const Arg3 &,const Arg4 &,const Arg5 &)' : expects 6 arguments - 2 provided
    
    C:\Users\vahid\Documents\qt projects\Emha\mainwindow.cpp:240: error: C2780: 'QFuture<T> QtConcurrent::run(T (__cdecl *)(Param1,Param2,Param3,Param4),const Arg1 &,const Arg2 &,const Arg3 &,const Arg4 &)' : expects 5 arguments - 2 provided
    
    C:\Users\vahid\Documents\qt projects\Emha\mainwindow.cpp:240: error: C2780: 'QFuture<T> QtConcurrent::run(T (__cdecl *)(Param1,Param2,Param3),const Arg1 &,const Arg2 &,const Arg3 &)' : expects 4 arguments - 2 provided
    
    C:\Users\vahid\Documents\qt projects\Emha\mainwindow.cpp:240: error: C2780: 'QFuture<T> QtConcurrent::run(T (__cdecl *)(Param1,Param2),const Arg1 &,const Arg2 &)' : expects 3 arguments - 2 provided
    
    C:\Users\vahid\Documents\qt projects\Emha\mainwindow.cpp:240: error: C2784: 'QFuture<T> QtConcurrent::run(T (__cdecl *)(Param1),const Arg1 &)' : could not deduce template argument for 'T (__cdecl *)(Param1)' from 'void (__cdecl MainWindow::* )(QString)'
    
    C:\Users\vahid\Documents\qt projects\Emha\mainwindow.cpp:240: error: C2780: 'QFuture<T> QtConcurrent::run(T (__cdecl *)(void))' : expects 1 arguments - 2 provided
    


  • @mjzarrin
    As the doc points out you have to pass a const reference or a pointer to run() - e.g.:

    QtConcurrent::run(&main_window, &MainWindow::showTree, QLatin1String("hi"));
    // replace main_window with your MainWindow object ...
    


  • @ttuna
    Thank you.
    your right. but still have a problem. in the first argument i means "&main_window" , it is an object of MainWindow. if i declare it above QtConcurrent::run like bellow

    MainWindow main_window;
    QtConcurrent::run(&main_window, &MainWindow::showTree,QStringList(filename));
    

    it works and qDebug in showTree() print filenames but the program can't access UI. I Think after calling QtConcurrent::run the new declared main_window could not access UI. for example treeShow() like bellow

    void MainWindow::showTree(QStringList datas)
    {
        QMessageBox::information(this,"hello","you");
    }
    

    get Debug Error as pop up in run time that says:

    Module: 5.5.0
    File: global\qglobal.cpp
    Line: 2978
    ASSERT failure in QWidget: "Widgets must be created in the GUI thread.", file kernel\qwidget.cpp, line1126
    

    my goal was updating treeWidget without hanging my application. i don't know it is possible or not, but your solution is correct if i dont need UI.
    thank you again and again.


  • Moderators

    As Chris Kawa already mentioned you should never try to access UI from another thread than the one where the UI is running!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.