[SOLVED]Possible? Multiple QSerialPort Threads Simultaneously Independently
-
@SGaist
Hi,Here is my QObject for QSerialPort control, with openSerial, closeSerial, and algorithm to control how to read data.
When I put SenSerialControlAlgorithmObject into a thread, it keeps telling me
QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread
whenever it comes to the openSerial or closeSerial command, and the serial communication doesn't work.One Serial Port connects with one MCU to control one sensor.
#include <QObject> #include <QtSerialPort/QSerialPort> #include <QTime> #include <QElapsedTimer> class SenSerialControlAlgorithmObject : public QObject { Q_OBJECT public: explicit SenSerialControlAlgorithmObject(QObject *parent = 0); QSerialPort *mySerialPort; QByteArray SenMotionByteArray; bool motionReadBegun; QElapsedTimer *myElapsedTimer; signals: void emitSerialCloseSetting(); void emitSerialOpenedSetting(); void emitSerialDataToConsole(QByteArray); void emitMotionTrackingStart(); void emitMotionTrackingStop(qint64); void emitMotionUpdateSignal(QByteArray SenMotionByteArray, int); public slots: void openSerialPort(Settings mySettingInfo); void closeSerialPort(); void readData(); void handleError(QSerialPort::SerialPortError error); private: int motionReadBytes, delta_X, delta_Y; }; #endif // SENSERIALCONTROLALGORITHMOBJECT_H
-
How are you putting SenSerialControlAlgorithmObject in a QThread ?
-
@SGaist
MainWindow:#include <QMainWindow> #include <QtSerialPort/QSerialPort> #include "SenConsole.h" #include "SenSettingsDialog.h" #include "SenSerialControlAlgorithmObject.h" class SenOpticalFlowSensorsMainWindow : public QMainWindow { private slots: void writeData(const QByteArray &data); void showDataInConsole(QByteArray data); signals: void emitOpenSerialOrder(SenSettingsDialog::Settings); private: Ui::SenOpticalFlowSensorsMainWindow *myMainWindow_ui; SenConsole *mySenConsole; SenSettingsDialog *mySenSettingsDialog; SenSettingsDialog::Settings mySettingInfo; SenSerialControlAlgorithmObject *myDefaulSerialObject; QThread *mySerialThread; };
Constructor:
SenOpticalFlowSensorsMainWindow::SenOpticalFlowSensorsMainWindow(QWidget *parent) : QMainWindow(parent), myMainWindow_ui(new Ui::SenOpticalFlowSensorsMainWindow) { myMainWindow_ui->setupUi(this); mySenConsole = new SenConsole; setCentralWidget(mySenConsole); //// myDefaulSerialObject = new SenSerialControlAlgorithmObject(); //// mySenSettingsDialog = new SenSettingsDialog; initActionsConnections(); mySerialThread = new QThread(); // myDefaulSerialObject ->moveToThread(mySerialThread ); mySerialThread ->start(); }
-
Just do not use the threads if you don't know how to do it.
-
No it's not impossible, however thread programming is a complex matter where it's very very very easy to shoot yourself in the foot.
One guess: your actual QSerialPort doesn't have a parent, so when your move myDefaultSerialObject, the serial port itself is not moved.
-
QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread
I appreciate your guessing, however the application output reminder is telling something failed in another thread, which means the command of
if (mySerialPort->open(QIODevice::ReadWrite)) {//Here is when the hint comes out emit emitSerialOpenedSetting(); syncNumMotionsCount = 0; SenMotionByteArray.clear(); debugError = false; } else { emit emitSerialOpenErrorSetting(mySerialPort->errorString()); }
failed in another thread instead of main thread.
-
Although it is not allowed to open/close QSerialPort in a new thread,
It is not true. There are no differences in from what a thread to do open/close. A main things is that the QSerialPort should be moved into another thread before than opened/closed/read/write on it and so on. Besides, this should be called in that thread to which the QSerialPort was moved (not from the main thread or any others).
And I do not understand what is reason to use a more than one thread.. Because you can handle a data from the several serial ports (sensors) from the one main thread "simultaneous".
-
That is also what I do not understand.
What do you don't understand?
I once again will repeat: simply don't use the threads, if no reason for this! (in your case there are is no any reason)
QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread
Obviously, you do something wrong: all methods of QSerialPort shall be called from the same thread in which an QSerialPort lives.
It seems that, there is no way to push the Object, which contains QSerialPort, back to main thread and then close QSerialPort.
WTF?
-
@kuzulis
I don't understand what's wrong with my codes; it doesn't work anyway to open/close QSerialPort in a new thread.I made it in main thread, no problem without putting the Serial Communication Control in a new thread; however, is that possible to do multiple serial threads?
Two reasons to do threads:
- To make it as fast as possible;
- Learn my bug in programming: I do not want to encounter the same bug again.
-
Threads are not always the way to make a program go faster. In some cases performance can be worse with threads. Qt's asynchronous nature allows to avoid usage of thread for most of the cases and generally serial port can be handled in the GUI thread without problem.