Bonjour,
Je souhaite faire une application de lecture/écriture sur un port série.
Pour cela, j'ouvre un port en read/write et je lance 2 threads, 1 pour la lecture et 1 pour l'écriture.
Mes 2 thread fonctionnent si il sont ouvert alternativement en premier (j'ai fait le test de la permutation dans le code).
Lors de la mise en place du 2ième thread, j'ai l'erreur suivante dans la fenêtre d’exécution :
Et bien sur le 2ième thread ne fonctionne as, et là, je ne sais plus quoi faire.QObject::moveToThread: Current thread (0x55a970cd4f70) is not the object's thread (0x55a970fe66f0).
Cannot move to target thread (0x55a970f5fca0)
Est-ce que je fais quelque chose de mal ou est ce que j'ai oublié quelque chose??
Merci d'avance pour votre aide.
Voici mon code :
MainWindows.h
MainWindows.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 class MainWindow : public QMainWindow { Q_OBJECT QPushButton* bt_OpenPort = (QPushButton*)(Q_NULLPTR); QPushButton* bt_Transmission = (QPushButton*)(Q_NULLPTR); RS_Tools* m_RS_Tools = (RS_Tools*)(Q_NULLPTR); Thread_Exec* threadEmission = (Thread_Exec*)(Q_NULLPTR); Thread_Exec* threadReception = (Thread_Exec*)(Q_NULLPTR); public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); QPushButton* getBt_OpenPort() const; public slots: void demarrerTransmission(); };
RS_Tools.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , m_RS_Tools( new RS_Tools ) { QWidget* centralWidget = new QWidget(this); QGridLayout* layout = new QGridLayout(); bt_OpenPort = new QPushButton("Ouvrir port COM"); bt_OpenPort->setCheckable(true); bt_OpenPort->setChecked(false); connect(bt_OpenPort, &QPushButton::toggled, m_RS_Tools, &RS_Tools::initPort ); layout->addWidget(bt_OpenPort, 0,1); bt_Transmission = new QPushButton("Demarrer/Arreter transmission"); bt_Transmission->setCheckable(true); bt_Transmission->setChecked(false); QObject::connect(bt_Transmission, &QPushButton::toggled, this, &MainWindow::demarrerTransmission, Qt::DirectConnection ); layout->addWidget(bt_Transmission, 1,1); centralWidget->setLayout(layout); setCentralWidget(centralWidget); } MainWindow::~MainWindow() { delete threadEmission; // delete threadReception; delete m_RS_Tools; } QPushButton* MainWindow::getBt_OpenPort() const { return bt_OpenPort; } void MainWindow::demarrerTransmission() { qDebug() << "Démarrage des transmissions"; if( bt_Transmission->isChecked() ) { m_RS_Tools->setRunning( true ); // Mise en place de la réception des trames if( threadReception == Q_NULLPTR ) { threadReception = new Thread_Exec(); } m_RS_Tools->moveToThread(threadReception); m_RS_Tools->connect(threadReception, SIGNAL(started()), m_RS_Tools, SLOT(receptionTrame()), Qt::DirectConnection ); threadReception->connect( m_RS_Tools, SIGNAL(finished()), SLOT(quit() ), Qt::DirectConnection ); // Mise en place de l'emission des trames if( threadEmission == Q_NULLPTR ) { threadEmission = new Thread_Exec(); } m_RS_Tools->moveToThread(threadEmission); m_RS_Tools->connect(threadEmission, SIGNAL(started()), m_RS_Tools, SLOT(initEnvoiTrame()), Qt::DirectConnection ); m_RS_Tools->connect(threadEmission, SIGNAL(finished() ), m_RS_Tools, SLOT(initEnvoiTrame()), Qt::DirectConnection ); threadEmission->connect( m_RS_Tools, SIGNAL(finished() ), SLOT( quit() ), Qt::DirectConnection ); // On démarre le tout threadReception->start(); threadEmission->start(); } else { m_RS_Tools->setRunning( false ); } }
RS_Tools.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 class RS_Tools : public QSerialPort { Q_OBJECT bool m_Running; QTimer* timerEmission = (QTimer*)(Q_NULLPTR); public: RS_Tools(); ~RS_Tools(); void setRunning(const bool running); public slots: void initPort(const bool checked); void initEnvoiTrame(); void emissionTrame(); void receptionTrame(); signals: void trameRecue( const QByteArray* data ); void trameEnvoyee( const QByteArray* data ); void finished(); };
et enfin le Thread_Exec.h tout bete
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 RS_Tools::RS_Tools() : m_Running(false) { } RS_Tools::~RS_Tools() { } void RS_Tools::setRunning(const bool running) { qDebug() << "Running = " << running; m_Running = running; } void RS_Tools::initPort(const bool checked ) { qDebug() << "Initialisation du port COM"; setPortName( QSerialPortInfo::availablePorts().first().portName() ); setBaudRate( QSerialPort::Baud9600 ); setDataBits( QSerialPort::Data8 ); setParity( QSerialPort::NoParity ); setStopBits( QSerialPort::OneStop ); setFlowControl( QSerialPort::NoFlowControl ); if( checked ) { if( !open( QIODevice::ReadWrite )) { qDebug() << "Le port COM n'a pas pu être ouvert"; QMessageBox::critical(Q_NULLPTR, "Ouverture port COM", QObject::tr("Le port %1 n'a pas pu être ouvert").arg( portName() )); } else { qDebug() << "Le port COM a été ouvert"; QMessageBox::information(Q_NULLPTR, "Ouverture port COM", QObject::tr("Le port %1 a pu être ouvert").arg( portName() )); } } else { close(); qDebug() << "Le port est fermé"; } } void RS_Tools::initEnvoiTrame( ) { qDebug() << "Demarrage init envoi trame"; if( m_Running ) { if( timerEmission == Q_NULLPTR ) { timerEmission = new QTimer(); connect(timerEmission, SIGNAL(timeout()), this, SLOT(emissionTrame())); } timerEmission->start(); qDebug() << "Timer mis en route"; } else { if( timerEmission != Q_NULLPTR ) { if ( timerEmission->isActive() ) { timerEmission->stop(); qDebug() << "Arret du timer des emissions"; } } } } void RS_Tools::emissionTrame() { if( m_Running ) { QString tmpData = QString("Test des datas envoyees\r"); QByteArray* data = new QByteArray(tmpData.toStdString().c_str()); write(data->data(), data->size()); emit trameEnvoyee( data ); } else { emit finished(); } } void RS_Tools::receptionTrame() { while( m_Running ) { char tmpData[64]; qstrncpy(tmpData, 0, 64); QByteArray* data = new QByteArray(); waitForReadyRead(); read( tmpData, 64 ); data->append(tmpData); emit trameRecue( data ); qDebug() << "Data reçue : " << *data; } emit finished(); }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 class Thread_Exec : public QThread { protected: void run() { exec(); } };
Partager