Serialport在一个单独的QThread中

问题描述 投票:0回答:1

我想将串行端口插入单独的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.

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

提前谢谢了。

c++ qt qthread
1个回答
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()信号,就可以在不使用线程的情况下完成。

如果你仍然坚持使用线程,只需使用相同的对象树并将其移动到指定的线程。

© www.soinside.com 2019 - 2024. All rights reserved.