QThread 的两种创建方式:object moveTo thread 方式

QThread 的两种创建方式:object moveTo thread 方式

**方法:工作对象继承QObject,包含 QThread 指针,创建Object 、创建QThread,然后object moveToThread() **
代码:

QSerial_Object_MoveTo_thread.pro

QT += core
QT += quick
QT += serialport

CONFIG += c++11

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
        main.cpp \
    serialinterface.cpp

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

HEADERS += \
    serialinterface.h

serialinterface.h

#ifndef SERIALINTERFACE_H
#define SERIALINTERFACE_H

#include 
#include 
#include 
#include 

// We use QSerialPort::SerialPortError in a signal so we must declare it as a meta type
Q_DECLARE_METATYPE(QSerialPort::SerialPortError)

Q_DECLARE_LOGGING_CATEGORY(SerialLinkLog)


class SerialInterface : public QObject
{
    Q_OBJECT
public:
    explicit SerialInterface(QObject *parent = nullptr);

signals:

    /*! 线程安全
     * \brief 数据转发
     * \param link
     * \param data
     */
    void bytesReceived(SerialInterface* link, QByteArray data);

public slots:
    void linkError(QSerialPort::SerialPortError error);

    /*! 发送数据
     *  1 调用线程执行(主线程)
     *  2 槽函数触发,线程安全, Qt::QueuedConnection
     */
    Q_INVOKABLE void writeData(QVariant data);

private slots:

    /*!
     * \brief 接收数据
     *
     *  Qt::DirectConnection
     *  槽函数在次线程中执行
     *
     *  Qt::QueuedConnection
     *  槽函数在所属对象SerialInterface线程中执行
     */
    void _readBytes();
private:
      QSerialPort *m_port;
      QThread *m_serialThread;
};

#endif // SERIALINTERFACE_H

serialinterface.cpp

#include "serialinterface.h"
#include 
#include 
#include 

Q_LOGGING_CATEGORY(SerialLinkLog, "SerialLinkLog")

SerialInterface::SerialInterface(QObject *parent) : QObject(parent)
{
    qCDebug(SerialLinkLog)<(&QSerialPort::error),
                     this, &SerialInterface::linkError, Qt::QueuedConnection);
    QObject::connect(m_port, &QIODevice::readyRead, this, &SerialInterface::_readBytes, Qt::QueuedConnection);


    // Try to open the port three times
    for (int openRetries = 0; openRetries < 3; openRetries++) {
        if (!m_port->open(QIODevice::ReadWrite)) {
            qCDebug(SerialLinkLog) << "Port open failed, retrying";
            // Wait 250 ms while continuing to run the event loop
            for (unsigned i = 0; i < 50; i++) {
                QThread::msleep(5);
                qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
            }
            qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
        } else {
            break;
        }
    }

    if (!m_port->isOpen() ) {
       qCDebug(SerialLinkLog)<< "open failed" << m_port->errorString() << m_port->error();

        m_port->close();
        delete m_port;
        m_port = NULL;
    }

    m_port->setDataTerminalReady(true);

    qCDebug(SerialLinkLog) << "Configuring port";
    m_port->setBaudRate     (QSerialPort::Baud9600);
    m_port->setDataBits     (QSerialPort::Data8);
    m_port->setFlowControl  (QSerialPort::SoftwareControl);
    m_port->setStopBits     (QSerialPort::OneStop);
    m_port->setParity       (QSerialPort::NoParity);


    //--moveToThread
    m_port->moveToThread(m_serialThread);
    this->moveToThread(m_serialThread);

    m_serialThread->start();
}


void SerialInterface::writeData(QVariant data)
{
    if (m_port && m_port->isOpen()) {
        m_port->write(data.toByteArray());
        qCDebug(SerialLinkLog)<isOpen()) {
        qint64 byteCount = m_port->bytesAvailable();
        if (byteCount) {
            QByteArray buffer;
            buffer.resize(byteCount);
            m_port->read(buffer.data(), buffer.size());

            qCDebug(SerialLinkLog)<

main.cpp

#include 
#include 
#include 
#include 

#include "serialinterface.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    qDebug()<("com.ui", 1, 0,"SerialInterface",QStringLiteral("Access to object"));

    SerialInterface *serial = new SerialInterface();

    engine.rootContext()->setContextProperty("serial", serial);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;


    //设置qml文件后执行
    QObject* rootQmlObject = engine.rootObjects().at(0);
    QObject::connect(rootQmlObject,SIGNAL(sendBtnClicked(QVariant)),serial,SLOT(writeData(QVariant)));

    return app.exec();
}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2

import QtQuick.Controls 2.4

import com.ui 1.0

Window {
    id:main
    visible: true
    width: 640
    height: 480
    title: qsTr("object moveTo thread")


    signal sendBtnClicked(var text)

    Button{
        id:sendBtn
        anchors{
            top:parent.top
            topMargin: 40
        }

        text:qsTr("Send")
        onClicked: {
            //serial.writeData(edit.text)
            sendBtnClicked(edit.text)
            edit.clear()

        }
    }


    Rectangle{
        width: 200
        height: 40

        anchors{
            left:sendBtn.right
            leftMargin:10
            verticalCenter:sendBtn.verticalCenter
        }

        color: "transparent"
        border.color: "#841775"
        border.width: 2


        TextEdit{
            id:edit
            anchors{
                fill:parent
            }

            horizontalAlignment: TextInput.AlignLeft
            clip:true

            wrapMode: TextEdit.WordWrap

        }


    }
}

串口接收函数(次线程中执行):

在次线程中执行

串口发送函数

  1. 主线程中执行
    函数调用方式,调用发送函数 : 发送函数在调用者线程中执行

  2. 次线程中执行
    信号槽方式,触发发送函数 : 发送函数在 次线程中执行

运行输出

使用虚拟串口 生成 /dev/pts/18 /dev/pts/19 一对串口
/dev/pts/18 用于程序 , 发送 666666666666
/dev/pts/19 用于串口助手,发送 99999999

QML debugging is enabled. Only use this in a safe environment.
int main(int, char**) 0x7f8baae0a780

SerialLinkLog: SerialInterface::SerialInterface(QObject*) 0x7f8baae0a780
SerialLinkLog: Configuring port

SerialLinkLog: void SerialInterface::_readBytes() 0x7f8b8cb00700
SerialLinkLog: "99999999"

SerialLinkLog: void SerialInterface::writeData(QVariant) 0x7f8b8cb00700
SerialLinkLog: void SerialInterface::writeData(QVariant) QVariant(QString, "666666666666")

Qt::DirectConnection 链接方式,槽函数在主线程中执行

QObject::connect(rootQmlObject,SIGNAL(sendBtnClicked(QVariant)),serial,SLOT(writeData(QVariant)),Qt::DirectConnection);

** 运行输出 **

使用虚拟串口 生成 /dev/pts/18 /dev/pts/19 一对串口
/dev/pts/18 用于程序 , 发送 fffffff
/dev/pts/19 用于串口助手,发送 ppppppp

QML debugging is enabled. Only use this in a safe environment.
int main(int, char**) 0x7fb575567780

SerialLinkLog: SerialInterface::SerialInterface(QObject*) 0x7fb575567780
SerialLinkLog: Configuring port

SerialLinkLog: void SerialInterface::_readBytes() 0x7fb54f3fe700
SerialLinkLog: "ppppppp"

SerialLinkLog: void SerialInterface::writeData(QVariant) 0x7fb575567780
SerialLinkLog: void SerialInterface::writeData(QVariant) QVariant(QString, "fffffff")

你可能感兴趣的:(QT/QML)