Missing SLOT ...then it won't execute
-
When SLOT is missing I get nice run time error message - without setting any specific options.
After implementing the missing SLOT - it won't execute .
How do I troubleshot this ?
Did I implemented QFutureWatcher (connect) in wrong place or did I missed something else ?QObject::connect: No such slot MainWindow_SUB_FT857::SCANFinished() in /mnt/sde5/QT_PROGRAMS_FULL/MDI_BT/MDI_BT/SUB_FT857/mainwindow_sub_ft857.cpp:2177 QObject::connect: (receiver name: 'MainWindow_SUB_FT857') QObject::connect: No such slot MainWindow_SUB_FT857::SCANFinished() in /mnt/sde5/QT_PROGRAMS_FULL/MDI_BT/MDI_BT/SUB_FT857/mainwindow_sub_ft857.cpp:2179 QObject::connect: (receiver name: 'MainWindow_SUB_FT857')
MainWindow_SUB_FT857::MainWindow_SUB_FT857(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow_SUB_FT857)
{
ui->setupUi(this);
QFutureWatcher<int> watcher;
connect(&watcher, SIGNAL(finished()), this , SLOT(SCANFinished()));
connect(&watcher, SIGNAL(started()), this , SLOT(SCANFinished()));}
I have added this const bool connected = connect(&watcher, SIGNAL(finished()), this , SLOT(SCANFinished())); qDebug() << "Connection established?" << connected; and it returns true ...
-
Switch to the (not so) new connect syntax and you will probably get a more descriptive error message at compile time. Also, I don't know if there is more code that you left out in your constructor, but since the QFutureWatcher is created on the stack it will go out of scope and be deleted once you exit the MainWindow_SUB_FT857 constructor (so won't emit any signals).
const bool connected = connect(&watcher, &QFutureWatcher::finished, this , &MainWindow_SUB_FT857::SCANFinished);
-
@mchinand said in Missing SLOT ...then it won't execute:
Switch to the (not so) new connect syntax and you will probably get a more descriptive error message at compile time.
Have already advised this countless times, and been insulted for daring to do so.
-
@AnneRanch said in Missing SLOT ...then it won't execute:
{
ui->setupUi(this);
QFutureWatcher<int> watcher;
connect(&watcher, SIGNAL(finished()), this , SLOT(SCANFinished()));
connect(&watcher, SIGNAL(started()), this , SLOT(SCANFinished()));
}watcher
is a local variable. It goes out of scope/gets destroyed once this function (the constructor) exits. -
Here is my modified code , still no go.
I have a connection between "watcher " and SLOT
QTConcurrent "finishes" but how do I know it "link" between
"watcher" is working ?Is there way I can actually emulate the "watcher" SIGNAL?
QFutureWatcher<int> watcher; connect(&watcher, SIGNAL(finished()), this , SLOT(SCANFinished())); connect(&watcher, SIGNAL(started()), this , SLOT(SCANFinished())); const bool connected = connect(&watcher, SIGNAL(finished()), this , SLOT(SCANFinished())); qDebug() << "Connection established?" << connected << " @line " << QString::number(__LINE__); time->start(); QFuture<int> future = QtConcurrent::run( std::bind( hci_inquiry, dev_id, len, max_rsp, lap, //NULL, &ii, flags) ); watcher.setFuture(future); // how to verify this ?? // future.waitForFinished(); test ionly qDebug() <<"hci_inquiry elapsed time " <<QString::number(time->elapsed()); qDebug() <<"hci_inquiry result " <<QString::number(future.result());
-
@mchinan I am NOT getting any errors - what make you say I "probably get more ...errors ." ??
I have found my "scope " problem - by myself ....Thanks for noting that problem....
appreciate your contributions
-
Is it possible the problem is in QtConncurrent running function whose state I am trying to monitor in NEW TREAD and
QtFutureWatcher runs in the original , main tread, and the SIGNAL and SLOT are also in main thread ?If so "connect" needs to "crossconnect" between threads.
-
@AnneRanch
While you continue to use the old-style connect() calls, so you will not receive compile-time errors regarding the slots. You will, and do, receive run-time errors regarding the problems with signal-slot connections in these cases.If, as has been suggested several times, you use the new-style connect() then you will receive compile- or link-time errors for the vast majority of signal-slot connection issues. Most programmers find that knowing about problems earlier rather than later is a good thing.
The most likely scenarios are that:
- there is a declaration but no implementation of
MainWindow_SUB_FT857::SCANFinished()
, or - there is an implementation but MOC has not run over the header that declares
void MainWindow_SUB_FT857::SCANFinished()
so that the slot does not appear in the lookup tables used to support runtime connection.
Is there way I can actually emulate the "watcher" SIGNAL?
Signals are just another function (generated by MOC). Try calling
watcher.finished()
.Your most recent posted code still has a stack-based QFutureWatcher. This will cease to exist at the end of the function (constructor in your first post) and thus will almost never emit signals (it might emit a signal immediately if the watched item is already finished at the time of the setFuture() call). To work, the QFutureWatcher object must exist at the indeterminate time in the future when the other thread finishes its work.
- there is a declaration but no implementation of
-
@AnneRanch said in Missing SLOT ...then it won't execute:
Is it possible the problem is in QtConncurrent running function whose state I am trying to monitor in NEW TREAD and
QtFutureWatcher runs in the original , main tread, and the SIGNAL and SLOT are also in main thread ?
If so "connect" needs to "crossconnect" between threads.QFuture
/QFutureWatcher
are design to handle cross-thread, and they works fine. I have often use them.I don't know how you fix the posted code, but here what I would suggest you:
// needs a dynamic allocated watcher auto watcher = new QFutureWatcher<int>(); auto time = new QElapsedTimer(); // use new connect style connect(watcher, &QFutureWatcher<int>::finished, this, [this, watcher, time](){ qDebug() <<"hci_inquiry elapsed time" << time->elapsed(); qDebug() <<"hci_inquiry result" << watcher->result(); SCANFinished(); // do not forget to release memory watcher->delateLater(); delete time }); time->start(); watcher->setFuture(QtConcurrent::run( std::bind( hci_inquiry, dev_id, len, max_rsp, lap, //NULL, &ii, flags) ));
-
@KroMignon said in Missing SLOT ...then it won't execute:
@AnneRanch said in Missing SLOT ...then it won't execute:
Is it possible the problem is in QtConncurrent running function whose state I am trying to monitor in NEW TREAD and
QtFutureWatcher runs in the original , main tread, and the SIGNAL and SLOT are also in main thread ?
If so "connect" needs to "crossconnect" between threads.QFuture
/QFutureWatcher
are design to handle cross-thread, and they works fine. I have often use them.I don't know how you fix the posted code, but here what I would suggest you:
// needs a dynamic allocated watcher auto watcher = new QFutureWatcher<int>(); auto time = new QElapsedTimer(); // use new connect style connect(watcher, &QFutureWatcher<int>::finished, this, [this, watcher, time](){ qDebug() <<"hci_inquiry elapsed time" << time->elapsed(); qDebug() <<"hci_inquiry result" << watcher->result(); SCANFinished(); // do not forget to release memory watcher->delateLater(); delete time }); time->start(); watcher->setFuture(QtConcurrent::run( std::bind( hci_inquiry, dev_id, len, max_rsp, lap, //NULL, &ii, flags) ));
Thanks for very constructive post. It does work , but I like to have some clarifications .
- If I use "dynamic allocation " then the old connect style complains - unfortunately it is not easy to display the QT error. But this not that important to resolve .
- I believe the MAIN error was / is in
watcher_new->setFuture(QtConcurrent::run(....
In not so technical terms - the QtFutureWatcher " runs" (setFuture...) the QtConcurrent - not QtFuture as coded originally .
The role of QtFuture is unclear. As coded only QtFutureWatcher "interacts" with QtConncurrent.watcher_new->setFuture(QtConcurrent::run( std::bind( hci_inquiry, dev_id, len, max_rsp, lap, //NULL, &ii, flags) )); #endif //return; //QFutureWatcher<int> watcher; auto watcher = new QFutureWatcher<int>(); connect(&watcher, SIGNAL(finished()), this, SLOT(SCANFinished())); connect(&watcher, SIGNAL(finished()), SLOT(SCANFinished()));
-
Whoops...
It saddens me to report that the code fails in few aspects
Not sure where to start to fix it.- It blocks the main thread outputs - that is the PRIMARY reason for using QtConcurrent - however it reports zero time spent "waiting for completion" which is correct .
- It "scan" over a minute - approximate scan time for one device is about 2 seconds
- It reports 10 devices found - I have only 5 real bluetooth devices it should report - consequently all the "info" data is bogus.
I do not expect assistance in finding out why QtConcurrent no longer functions as before. (... time for MS approach - reboot ...)
However, primary reason for the post was to solve the lack of SIGNAL/ SLOT response and that has been solved.
SOLVED
Here is the output on QT console :
??? hci_inquiry elapsed time "0" this is expected new_watcher hci_inquiry elapsed time 51681 should be about 10 seconds new_watcher hci_inquiry result 1 should be 0 on start TEST access counter "0" OK started START /mnt/sde5/QT_PROGRAMS_FULL/MDI_BT/MDI_BT/SUB_FT857/mainwindow_sub_ft857.cpp SCANFinished @ line "98" START sleep ...LocalConn END sleep ...LocalConn END /mnt/sde5/QT_PROGRAMS_FULL/MDI_BT/MDI_BT/SUB_FT857/mainwindow_sub_ft857.cpp SCANFinished @ line "106" new_watcher hci_inquiry elapsed time 52681 new_watcher hci_inquiry result 1 TEST access counter "1" OK finished START /mnt/sde5/QT_PROGRAMS_FULL/MDI_BT/MDI_BT/SUB_FT857/mainwindow_sub_ft857.cpp SCANFinished @ line "98" START sleep ...LocalConn END sleep ...LocalConn END /mnt/sde5/QT_PROGRAMS_FULL/MDI_BT/MDI_BT/SUB_FT857/mainwindow_sub_ft857.cpp SCANFinished @ line "106"
-
@AnneRanch
Time to get serious about this "new connect format "- SIGNAL is "just a function : " , hence
Am I testing this wrong ?
This is what I get after
watcher_new->started();Status "10" NEW Connection started established? true @line "2234" started new_watcher hci_inquiry elapsed time 0 14:31:33: /media/q5/MDI/QT_PROGRAMS/SOURCE/mdi/mdi crashed.
PS
I really do not need the debug code in "new style connect" ,
but I like to see RESPONSE to "started" - what I am getting is some kind of QyConcurrent "finished" and it blocks the main thread.
Definitely no getting "started" SIGNAL at zero time.// needs a dynamic allocated watcher auto watcher_new = new QFutureWatcher<int>(); auto time_new = new QElapsedTimer(); time_new->start(); time_class.start(); //watcher_new->started(); // use new connect style // verify started const bool connected = connect(watcher_new, &QFutureWatcher<int> ::started, this, [this, watcher_new, time_new](){ qDebug() <<"started new_watcher hci_inquiry elapsed time" << time_new->elapsed(); qDebug() <<"started new_watcher hci_inquiry result" << watcher_new->result(); //SCANFinished(); SCANStarted(); // do not forget to release memory //watcher->delateLater(); //delete time }); qDebug() << "NEW Connection started established?" << connected << " @line " << QString::number(__LINE__); watcher_new->started(); attempt to test SIGNAL get crash shlu dget SCANStarted "SLOT " function... return;
-
I have removed both qDebug calls from "connect" and did this
emit watcher_new->started(); return;
No more crash and it really runs the SLOT function as expected .
however
Current "new connect" still does not work, same as the original one.
Best guess
if the "new connect" debug calls run in current thread - it blocks it - no good.
-
Here is the latest
All data as expected , with the exception of last = this code crashes AFTER QtConcurrent::run is actually "finished". about 10- seconds after both "started " and "running" are verified = there is no code top process "finished " but OK if "waitforFinihsed " is added .
That however defeats the "no blocking of main thread " requirement. .
QFuture<int> future_SCAN = QtConcurrent::run( std::bind( hci_inquiry, dev_id, len, max_rsp, lap, //NULL, &ii, flags) );
original direct # of devices found "4" original direct elapsed time "10250" QtConcurrent # of devices found "4" QTConcurrent (main thread ) elapsed time "0" QtConcurrent futureSCAN # of devices found "4" QTConcurrent futureSCAN (main thread ) elapsed time "0" verify future_SCAN started ? true verify future_SCAN running ? true verify future_SCAN finished ? false expected 18:28:27: /media/q5/MDI/QT_PROGRAMS/SOURCE/mdi/mdi crashed.
OK after future_SCAN finished waitForFinished() is added
original direct # of devices found "0" original direct elapsed time "19" QtConcurrent # of devices found "0" QTConcurrent (main thread ) elapsed time "0" QtConcurrent futureSCAN # of devices found "0" QTConcurrent futureSCAN (main thread ) elapsed time "0" verify future_SCAN started ? true verify future_SCAN running ? true verify future_SCAN finished ? false OK future_SCAN finished waitForFinished() verify future_SCAN finished ? true OK
... time to start working on catching SIGNALS ...