串行端口在单独的QThread中

时间:2019-02-18 10:47:02

标签: c++ qt qthread

我想将串行端口插入单独的QThread中,但是应用程序崩溃。我写了以下C ++类

Worker.h

 class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = 0);

signals:
    void finished();
    void error(QString err);

public slots:
    void process();

};

class WorkerInterface : public QObject
{
    Q_OBJECT

public:
    explicit WorkerInterface(QObject *parent = nullptr);
    ~WorkerInterface();

    serialport *readSerialPort();

signals:
    void threadStoppedChanged();

public slots:
    void errorString(QString errorMsg);
    void stopThread();

private:
    QThread m_thread;
    serialPort *m_serial;
};

Worker::Worker(QObject *parent)
    : QObject(parent)
{
}

void Worker::process()
{

    emit finished();
}

Worker.cpp

WorkerInterface::WorkerInterface(QObject *parent)
    : QObject(parent)
    , m_thread(this)
{
    serialPort::serialPortMaster = new serialPort(nullptr);
    m_serial = serialPort::serialPortMaster;
    serialPort::serialPortMaster->moveToThread(&m_thread);
    connect(&m_thread, SIGNAL(started()),serialPort::serialPortMaster, SLOT(Init()));
    m_thread.start();

}

WorkerInterface::~WorkerInterface()
{
    m_thread.quit();
    m_thread.wait(1000);
    if (!m_thread.isFinished())
        m_thread.terminate();

}

void WorkerInterface::errorString(QString errorMsg)
{
    qDebug() << "error" << errorMsg;
}

void WorkerInterface::stopThread()
{
    m_thread.quit();
    m_thread.wait(1000);
    if (!m_thread.isFinished())
        m_thread.terminate();

    emit threadStoppedChanged();
}

serialPort* WorkerInterface::readSerialPort()
{
    return(m_serialPort);
}

在main.cpp中,我编写了以下代码:

WorkerInterface workerInterface;
engine.rootContext()->setContextProperty("newserial", workerInterface.readSerialPort());

QQmlComponent component(&engine,QUrl(QStringLiteral("qrc:/Pages/Content/Qml/main.qml")));

QObject *qmlObject = component.create();

当代码到达main.cpp中的最后一条指令时,应用程序崩溃,并且在QT创建者控制台中显示以下消息:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QSerialPort(0xee18c0), parent's thread is QThread(0xc8d8b0), current thread is QThread(0x7fffffffdc60)

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QSerialPort(0xee18c0), parent's thread is QThread(0xc8d8b0), current thread is QThread(0x7fffffffdc60)
QQmlEngine: Illegal attempt to connect to serialPort(0xee1710) that is in a different thread than the QML engine QQmlApplicationEngine(0x7fffffffdc30.

有人可以帮助我解决崩溃吗?

非常感谢。

1 个答案:

答案 0 :(得分:0)

假设您拥有可以响应文本的设备,那么做到这一点的最佳和最简单的方法就是这样:

class IODevLineReader
{
    Q_OBJECT
public:
    explicit IODevLineReader(QObject *parent);

public signals:
    void lineWasReceived(const QString &line);

public slots:
    void onReadyRead() {
        QIODevice *dev = qobject_cast<QIODevice *>(sender());
        while (dev && dev->canReadLine()) {
            auto lineBytes = dev->readLine();
            emit lineWasReceived(lineBytes);
        }
    }
};

只需将QSerialPort::readyRead()连接到IODevLineReader::onReadyRead()并将某个插槽连接到IODevLineReader::lineWasReceived()信号,就可以完成不使用线程的操作。

如果您仍然坚持使用线程,只需使用同一对象树并将其移至指定线程即可。