2015-11-24 2 views
0

J'ai vu un similar question, mais je pense que je suis la mise en œuvre du modèle correct et pourtant je ne peux pas le faire!Fil d'affinité: Impossible de créer des enfants pour un parent qui est dans un thread différent

Eh bien, j'ai un Gui pour démarrer et arrêter l'acquisition de données à partir d'un serial port et afficher les messages de communication nécessaires. Pour garder le Gui sensible, je déplace le travailleur à un fil. J'ai essayé de mettre en œuvre fil affinité, selon: How to Use QThread in the Right Way et How To Really, Truly Use QThreads. Quand je clique sur le bouton de démarrage, je reçois;

QWinEventNotifier: event notifiers cannot be enabled from another thread 
QWinEventNotifier: event notifiers cannot be enabled from another thread 
QWinEventNotifier: event notifiers cannot be enabled from another thread 
QObject: Cannot create children for a parent that is in a different thread. 
(Parent is QSerialPort(0x142cd390), parent's thread is QThread(0x1259b070), current thread is QThread(0x142db1f0) 

Que manque-t-il? Voici une partie du code lié à ma question:

tête des travailleurs

#ifndef COMPORT_H 
#define COMPORT_H 

#include <QObject> 
#include <QDebug> 
#include <QSerialPort> 

class QTimer; 

class ComPort : public QObject 
{ 
    Q_OBJECT 

public: 
    explicit ComPort(const QString &portName, QObject* parent = 0); 
    ~ComPort(); 

private: 
    QSerialPort* port; 
    QString   portMsg; 
    QByteArray  responseData; 
signals: 
    void finished(); 

private slots: 
    void onReadyRead(); 
    void setupPort(); 

}; 

#endif // COMPORT_H 

Travailleur cpp

#include "comport.h" 

ComPort::ComPort(const QString &portName, QObject *parent) 
    :QObject(parent) 
{ 
    this->port = new QSerialPort(portName); 
} 

ComPort::~ComPort() 
{ 
    port->close(); 
    delete port; 
} 

void ComPort::setupPort() 
{ 
    port->setBaudRate(QSerialPort::Baud19200); 
    port->setDataBits(QSerialPort::Data8); 
    port->setFlowControl(QSerialPort::NoFlowControl); 
    port->setParity(QSerialPort::NoParity); 
    port->setStopBits(QSerialPort::OneStop); 

    connect(port, SIGNAL(readyRead()), this, SLOT(onReadyRead())); 

    *SOME CODE HERE* 
} 

void ComPort::onReadyRead() 
{ 
    QByteArray bytes = port->readAll() ; 
    qDebug() << "bytes:" << bytes <<"\n"; 
    responseData.append(bytes); 
} 

et

Gui
#include "gui.h" 
#include "ui_gui.h" 

gui::gui(QWidget *parent) : 
    QDialog(parent), 
    ui(new Ui::gui) 
{ 
    ui->setupUi(this); 
    connect(ui->startButton, SIGNAL(clicked()), this, SLOT(OnstartButtonClicked())); 
} 

gui::~gui() 
{ 
    delete ui; 
} 

void gui::OnstartButtonClicked() 
{ 
    QThread* cThread = new QThread; 
    ComPort* cPort = new ComPort(QString("COM4")); 
    cPort->moveToThread(cThread); 
    connect(cPort, SIGNAL(finished()), cThread, SLOT(quit())); 
    connect(cPort, SIGNAL(finished()), cPort, SLOT(deleteLater())); 
    connect(cThread, SIGNAL(finished()), cThread, SLOT(deleteLater())); 
    connect(cThread, SIGNAL(started()), cPort, SLOT(setupPort())); 
    cThread->start(); 
} 

Répondre

0

Merci à la réponse de Kim Bowles Sørhus, j'ai résolu mon problème. Je créais un port série dans le constructeur de ComPort qui est appelé dans le thread principal. Lorsque l'objet cPort est déplacé vers le cThread le QSerialPort a toujours son affinité de thread définie sur le thread d'origine. Une solution consiste à créer le QSerialPort dans ComPort::setupPort.