QT C++ 多线程多串口界面设计

QT C++ 多线程多串口界面设计

2018年04月05日 20:57:47 江东风又起 阅读数:1036

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ysgjiangsu/article/details/79829150

忙了两三天了,总算得空记录一下QT串口,文末会有总的工程文件上传,多谢大家捧场。
之前博文写过PyQT,目前我逐渐偏向C++了,但主要代码思想没有变,如下:

第一,在QTdesigner下,建立好UI,如下图(右下角是我自己的小公司,留个爪印哈):
这里写图片描述
UI细节就不详细说了,具体可以看文末连接的工程文件

第二,新建串口线程类,这里要说明一下,QT本身已有串口类,我这里继承了QThread后,在类内添加串口类成员,代码如下:

#ifndef TASERIALTHREAD_H
#define TASERIALTHREAD_H

#include 
#include 
#include 
#include 

class TA_SerialThread:public QThread
{
public:
    TA_SerialThread();
    ~TA_SerialThread();

public:
    uint8_t portCnt;
    QSerialPort *m_arrSerial;//ptr point to an array,maxium port num is 5

public:
    void SearchPort(void);
    void InitPortName(uint8_t portIndex,const QString &portName);
    void InitPortBaudRate(uint8_t portIndex,qint32 baudRate);
    void InitPortDataBits(uint8_t portIndex,QSerialPort::DataBits dataBits);
    void InitPortParity(uint8_t portIndex,QSerialPort::Parity parity);
    void InitPortStopBits(uint8_t portIndex,QSerialPort::StopBits stopBits);
    void OpenPort(uint8_t portIndex);
    void ClosePort(uint8_t portIndex);
    void SendDataBuf(uint8_t portIndex,const QByteArray &str);
    QByteArray GetDataBuf(uint8_t portIndex);

private slots:
    void run();
};
#endif // TASERIALTHREAD_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

有几处说明,

QSerialPort *m_arrSerial;
  • 1

指针用于存储多个串口,当串口数组用了

uint8_t portCnt;
  • 1

用于标记当前串口的总个数
portIndex用于明确对哪个串口操作

第三,新建主窗口类,目的是将ui与底层连接起来,把二者融合在一个类里,类如下:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include "taserialthread.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    void MWOnoffPort(void);
    void MWSendCmd(void);
    void MWReadData(void);
    void MWClearRecv(void);
    void MWRSNumDisplay(void);

private:
    Ui::MainWindow *ui;
    TA_SerialThread *sPortThread;
    volatile uint32_t m_recvNum;
    volatile uint32_t m_sendNum;
};

#endif // MAINWINDOW_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

都是通过私有成员的方式,添加进类MainWindow

第四,信号与槽连接以及细节处理

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_recvNum = 0;
    m_sendNum = 0;
    sPortThread = new TA_SerialThread;
    sPortThread->SearchPort();

    for(uint8_t i = 0;i < sPortThread->portCnt;i++)
        ui->comboBox_SPortName->addItem(sPortThread->m_arrSerial[i].portName());

    //0:1200 1:2400 2:4800 3:9600 4:19200 5:38400 6:57600 7:115200
    ui->comboBox_SPortBaud->setCurrentIndex(3);
    //0:5 1:6 2:7 3:8
    ui->comboBox_SPortDataBit->setCurrentIndex(3);
    //0:no p 2:e p 3:o p 4:s p 5:m p
    ui->comboBox_SPortOEBit->setCurrentIndex(0);
    //0:1 1:2 2:1.5
    ui->comboBox_SPortStopBit->setCurrentIndex(0);

    ui->pushButton_SendCmd->setEnabled(false);
    ui->graphicsView_ComStatus->setStyleSheet("background-color: rgb(255, 0, 0);");
    ui->label_ComStatus->setText(tr("串口状态: 断开"));

    connect(ui->pushButton_OpenCom, SIGNAL(clicked(bool)), this, SLOT(MWOnoffPort()));
    connect(ui->pushButton_SendCmd, SIGNAL(clicked(bool)), this, SLOT(MWSendCmd()));
    connect(ui->pushButton_ClearRecv,SIGNAL(clicked(bool)),this, SLOT(MWClearRecv()));
}

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

void MainWindow::MWOnoffPort(void)
{
    uint8_t comIndex = ui->comboBox_SPortName->currentIndex();

    if(ui->pushButton_OpenCom->text()==tr("打开串口"))
    {
        sPortThread->InitPortName(comIndex,ui->comboBox_SPortName->currentText());
        sPortThread->InitPortBaudRate(comIndex,ui->comboBox_SPortBaud->currentText().toInt());

        //qDebug()<comboBox_SPortDataBit->currentIndex();
        switch(ui->comboBox_SPortDataBit->currentIndex())
        {
            case 0: sPortThread->InitPortDataBits(comIndex,QSerialPort::Data5); break;//0:5
            case 1: sPortThread->InitPortDataBits(comIndex,QSerialPort::Data6); break;//1:6
            case 2: sPortThread->InitPortDataBits(comIndex,QSerialPort::Data7); break;//2:7
            case 3: sPortThread->InitPortDataBits(comIndex,QSerialPort::Data8); break;//3:8
            default: break;
        }

        switch(ui->comboBox_SPortStopBit->currentIndex())
        {
            case 0:sPortThread->InitPortStopBits(comIndex,QSerialPort::OneStop);break;
            case 1:sPortThread->InitPortStopBits(comIndex,QSerialPort::TwoStop);break;
            case 2:sPortThread->InitPortStopBits(comIndex,QSerialPort::OneAndHalfStop);break;
            default: break;
        }

        switch(ui->comboBox_SPortOEBit->currentIndex())
        {
            case 0:sPortThread->InitPortParity(comIndex,QSerialPort::NoParity);break;
            case 1:sPortThread->InitPortParity(comIndex,QSerialPort::EvenParity);break;
            case 2:sPortThread->InitPortParity(comIndex,QSerialPort::OddParity);break;
            case 3:sPortThread->InitPortParity(comIndex,QSerialPort::SpaceParity);break;
            case 4:sPortThread->InitPortParity(comIndex,QSerialPort::MarkParity);break;
            default: break;
        }
        sPortThread->OpenPort(comIndex);

        connect(&(sPortThread->m_arrSerial[comIndex]), SIGNAL(readyRead()), this, SLOT(MWReadData()));

        //参数设置禁止
        ui->comboBox_SPortName->setEnabled(false);
        ui->comboBox_SPortBaud->setEnabled(false);
        ui->comboBox_SPortDataBit->setEnabled(false);
        ui->comboBox_SPortOEBit->setEnabled(false);
        ui->comboBox_SPortStopBit->setEnabled(false);
        ui->pushButton_OpenCom->setText(tr("关闭串口"));
        //发送设置使能
        ui->pushButton_SendCmd->setEnabled(true);
        ui->graphicsView_ComStatus->setStyleSheet("background-color: rgb(0, 255, 0);");
        ui->label_ComStatus->setText(tr("串口状态: 连接"));
    }
    else
    {
        sPortThread->ClosePort(comIndex);
        //参数设置使能
        ui->comboBox_SPortName->setEnabled(true);
        ui->comboBox_SPortBaud->setEnabled(true);
        ui->comboBox_SPortDataBit->setEnabled(true);
        ui->comboBox_SPortOEBit->setEnabled(true);
        ui->comboBox_SPortStopBit->setEnabled(true);
        ui->pushButton_OpenCom->setText(tr("打开串口"));
        //发送设置禁止
        ui->pushButton_SendCmd->setEnabled(false);
        ui->graphicsView_ComStatus->setStyleSheet("background-color: rgb(255, 0, 0);");
        ui->label_ComStatus->setText(tr("串口状态: 断开"));
    }
}

void MainWindow::MWSendCmd(void)
{
   sPortThread->SendDataBuf(ui->comboBox_SPortName->currentIndex(),ui->textEdit->toPlainText().toLatin1());
   m_sendNum +=  (ui->textEdit->toPlainText().toLatin1()).length();
   MWRSNumDisplay();
}

void MainWindow::MWReadData(void)
{
    QByteArray buf;

    buf = sPortThread->GetDataBuf(ui->comboBox_SPortName->currentIndex());

    if(!buf.isEmpty())
    {
        QString str = ui->textBrowser->toPlainText();
        str += tr(buf);
        ui->textBrowser->clear();
        ui->textBrowser->append(str);
        m_recvNum += tr(buf).length();
        MWRSNumDisplay();
    }

    buf.clear();
}

void MainWindow::MWClearRecv(void)
{
    ui->textBrowser->clear();
    m_recvNum = 0;
    m_sendNum = 0;
    MWRSNumDisplay();
}

void MainWindow::MWRSNumDisplay(void)
{
    ui->label_RecvNum->setText(tr("已接收:") + QString::number(m_recvNum,10));
    ui->label_SendNum->setText(tr("已发送:") + QString::number(m_sendNum,10));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148

看一下运行效果,
运行后
这里写图片描述
打开串口,发送指令
这里写图片描述
主要功能是,按SET+电压值+V的格式向DSP28335发送命令,如果DSP正确解析命令并调节出相应电压值,则返回V,经多次测试OK。

logo和自适应窗口大小还没做,界面还比较单调,以后会逐渐完善的

总体上,本工程可实现多个串口多线程通信,但是,目前的工程文件,只实现了基本框架以及基本的串口功能,该功能预留了框架,有些地方还在扩展中,时间关系,以后会逐渐更新。以下是全部工程压缩文件,欢迎大家拍砖哈
https://download.csdn.net/download/ysgjiangsu/10329501

你可能感兴趣的:(编程语言)