How to use timer object to send a table row content each 2000msec ?
-
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), m_ui(new Ui::MainWindow), m_busStatusTimer(new QTimer(this)), m_speedTimer(new QTimer(this)) { m_ui->setupUi(this); connect(m_speedTimer, &QTimer::timeout, this, &MainWindow::on_Send_Row_Button_clicked);}
void MainWindow::on_SendAll_Button_clicked() {int a= m_ui->Table_CSV->model()->rowCount(); for(int i=0;i<a; i++) //R :read , W :write { QString PayloadData_R = m_ui->Table_CSV->model()->data(m_ui->Table_CSV->model()->index(i,1)).toString(); qDebug()<<"PayloadData_R="<<PayloadData_R; QString IdData_R = m_ui->Table_CSV->model()->data(m_ui->Table_CSV->model()->index(i,2)).toString(); qDebug()<<"IdData_R="<<IdData_R; // m_speedTimer->start(2000); sendFrame(IdData_R, PayloadData_R,i); }
void MainWindow::sendFrame(QString IdData_R,QString PayloadData_R,int i) { if (m_canDevice) { QCanBusFrame frameconnect; // Declaration nv trame :de type QCanBusFrame container of a single can frame = content "frameId + payload" to send //QString ID = IdData_R; //Declaration nv ID :chaine de caractère //const uint frameId = ID.toUInt(nullptr, 16); //Declaration nv frameID :conversion de ID (chaine de caractère) to uint(unsgned int taille 16bit) //just changed if 101 *** if (IdData_R=="Tx"){ QString ID = "101"; //Declaration nv ID :chaine de caractère qDebug() <<"Id Tx"<<ID; const uint frameId = ID.toUInt(nullptr, 16); //Declaration nv frameID :conversion de ID (chaine de caractère) to uint(unsgned int taille 16bit) //just changed if 101 *** frameconnect.setFrameId(frameId); //incertion de FrameId dans uint frameId QByteArray payloadconnect= QByteArray::fromHex(PayloadData_R.toLatin1()); //Declaration nv tab of bytes(octets) //fromHex: Renvoie une copie décodée du tableau encodé en hexadécimal hexEncoded. frameconnect.setPayload(payloadconnect);//incertion de FrameId dans uint frameId qDebug() << "payload connect to control board" << payloadconnect; //affichage en terminal payloadconnect="\xFF\x00" m_canDevice->writeFrame(frameconnect); //envoi ecriture du trame initialement crée (frameconnect) sur canDevice // QMessageBox::information(this,"Done","connect frame sent"); m_canDevice->waitForFramesReceived(2000); //attend reception trame 2sec snn out //Renvoie vrai si de nouvelles trames sont disponibles pour la lecture et que le signal framesReceived() est émis ; //sinon renvoie false (si l'opération a expiré ou si une erreur s'est produite). QCanBusFrame frametestconnect = m_canDevice->readFrame(); //read m_canDevice trame et stocage dans la nouvelle "frametestconnect" QByteArray connectRep = frametestconnect.payload();//recupération de payload du trame qDebug() << "trame de test" << connectRep; qDebug() << frametestconnect.payload() << " size reponse connect carte de commande" << frametestconnect.payload().size(); qDebug() << frametestconnect.frameId()<<"rense connect carte de commande" << frametestconnect.payload().size(); //Test comparaison result recu "connectRep" et resultat attendu "Testconnect" QByteArray Testconnect = QByteArray::fromHex("FF00");//"FF00804008000101" Dec de trame qu'il faut recupéré if( connectRep[0]==Testconnect[0]){ qDebug() <<"Test FF good!"; //model dialogue informing mModel->item(i, 4)->setText("FF");//ack mModel->item(i, 6)->setText("Pass");//result } else {qDebug() <<"Test bad! connectRep"<<connectRep; mModel->item(i, 4)->setText("FE");//ack mModel->item(i, 6)->setText("Fail");//result } } }//if 101 ** changeboth send and sendall //m_speedTimer->stop(); }
-
@imene What exactly is the issue? Do you expect others to analyse all this code to find out what is wrong?! And please reduce code to a minimum (remove everything not relevant for your problem)!
There is really nothing special:- Create a timer with 2000ms timeout
- In the slot connected to the timeout signal take next row and send it (use a member variable to remember which row was sent last time).
- Start the timer
- Stop the timer as soon as last line was sent
-
1_ Creation of a timer with 2000ms timeout:
int i=0; .... sendFrame(IdData_R, PayloadData_R,i,a); QObject::connect(sendTimer, SIGNAL(timeout()), this, SLOT(sendFrame(IdData_R, PayloadData_R,i++,a))); sendTimer->start(2000); i++; if (i==a){ sendTimer->stop(); }
void MainWindow::sendFrame(QString IdData_R,QString PayloadData_R,int i,int a) { if (m_canDevice) { { .....} if (i==a){ sendTimer->stop(); } }
it sends first line then it crashed !
-
@imene said in How to use timer object to send a table row content each 2000msec ?:
How to Create a timer with 2000ms timeout ?
Go to https://doc.qt.io/qt-6/qtimer.html and read:
QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, this, QOverload<>::of(&AnalogClock::update)); timer->start(1000);
Replace 1000 with 2000...
-
@imene said in How to use timer object to send a table row content each 2000msec ?:
QObject::connect(sendTimer, SIGNAL(timeout()), this, SLOT(sendFrame(IdData_R, PayloadData_R,i++,a)));
What do you think you are doing here? This old syntax for connecting signals and slots only takes types in the function's parameter list. You cannot provide the values here. It is better to use the new connect syntax:
QObject::connect(sendTimer, &QTimer::timeout, this, &MainWindow::sendFrame);
This will tell you at compile time when you are doing something wrong in you connect (there is no way to provide the parameter values in this syntax as it does not work anyway). You should have output on your console telling you that your connect (with the old syntax) failed.Moreover, you can only connect signals with slots that are compatible. Most importantly, a slot cannot have more parameters than the signal. All parameters have to be in the same order and have matching types.
QTimer::timeout()
will only connect to slots that don't have any parameters at all.What you could do instead is use lambdas with the new connect syntax:
QObject::connect(sendTimer, &QTimer::timeout, this, [this,IdData_R,PayloadData_R,i,a]() { sendFrame(IdData_R, PayloadData_R, i, a); });
If yourIdData_R
andPayloadData_R
can change over time you have to query them inside the lambda instead.