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."
-
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 aQtConcurrent::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 changethis
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
-
@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 bellowMainWindow 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. -
As Chris Kawa already mentioned you should never try to access UI from another thread than the one where the UI is running!