QSerialPort with Thread miss same data
-
@mrjj However, another program is working well like you can see my video. Is this big problem for application? e.g my application must immediately give an error in this condition and stop the communication.
What do you suggest me in order to solve this problem? I had used the LabVIEW before and developed like this application, it had worked flawlessly. -
I have added for you an example "qsp-no-freeze-workaround-windows" which demonstrates how it should work with threads!
-
I have added for you an example "qsp-no-freeze-workaround-windows" which demonstrates how it should work with threads!
@kuzulis Thank you very much, it's really working well. My first code that is in my first post here looks like this, but there is one different between them, it is inheritance. Is this a problem?
Also, how should I use qmutex between two classes in order to syncrhronşze? It's not declared the static and global variable is not recommended for it.
-
@kuzulis Thank you very much, it's really working well. My first code that is in my first post here looks like this, but there is one different between them, it is inheritance. Is this a problem?
Also, how should I use qmutex between two classes in order to syncrhronşze? It's not declared the static and global variable is not recommended for it.
@Gokhan said in QSerialPort with Thread miss same data:
how should I use qmutex between two classes in order to syncrhronşze?
What do you need to synchronize ?
You could use signals to tell other class about new data. -
@mrjj I must convert the received data to be meaningful, then will show these in tableview. I thought these data periodically will be converted and shown in two different thread for 100milisec.
@Gokhan
Hi, you cannot use any widget in any other thread than the main thread.
But using a signal to tell the some other class about the formatted data will work super.
https://stackoverflow.com/questions/15276628/send-data-from-worker-thread-to-gui-thread-in-qt -
@mrjj Don't I need a mutex if use a signal to tell other class? By the way, thread appends the raw array and after slot received a signal, it will convert the raw array and then clear it. Doesn't it need a mutex to do this process?
@Gokhan
The signal will contain a copy of the data so in most cases you do not need to protect it.
But depends on your design. If its possible that array is being written to , while you clear it then, yes
you need concurrency control. -
@mrjj Sometimes the array can be huge size, e.g 100K and conversion can take a long time furthermore it will show these data in tableview. Do not you think it takes a long time? Then which method do you suggest me to use?
-
-
To synchronize I used a global mutex, while running the convert class, everything is normal and it has converted successfully.
However, another class to show data has a problem, it's giving an error about visual c++. Also while holding left button on the bar it's not running.
When rowData<< new QStandardItem(strTableCount); and tableView->scrollToBottom(); is actived, it gives immediately an error. Where do I make mistake again?class DisplayData : public QThread { public: DisplayData () {} QTableView *tableView; uint32_t tableCount=0; uint32_t bufferSize = 100; QStandardItemModel *model; void init(QTableView *table){ tableView = table; model = new QStandardItemModel(); tableView->setModel(model); model->setHorizontalHeaderLabels(QString("Number;Time(sec);ID;Ext/Std;Rtr/Data;Lenght;D0;D1;D2;D3;D4;D5;D6;D7").split(";")); QHeaderView *verticalHeader = tableView->verticalHeader(); verticalHeader->setVisible(false); verticalHeader->setSectionResizeMode(QHeaderView::Fixed); verticalHeader->setDefaultSectionSize(20); tableView->setColumnWidth(0,60); tableView->setColumnWidth(1,70); tableView->setColumnWidth(2,70); tableView->setColumnWidth(3,50); tableView->setColumnWidth(4,60); tableView->setColumnWidth(5,50); tableView->setColumnWidth(6,40); tableView->setColumnWidth(7,40); tableView->setColumnWidth(8,40); tableView->setColumnWidth(9,40); tableView->setColumnWidth(10,40); tableView->setColumnWidth(11,40); tableView->setColumnWidth(12,40); tableView->setColumnWidth(13,40); } void run() override{ QString str; if(tableView == NULL) return; while(1){ mutexCanbusData.lock(); // it's global int dataLength = canbus_data.length(); mutexCanbusData.unlock(); if(dataLength) { for(int i=0;i<dataLength;i++){ tableCount++; const QMutexLocker locker(&mutexCanbusData); QString strTableCount=QString::number(tableCount); QString strTime=str.sprintf("%.03f",canbus_data.at(i).time).toUpper(); QList<QStandardItem *> rowData; // rowData<< new QStandardItem(strTableCount); // rowData<< new QStandardItem(QString::number(tableCount)); // // rowData<< new QStandardItem(str.sprintf("%.03f",shadowSerial->canbus_data.at(i).time).toUpper()); // // rowData<< new QStandardItem(str.sprintf("%08x",shadowSerial->canbus_data.at(i).id.all).toUpper()); // // rowData<< new QStandardItem((shadowSerial->canbus_data.at(i).attribute.att.id==1) ? "Ext":"Std"); // // rowData<< new QStandardItem((shadowSerial->canbus_data.at(i).attribute.att.rtr==1) ? "Rtr":"Data"); // // rowData<< new QStandardItem(QString::number(shadowSerial->canbus_data.at(i).attribute.att.number_of_bytes)); // // rowData<< new QStandardItem(str.sprintf("%02x",shadowSerial->canbus_data.at(i).data[0]).toUpper()); // // rowData<< new QStandardItem(str.sprintf("%02x",shadowSerial->canbus_data.at(i).data[1]).toUpper()); // // rowData<< new QStandardItem(str.sprintf("%02x",shadowSerial->canbus_data.at(i).data[2]).toUpper()); // // rowData<< new QStandardItem(str.sprintf("%02x",shadowSerial->canbus_data.at(i).data[3]).toUpper()); // // rowData<< new QStandardItem(str.sprintf("%02x",shadowSerial->canbus_data.at(i).data[4]).toUpper()); // // rowData<< new QStandardItem(str.sprintf("%02x",shadowSerial->canbus_data.at(i).data[5]).toUpper()); // // rowData<< new QStandardItem(str.sprintf("%02x",shadowSerial->canbus_data.at(i).data[6]).toUpper()); // // rowData<< new QStandardItem(str.sprintf("%02x",shadowSerial->canbus_data.at(i).data[7]).toUpper()); // // for(uint8_t i=0;i<14;i++) // // rowData[i]->setTextAlignment(Qt::AlignCenter); model->appendRow(rowData); if(tableCount>bufferSize){ model->removeRow(0); } } mutexCanbusData.lock(); canbus_data.clear(); mutexCanbusData.unlock(); } //tableView->scrollToBottom(); QThread::msleep(100); } } };``` -
Hi, you CANNOT use QTableView in another thread. Only in main thread. ( the gui)
-
@mrjj I got it, thank you very much for your interest. In my opinion, this topic will help the developers who are newbie in Qt like me :)