Please help with lambda sytax
-
Please note - I am posting this to illustrate the problem, please please please - NO comments on my programming style!
My primary goal is to duplicate XML "connect" using code.
The attached code and its variations generally compiles - that is one goal done.HOWEVER - it crashes during run time and I SUSPECT the problem is
after
clicking button 11 my code builds new instance of scanner dialog and it has build-in timers . The "list" is , in theory, filed AFTER each item individual timer expire.
BUT
my test connect is executed immediately after the first timer expires and the "item" is changed .I am asking - is it possible I have a timing problem?
Here is my current - under construction connect to copy the "list" lines.
All it does - just compiles and cannot be tested , in existing code , due to this issue.#ifdef BYPASS // interacts with pushing buitto 11 // keeps crashing connect( this->ui->list, // SIGNAL(ui->list->currentTextChanged()), SIGNAL(ui->list->itemDoubleClicked(*pItem)), // SIGNAL(DDD->ui->list->itemChanged(TEST_LABEL)), // SIGNAL(itemClicked(QListWidgetItem *)), // SIGNAL(itemChanged(TEST_LABEL)), this->ui->plainTextEdit, // SLOT(DDD->ui->plainTextEdit->appendPlainText(TEST_LABEL)) // SLOT(appendPlainText(TEST_LABEL)) SLOT(ui->plainTextEdit->appendPlainText(*pItem))); // ); #endif
This is how it tracks when working - without the code above
QDEBUG TRACE QDEBUG TRACE TASK END imoplement Device DiscoiveryDialog QDEBUG TRACE TASK find nearby BT devices file /media/f/QT/QT_PROJECT/TEST_PROJECT_14/mainwindow_cat_tab.cpp function on_pushButton_11_clicked @line 236 TEMPORARY EXIT /home/f/build-TEST_PROJECT-Desktop-Debug/TEST_PROJECT exited with code 0
And this is failing track
QDEBUG TRACE QDEBUG TRACE TASK START imoplement Device DiscoveryDialog QDEBUG TRACE TASK find nearby BT devices file /media/f/QT/QT_PROJECT/TEST_PROJECT_14/mainwindow_cat_tab.cpp function on_pushButton_11_clicked @line 206 TEMPORARY EXIT TRACE SCAN FLOW START TOK TRACE SCAN FLOW CONSTRUCTOR DeviceDiscoveryDialog::DeviceDiscoveryDialog(QWidget *parent) TEMPORARY exit @line 133 The program has unexpectedly finished. /home/f/build-TEST_PROJECT-Desktop-Debug/TEST_PROJECT crashed
Again - all I am asking - is it possible I have a timing problem?
-
Please note - I am posting this to illustrate the problem, please please please - NO comments on my programming style!
My primary goal is to duplicate XML "connect" using code.
The attached code and its variations generally compiles - that is one goal done.HOWEVER - it crashes during run time and I SUSPECT the problem is
after
clicking button 11 my code builds new instance of scanner dialog and it has build-in timers . The "list" is , in theory, filed AFTER each item individual timer expire.
BUT
my test connect is executed immediately after the first timer expires and the "item" is changed .I am asking - is it possible I have a timing problem?
Here is my current - under construction connect to copy the "list" lines.
All it does - just compiles and cannot be tested , in existing code , due to this issue.#ifdef BYPASS // interacts with pushing buitto 11 // keeps crashing connect( this->ui->list, // SIGNAL(ui->list->currentTextChanged()), SIGNAL(ui->list->itemDoubleClicked(*pItem)), // SIGNAL(DDD->ui->list->itemChanged(TEST_LABEL)), // SIGNAL(itemClicked(QListWidgetItem *)), // SIGNAL(itemChanged(TEST_LABEL)), this->ui->plainTextEdit, // SLOT(DDD->ui->plainTextEdit->appendPlainText(TEST_LABEL)) // SLOT(appendPlainText(TEST_LABEL)) SLOT(ui->plainTextEdit->appendPlainText(*pItem))); // ); #endif
This is how it tracks when working - without the code above
QDEBUG TRACE QDEBUG TRACE TASK END imoplement Device DiscoiveryDialog QDEBUG TRACE TASK find nearby BT devices file /media/f/QT/QT_PROJECT/TEST_PROJECT_14/mainwindow_cat_tab.cpp function on_pushButton_11_clicked @line 236 TEMPORARY EXIT /home/f/build-TEST_PROJECT-Desktop-Debug/TEST_PROJECT exited with code 0
And this is failing track
QDEBUG TRACE QDEBUG TRACE TASK START imoplement Device DiscoveryDialog QDEBUG TRACE TASK find nearby BT devices file /media/f/QT/QT_PROJECT/TEST_PROJECT_14/mainwindow_cat_tab.cpp function on_pushButton_11_clicked @line 206 TEMPORARY EXIT TRACE SCAN FLOW START TOK TRACE SCAN FLOW CONSTRUCTOR DeviceDiscoveryDialog::DeviceDiscoveryDialog(QWidget *parent) TEMPORARY exit @line 133 The program has unexpectedly finished. /home/f/build-TEST_PROJECT-Desktop-Debug/TEST_PROJECT crashed
Again - all I am asking - is it possible I have a timing problem?
@AnneRanch said in Please help with lambda sytax:
connect(
this->ui->list,
// SIGNAL(ui->list->currentTextChanged()),
SIGNAL(ui->list->itemDoubleClicked(*pItem)),
// SIGNAL(DDD->ui->list->itemChanged(TEST_LABEL)),
// SIGNAL(itemClicked(QListWidgetItem *)),
// SIGNAL(itemChanged(TEST_LABEL)),
this->ui->plainTextEdit,
// SLOT(DDD->ui->plainTextEdit->appendPlainText(TEST_LABEL))
// SLOT(appendPlainText(TEST_LABEL))
SLOT(ui->plainTextEdit->appendPlainText(*pItem)));
// );This is invalid connect() call. Please check https://doc.qt.io/qt-5/signalsandslots.html And it is better to use Qt5 connect() syntax to detect such issues during compile time instead of run time.
It should beconnect( this->ui->list, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this->ui->plainTextEdit, SLOT(appendPlainText(QListWidgetItem*)));
But this will also not work as QPlainTextEdit does not have a slot appendPlainText which takes a QListWidgetItem* as parameter (use new Qt5 connect syntax and a lambda)...
-
Please note - I am posting this to illustrate the problem, please please please - NO comments on my programming style!
My primary goal is to duplicate XML "connect" using code.
The attached code and its variations generally compiles - that is one goal done.HOWEVER - it crashes during run time and I SUSPECT the problem is
after
clicking button 11 my code builds new instance of scanner dialog and it has build-in timers . The "list" is , in theory, filed AFTER each item individual timer expire.
BUT
my test connect is executed immediately after the first timer expires and the "item" is changed .I am asking - is it possible I have a timing problem?
Here is my current - under construction connect to copy the "list" lines.
All it does - just compiles and cannot be tested , in existing code , due to this issue.#ifdef BYPASS // interacts with pushing buitto 11 // keeps crashing connect( this->ui->list, // SIGNAL(ui->list->currentTextChanged()), SIGNAL(ui->list->itemDoubleClicked(*pItem)), // SIGNAL(DDD->ui->list->itemChanged(TEST_LABEL)), // SIGNAL(itemClicked(QListWidgetItem *)), // SIGNAL(itemChanged(TEST_LABEL)), this->ui->plainTextEdit, // SLOT(DDD->ui->plainTextEdit->appendPlainText(TEST_LABEL)) // SLOT(appendPlainText(TEST_LABEL)) SLOT(ui->plainTextEdit->appendPlainText(*pItem))); // ); #endif
This is how it tracks when working - without the code above
QDEBUG TRACE QDEBUG TRACE TASK END imoplement Device DiscoiveryDialog QDEBUG TRACE TASK find nearby BT devices file /media/f/QT/QT_PROJECT/TEST_PROJECT_14/mainwindow_cat_tab.cpp function on_pushButton_11_clicked @line 236 TEMPORARY EXIT /home/f/build-TEST_PROJECT-Desktop-Debug/TEST_PROJECT exited with code 0
And this is failing track
QDEBUG TRACE QDEBUG TRACE TASK START imoplement Device DiscoveryDialog QDEBUG TRACE TASK find nearby BT devices file /media/f/QT/QT_PROJECT/TEST_PROJECT_14/mainwindow_cat_tab.cpp function on_pushButton_11_clicked @line 206 TEMPORARY EXIT TRACE SCAN FLOW START TOK TRACE SCAN FLOW CONSTRUCTOR DeviceDiscoveryDialog::DeviceDiscoveryDialog(QWidget *parent) TEMPORARY exit @line 133 The program has unexpectedly finished. /home/f/build-TEST_PROJECT-Desktop-Debug/TEST_PROJECT crashed
Again - all I am asking - is it possible I have a timing problem?
@AnneRanch
As @jsulm has said. As long as you use the old-styleSIGNAL
&SLOT()
macros, you are liable to have code which compiles OK but does not behave correctly at runtime. With the new style syntax, if the signal/slot code is wrong, you get told at compile-time. It might seem harder to get it right, but at least you know that when it does compile it will do what you expect when you run it; if it does not compile, you have to sort it out to be correct at that stage. -
@AnneRanch said in Please help with lambda sytax:
connect(
this->ui->list,
// SIGNAL(ui->list->currentTextChanged()),
SIGNAL(ui->list->itemDoubleClicked(*pItem)),
// SIGNAL(DDD->ui->list->itemChanged(TEST_LABEL)),
// SIGNAL(itemClicked(QListWidgetItem *)),
// SIGNAL(itemChanged(TEST_LABEL)),
this->ui->plainTextEdit,
// SLOT(DDD->ui->plainTextEdit->appendPlainText(TEST_LABEL))
// SLOT(appendPlainText(TEST_LABEL))
SLOT(ui->plainTextEdit->appendPlainText(*pItem)));
// );This is invalid connect() call. Please check https://doc.qt.io/qt-5/signalsandslots.html And it is better to use Qt5 connect() syntax to detect such issues during compile time instead of run time.
It should beconnect( this->ui->list, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this->ui->plainTextEdit, SLOT(appendPlainText(QListWidgetItem*)));
But this will also not work as QPlainTextEdit does not have a slot appendPlainText which takes a QListWidgetItem* as parameter (use new Qt5 connect syntax and a lambda)...
@jsulm said in Please help with lambda sytax:
But this will also not work as QPlainTextEdit does not have a slot appendPlainText which takes a QListWidgetItem* as parameter (use new Qt5 connect syntax and a lambda)...
I do appreciate the post.
It may seems strange, but at this point I am NOT after "it" working.
I just need to figure out WHY adding this "connect" , in any form or format , crashes the program.
After I figure out the crasher I will work on form / format/ style.
Of course I could verify the "connect" using separate test program. -
Please note - I am posting this to illustrate the problem, please please please - NO comments on my programming style!
My primary goal is to duplicate XML "connect" using code.
The attached code and its variations generally compiles - that is one goal done.HOWEVER - it crashes during run time and I SUSPECT the problem is
after
clicking button 11 my code builds new instance of scanner dialog and it has build-in timers . The "list" is , in theory, filed AFTER each item individual timer expire.
BUT
my test connect is executed immediately after the first timer expires and the "item" is changed .I am asking - is it possible I have a timing problem?
Here is my current - under construction connect to copy the "list" lines.
All it does - just compiles and cannot be tested , in existing code , due to this issue.#ifdef BYPASS // interacts with pushing buitto 11 // keeps crashing connect( this->ui->list, // SIGNAL(ui->list->currentTextChanged()), SIGNAL(ui->list->itemDoubleClicked(*pItem)), // SIGNAL(DDD->ui->list->itemChanged(TEST_LABEL)), // SIGNAL(itemClicked(QListWidgetItem *)), // SIGNAL(itemChanged(TEST_LABEL)), this->ui->plainTextEdit, // SLOT(DDD->ui->plainTextEdit->appendPlainText(TEST_LABEL)) // SLOT(appendPlainText(TEST_LABEL)) SLOT(ui->plainTextEdit->appendPlainText(*pItem))); // ); #endif
This is how it tracks when working - without the code above
QDEBUG TRACE QDEBUG TRACE TASK END imoplement Device DiscoiveryDialog QDEBUG TRACE TASK find nearby BT devices file /media/f/QT/QT_PROJECT/TEST_PROJECT_14/mainwindow_cat_tab.cpp function on_pushButton_11_clicked @line 236 TEMPORARY EXIT /home/f/build-TEST_PROJECT-Desktop-Debug/TEST_PROJECT exited with code 0
And this is failing track
QDEBUG TRACE QDEBUG TRACE TASK START imoplement Device DiscoveryDialog QDEBUG TRACE TASK find nearby BT devices file /media/f/QT/QT_PROJECT/TEST_PROJECT_14/mainwindow_cat_tab.cpp function on_pushButton_11_clicked @line 206 TEMPORARY EXIT TRACE SCAN FLOW START TOK TRACE SCAN FLOW CONSTRUCTOR DeviceDiscoveryDialog::DeviceDiscoveryDialog(QWidget *parent) TEMPORARY exit @line 133 The program has unexpectedly finished. /home/f/build-TEST_PROJECT-Desktop-Debug/TEST_PROJECT crashed
Again - all I am asking - is it possible I have a timing problem?
@AnneRanch said in Please help with lambda sytax:
function on_pushButton_11_clicked
@line 206Can you show your on_pushButton_11_clicked? The crash is there at line 206.
-
@jsulm said in Please help with lambda sytax:
But this will also not work as QPlainTextEdit does not have a slot appendPlainText which takes a QListWidgetItem* as parameter (use new Qt5 connect syntax and a lambda)...
I do appreciate the post.
It may seems strange, but at this point I am NOT after "it" working.
I just need to figure out WHY adding this "connect" , in any form or format , crashes the program.
After I figure out the crasher I will work on form / format/ style.
Of course I could verify the "connect" using separate test program.@AnneRanch
Back to lambdas:
You said, you are struggling to understand lambda connections correctly.
It's not as complicated as it might look.-
You have your sender (first argument)
connect(ui->list,.....)
-
You have your sender's class + signal
connect(ui->list, &QListWidget::itemDoubleClicked,.....)
-
Then you can define a scope for your lambda
connect(ui->list, &QListWidget::itemDoubleClicked, this,......)
-
the last part consists of the capture, the function or slot arguments and the actual code itself, using the passed and captured values
-
Capture
- "
[ ]
": None of the variables from current class / scope are captured and can be used inside lambda "code" - "
[=]
": Captures everything (by value!) - "
[this]
": (current instance) or any combination of variables (e.g.[x, a]
), to pick variables you need explicitely. - "
[&]
" or "[ &someVar ]
": Captures by reference. Changes made inside lambda will affect and change the captured variable outside the lambda as well ( Thx, @JonB )
- "
-
Signal / Slot arguments after capture inside
( .... )
, e.g. if signal sends aQListWidgetItem
, you need a(QListWidgetItem *item)
here. -
lambda code inside
{ .... }
- do whatever you like and what you would put in your slot here.
-
One big advantage using lambda connections is, that you can connect signals to slots (or "code"), that would be incompatible using a "direct" connection because of any reason (e.g. parameter mismatch).
Simple example:
// signal void signal(QString s); // slot void onSignalFired(int i);
A direct connection of these two won't work neither using the
SIGNAL(...) / SLOT( ... )
syntax
(-> crash / error at runtime),
nor using the function based connection&Class::signal... &Class::onSignalFired
( -> wont compile).With lambda, you can make it work:
connect(this, &Class::signal, [] (QString s) { onSignalFired( s.toInt() ); } );
Instead of calling the slot, you could also skip the slot and do whatever you want to do with this string inside the lambda directly, e.g. send your number to a
QLineEdit
("A" would lead to a 65, simple ASCII).@AnneRanch said in Please help with lambda sytax:
Here is my current - under construction connect to copy the "list" lines.
All it does - just compiles and cannot be tested , in existing code , due to this issue.... and this is exactly where you can make use of lambdas ( as @jsulm already said ).
Pass yourQListWidgetItem
from signal to your lambda, get the text from your item usingtext()
(Qt Doc), then pass the text toQPlainTextEdit
'sappendPlainText(QString)
. -
-
@AnneRanch
Back to lambdas:
You said, you are struggling to understand lambda connections correctly.
It's not as complicated as it might look.-
You have your sender (first argument)
connect(ui->list,.....)
-
You have your sender's class + signal
connect(ui->list, &QListWidget::itemDoubleClicked,.....)
-
Then you can define a scope for your lambda
connect(ui->list, &QListWidget::itemDoubleClicked, this,......)
-
the last part consists of the capture, the function or slot arguments and the actual code itself, using the passed and captured values
-
Capture
- "
[ ]
": None of the variables from current class / scope are captured and can be used inside lambda "code" - "
[=]
": Captures everything (by value!) - "
[this]
": (current instance) or any combination of variables (e.g.[x, a]
), to pick variables you need explicitely. - "
[&]
" or "[ &someVar ]
": Captures by reference. Changes made inside lambda will affect and change the captured variable outside the lambda as well ( Thx, @JonB )
- "
-
Signal / Slot arguments after capture inside
( .... )
, e.g. if signal sends aQListWidgetItem
, you need a(QListWidgetItem *item)
here. -
lambda code inside
{ .... }
- do whatever you like and what you would put in your slot here.
-
One big advantage using lambda connections is, that you can connect signals to slots (or "code"), that would be incompatible using a "direct" connection because of any reason (e.g. parameter mismatch).
Simple example:
// signal void signal(QString s); // slot void onSignalFired(int i);
A direct connection of these two won't work neither using the
SIGNAL(...) / SLOT( ... )
syntax
(-> crash / error at runtime),
nor using the function based connection&Class::signal... &Class::onSignalFired
( -> wont compile).With lambda, you can make it work:
connect(this, &Class::signal, [] (QString s) { onSignalFired( s.toInt() ); } );
Instead of calling the slot, you could also skip the slot and do whatever you want to do with this string inside the lambda directly, e.g. send your number to a
QLineEdit
("A" would lead to a 65, simple ASCII).@AnneRanch said in Please help with lambda sytax:
Here is my current - under construction connect to copy the "list" lines.
All it does - just compiles and cannot be tested , in existing code , due to this issue.... and this is exactly where you can make use of lambdas ( as @jsulm already said ).
Pass yourQListWidgetItem
from signal to your lambda, get the text from your item usingtext()
(Qt Doc), then pass the text toQPlainTextEdit
'sappendPlainText(QString)
. -
-
@AnneRanch said in Please help with lambda sytax:
function on_pushButton_11_clicked
@line 206Can you show your on_pushButton_11_clicked? The crash is there at line 206.
@jsulm said in Please help with lambda sytax:
@AnneRanch said in Please help with lambda sytax:
function on_pushButton_11_clicked
@line 206Can you show your on_pushButton_11_clicked? The crash is there at line 206.
There it is.
I have left in all the trace / debug stuff .
And highlighted the line 206code// scan for nearby BT devices void MainWindow_CAT_TAB::on_pushButton_11_clicked() { #ifdef TRACE qDebug() << "QDEBUG TRACE "; qDebug() << "QDEBUG TRACE TASK \n\t\t void MainWindow_CAT_TAB::on_pushButton_11_clicked() \n"; qDebug() << "QDEBUG TRACE TASK \n\t\t find nearby BT devices \n"; qDebug() << "file " << __FILE__; qDebug() << "function "<<__FUNCTION__; qDebug() << "@line " << __LINE__; qDebug()<<"TEMPORARY EXIT "; //exit(99); #endif // ui->listWidget_5->(" addItem(on_pushButton_11_clicked()"); // ui->listWidget_5->(addItem(on_pushButton_11_clicked()); ui->listWidget_5->addItem(" addItem(on_pushButton_11_clicked()"); ui->listWidget_5->addItem(" addItem(on_pushButton_11_clicked()"); ui->listWidget_5->addItem("information_main.count())"); #ifdef TRACE qDebug() << "QDEBUG TRACE "; qDebug() << "QDEBUG TRACE TASK \n\t\t START imoplement Device DiscoveryDialog \n"; qDebug() << "QDEBUG TRACE TASK \n\t\t find nearby BT devices \n"; qDebug() << "file " << __FILE__; qDebug() << "function "<<__FUNCTION__; **qDebug() << "@line " << __LINE__;** qDebug()<<"TEMPORARY EXIT "; //exit(99); #endif // instatiate Devievce Discovery Dialog as in btscanner example DeviceDiscoveryDialog *DDD = new DeviceDiscoveryDialog(); DDD->startScan(); // takes time 2 seconds for each device DDD->show(); #ifdef BYPASS // test add connect here connect( DDD->ui->list, // SIGNAL(DDD->ui->list->itemChanged(TEST_LABEL)), SIGNAL(itemChanged(TEST_LABEL)), DDD->ui->plainTextEdit, // SLOT(DDD->ui->plainTextEdit->appendPlainText(TEST_LABEL)) SLOT(appendPlainText(TEST_LABEL)) ); #endif #ifdef TRACE qDebug() << "QDEBUG TRACE "; qDebug() << "QDEBUG TRACE TASK \n\t\t END imoplement Device DiscoiveryDialog \n"; qDebug() << "QDEBUG TRACE TASK \n\t\t find nearby BT devices \n"; qDebug() << "file " << __FILE__; qDebug() << "function "<<__FUNCTION__; qDebug() << "@line " << __LINE__; qDebug()<<"TEMPORARY EXIT "; //exit(99); #endif }_text
-
@AnneRanch said in Please help with lambda sytax:
SIGNAL(itemChanged(TEST_LABEL)),
And you really want to tell us that you read at least one sentence from what we're telling you here??
-
@AnneRanch said in Please help with lambda sytax:
SIGNAL(itemChanged(TEST_LABEL)),
And you really want to tell us that you read at least one sentence from what we're telling you here??
Partial success.
Using both old and new "connect" style throws "segmentation fault" at either one.It is my understanding that "connect" code placement is not critical - however my crash occurs exactly on "connect" which I have placed in a secondary dialog constructor. My main window dialog is primary.
RTFM implies that passing null pointer may be the problem...
-
Partial success.
Using both old and new "connect" style throws "segmentation fault" at either one.It is my understanding that "connect" code placement is not critical - however my crash occurs exactly on "connect" which I have placed in a secondary dialog constructor. My main window dialog is primary.
RTFM implies that passing null pointer may be the problem...
@AnneRanch DONE!
Ready to tackle lambda .
Moral of the story - stay on original issue - it was my shallow knowledge of "connect" , my wrong syntax and my implementation of "connect" - applied in wrong place.Help from everybody assisting is very much appreciated.
-
@AnneRanch DONE!
Ready to tackle lambda .
Moral of the story - stay on original issue - it was my shallow knowledge of "connect" , my wrong syntax and my implementation of "connect" - applied in wrong place.Help from everybody assisting is very much appreciated.
@AnneRanch said in Please help with lambda sytax:
@AnneRanch DONE!
great, so please don't forget to mark your post as solved!