QextSerialPort是一个跨平台的第三方串口类,可以很方便地在QT中对串口读写操作。但是默认使用的读写方式是查询方式,一般都是在程序中使用定时器。如果需要快速响应串口读写,可以使用多线程方式。在qtcentre论坛上找到了一位作者贴出了自己的源码,在此转贴出来,方便大家。(原帖地址:http://www.qtcentre.org/threads/21063-QextSerialPort-with-QTimer-approch-for-reading?p=103325&highlight=#post103325)
程序是QT4直接可用的。如果是QTE2,相应做一些修改后也可以工作。
mythreadport.h
#ifndef MYSERIALPORT_H #define MYSERIALPORT_H #include
mythreadport.cpp
#include "myserialport.h" /* Private Functions */ void MySerialPort::initPrivateVariable() { // Init private variable sendThread = NULL; receiveThread = NULL; sendingEnable = false; receivingEnable = false; closeCalled = false; saveStateSendingEnable = false; saveStateReceivingEnable = false; saveStateReceiveData = false; } /******************************************************************************* ******************************* PUBLIC **************************************** ******************************************************************************/ /******************************* Constructor **********************************/ MySerialPort::MySerialPort() { initPrivateVariable(); } MySerialPort::MySerialPort(const QString &name, const BaudRateType baudRate, const DataBitsType dataBits, const ParityType parity, const StopBitsType stopBits, const FlowType flowControl, ulong seconds, ulong milliseconds) { initPrivateVariable(); setPortName(name); setBaudRate(baudRate); setDataBits(dataBits); setParity(parity); setStopBits(stopBits); setFlowControl(flowControl); setTimeout(seconds, milliseconds); } /******************************* Distructor ***********************************/ MySerialPort::~MySerialPort() { if (sendThread) { delete sendThread; sendThread = NULL; } if (receiveThread) { delete receiveThread; receiveThread = NULL; } if (isOpen()) port.close(); } /******************************* Methods **************************************/ // Open the SerialPort bool MySerialPort::open() { bool res = port.open(QIODevice::ReadWrite); // If the port is reopened after an earlier closure restores the previous state if (closeCalled) { if (saveStateSendingEnable) enableSending(); if (saveStateReceivingEnable) enableReceiving(); if (saveStateReceiveData) receiveData(); closeCalled = false; } return res; } bool MySerialPort::open(const QString &name, const BaudRateType baudRate, const DataBitsType dataBits, const ParityType parity, const StopBitsType stopBits, const FlowType flowControl, ulong seconds, ulong milliseconds) { setPortName(name); setBaudRate(baudRate); setDataBits(dataBits); setParity(parity); setStopBits(stopBits); setFlowControl(flowControl); setTimeout(seconds, milliseconds); //return open(); return port.open(QIODevice::ReadWrite); } // SerialPort is open? bool MySerialPort::isOpen() const { return port.isOpen(); } // Close the SerialPort void MySerialPort::close() { closeCalled = true; // Save the state saveStateSendingEnable = isSendingEnable(); saveStateReceivingEnable = isReceivingEnable(); // Close the port disableReceiving(); disableSending(); port.close(); // TODO: should I stop send and receive? } // Setter and getter for the basic property of the QextSerialPort void MySerialPort::setPortName(const QString &name) { port.setPortName(name); } QString MySerialPort::portName() const { return port.portName(); } void MySerialPort::setBaudRate(const BaudRateType baudRate) { port.setBaudRate(baudRate); } BaudRateType MySerialPort::baudRate() const { return port.baudRate(); } void MySerialPort::setDataBits(const DataBitsType dataBits) { port.setDataBits(dataBits); } DataBitsType MySerialPort::dataBits() const { return port.dataBits(); } void MySerialPort::setParity(const ParityType parity) { port.setParity(parity); } ParityType MySerialPort::parity() const { return port.parity(); } void MySerialPort::setStopBits(StopBitsType stopBits) { port.setStopBits(stopBits); } StopBitsType MySerialPort::stopBits() const { return port.stopBits(); } void MySerialPort::setFlowControl(const FlowType flowControl) { port.setFlowControl(flowControl); } FlowType MySerialPort::flowControl() const { return port.flowControl(); } void MySerialPort::setTimeout(const ulong seconds, const ulong milliseconds) { port.setTimeout(seconds, milliseconds); } /* Send */ // Enable the SerialPort to send data (init the thread) void MySerialPort::enableSending() { // If the Sending is not already active AND the sendThead is not initialized if (!sendingEnable && !sendThread) { sendThread = new SendThread(port); sendingEnable = true; } } // Disable the SerialPort to send data (terminate the thread) void MySerialPort::disableSending() { // If the Sending is already active AND there is a sendThread if (sendingEnable && sendThread) { delete sendThread; sendThread = NULL; sendingEnable = false; } } bool MySerialPort::isSendingEnable() const { return sendingEnable; } // Stop the currently sending data operation (don't terminate the thread) void MySerialPort::stopSending() { // If the Sending is not alread active OR the sendThread is not initialized if (!sendingEnable || !sendThread) return; // If the SerialPort is currently sending data, stop if (sendThread->isRunning()) { sendThread->stopSending(); //wait(); ?????????? sendThread->wait(); } } // Enqueue data to the sendThread queue // return 1 OK // return 2 port closed // return 3 sending operation disable uchar MySerialPort::sendData(const QByteArray &data) { // check the port if is open if (!isOpen()) return 2; // check if sending operation is enable if (!sendingEnable || !sendThread) return 3; sendThread->addDataToSend(data); return 1; } /* Receive */ // Enable the SerialPort to receive data (init the thread) void MySerialPort::enableReceiving() { // If the Receiving is not already active AND the receiveThead is not initialized if (!receivingEnable && !receiveThread) { receiveThread = new ReceiveThread(port); connect(receiveThread, SIGNAL(dataReceived(const QByteArray &)), this, SIGNAL(dataReceived(const QByteArray &))); receivingEnable = true; } } // Disable the SerialPort to receive data (terminate the thread) void MySerialPort::disableReceiving() { // If the Receiving is already active AND there is a receiveThread if (receivingEnable && receiveThread) { delete receiveThread; receiveThread = NULL; receivingEnable = false; } } bool MySerialPort::isReceivingEnable() const { return receivingEnable; } // Stop the currently receiving data operation (don't terminate the thread) void MySerialPort::stopReceiving() { // If the Receiving is not alread active OR the receiveThread is not initialized if (!receivingEnable || !receiveThread) return; // If the SerialPort is currently receiving data, stop if (receiveThread->isRunning()) { saveStateReceiveData = false; receiveThread->stopReceiving(); // wait(); receiveThread->wait(); } } // Start the receiving thread // return 1 OK // return 2 port closed // return 3 receiving operation disable uchar MySerialPort::receiveData() { // check the port if is open if (!isOpen()) return 2; // check if receiving operation is enable if (!receivingEnable && !receiveThread) return 3; // If the SerialPort receiving thread is not currently active, start it if (!receiveThread->isRunning()) { saveStateReceiveData = true; receiveThread->start(); } return 1; } /******************************************************************************* ******************************* SENDTHREAD ************************************ ******************************************************************************/ /******************************* Constructor **********************************/ SendThread::SendThread(QextSerialPort &adrPort): port(adrPort) { dataToSend.clear(); stopped = false; } /******************************* Distructor ***********************************/ SendThread::~SendThread() { if (isRunning()) { stopSending(); wait(); } } /******************************* Methods **************************************/ // Add the data to the Send Queue void SendThread::addDataToSend(const QByteArray &dataToAdd) { QMutexLocker locker(&mutexSend); for (int i=0; i