用qextserialport-1.2rc库写一个串口小工具

最近需要写一个串口工具,一开始完全找不到方向只好到处瞎碰,写这个就是希望后来者不要那么心累的到处瞎找....



首先得把这个第三方库下载下来,链接:http://code.google.com/p/qextserialport/downloads/detail?name=qextserialport-1.2rc.zip

下载好了之后,解压,在红色框里的文件夹里把对应的.cpp和.h文件拷到你创建的文件夹下(什么系统就拷什么后缀的)。


用qextserialport-1.2rc库写一个串口小工具_第1张图片

在.pro里添加:

include(qextserialport.pri)
然后可以看到如下框架:

用qextserialport-1.2rc库写一个串口小工具_第2张图片

首先我是先做的界面,如图:(直接拉的框框,不是敲代码实现的,见谅见谅)

用qextserialport-1.2rc库写一个串口小工具_第3张图片

那5个Btn直接右键转到槽选择第一个信号clicked()之后会跳到tool.cpp,大的框是textBrowser小的是lineEdit。

头文件tool.h:

#ifndef TOOL_H
#define TOOL_H

#include 
#include 
#include 
#include 
#include "qextserialport.h"
#include "qextserialenumerator.h"

namespace Ui {
class tool;
}

class tool : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::tool *ui;
    QextSerialPort *myCom;

private:
    void initPortList();

private slots:
    void readMyCom();
    void on_openMyComBtn_clicked();
    void on_closeMyComBtn_clicked();
    void on_cleanReceBtn_clicked();
    void on_sendDataBtn_clicked();
    void on_cleanSendBtn_clicked();
    void on_textBrowser_textChanged();
};

#endif // TOOL_H

tool.cpp文件:

#include "tool.h"
#include "ui_tool.h"
#include 
#include 

tool::tool(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::tool)
{
    ui->setupUi(this);
    //设置各按钮初始状态
    ui->closeMyComBtn->setEnabled(false);
    ui->cleanReceBtn->setEnabled(false);
    ui->cleanSendBtn->setEnabled(false);
    ui->sendDataBtn->setEnabled(false);

    initPortList();

    //按钮设置关联槽函数
    connect(ui->openMyComBtn, SIGNAL(clicked()), SLOT(on_openMyComBtn_clicked()));
    connect(ui->closeMyComBtn, SIGNAL(clicked()), SLOT(on_closeMyComBtn_clicked()));
    connect(ui->sendDataBtn, SIGNAL(clicked()), SLOT(on_sendDataBtn_clicked()));
    connect(ui->cleanReceBtn, SIGNAL(clicked()),SLOT(on_cleanReceBtn_clicked()));
    connect(ui->cleanSendBtn, SIGNAL(clicked()),SLOT(on_cleanSendBtn_clicked()));
    connect(myCom, SIGNAL(readyRead()), SLOT(readMyCom()));
    //窗口标题
    setWindowTitle(tr("串口工具"));
}

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

//读取系统可用的串口,并显示在combox中
void tool::initPortList()
{
    QList ports = QextSerialEnumerator::getPorts();
    foreach( QextPortInfo port, ports )
    {
        ui->portNameComboBox->addItem(port.portName);
    }
    ui->portNameComboBox->setEditable(true);
    PortSettings settings = {BAUD9600, DATA_8, PAR_NONE, STOP_1, FLOW_OFF, 10};
    myCom = new QextSerialPort(ui->portNameComboBox->currentText(), settings, QextSerialPort::EventDriven);

}

//串口read事件槽函数
void tool::readMyCom()
{
    QByteArray temp = myCom->readAll();
    ui->textBrowser->insertPlainText(temp.toHex());
}

//open按钮点击事件槽函数
void tool::on_openMyComBtn_clicked()
{
    myCom->open(QIODevice::ReadWrite);
    //设置波特率
    if (ui->baudRateComboBox->currentText() == tr("9600")){
        myCom->setBaudRate(BAUD9600);
    }else if (ui->baudRateComboBox->currentText() == tr("115200")){
        myCom->setBaudRate(BAUD115200);
    }
    //设置数据位
    if (ui->dataBitsComboBox->currentText() == tr("8")){
        myCom->setDataBits(DATA_8);
    }else if (ui->dataBitsComboBox->currentText() == tr("7")){
        myCom->setDataBits(DATA_7);
    }
    //设置奇偶校验
    if (ui->parityComboBox->currentText() == tr("无")){
        myCom->setParity(PAR_NONE);
    }else if (ui->parityComboBox->currentText() == tr("奇")){
        myCom->setParity(PAR_ODD);
    }else if (ui->parityComboBox->currentText() == tr("偶")){
        myCom->setParity(PAR_EVEN);
    }
    //设置停止位
    if (ui->stopBitsComboBox->currentText() == tr("1")){
        myCom->setStopBits(STOP_1);
    }else if (ui->stopBitsComboBox->currentText() == tr("2")){
        myCom->setStopBits(STOP_2);
    }
    //设置数据流控制,我们使用无数据流控制的默认设置
    myCom->setFlowControl(FLOW_OFF);
    //设置延时
    myCom->setTimeout(10);

    //设置各按钮是否可用
    ui->openMyComBtn->setEnabled(false);
    ui->closeMyComBtn->setEnabled(true);
    ui->cleanReceBtn->setEnabled(true);
    ui->cleanSendBtn->setEnabled(true);
    ui->sendDataBtn->setEnabled(true);
    //设置各组合框是否可用
    ui->baudRateComboBox->setEnabled(false);
    ui->dataBitsComboBox->setEnabled(false);
    ui->parityComboBox->setEnabled(false);
    ui->portNameComboBox->setEnabled(false);
    ui->stopBitsComboBox->setEnabled(false);
}

//close按钮点击事件槽函数
void tool::on_closeMyComBtn_clicked()
{
    myCom->close();

    ui->openMyComBtn->setEnabled(true);
    ui->closeMyComBtn->setEnabled(false);
    ui->sendDataBtn->setEnabled(false);
    ui->cleanReceBtn->setEnabled(true);
    ui->cleanSendBtn->setEnabled(true);

    ui->baudRateComboBox->setEnabled(true);
    ui->dataBitsComboBox->setEnabled(true);
    ui->parityComboBox->setEnabled(true);
    ui->portNameComboBox->setEnabled(true);
    ui->stopBitsComboBox->setEnabled(true);
}

//清除接收框按钮点击事件槽函数
void tool::on_cleanReceBtn_clicked()
{
    ui->textBrowser->setText("");
}

//把读取到的string型的转为16进制
void tool::StringToHex(QString str, QByteArray & senddata)
{
    int hexdata,lowhexdata;
    int hexdatalen = 0;
    int len = str.length();
    senddata.resize(len/2);
    char lstr,hstr;
    for (int i = 0;i < len;)
    {
        hstr = str[i].toLatin1();
        if (hstr == ' ')
        {
            i++;
            continue;
        }
        i++;
        if (i >= len)
        {
            break;
        }
        lstr = str[i].toLatin1();
        hexdata = ConvertHexChar(hstr);
        lowhexdata = ConvertHexChar(lstr);
        if ((hexdata == 16) || (lowhexdata == 16))
        {
            break;
        }else
        {
            hexdata = hexdata*16 + lowhexdata;
        }
        i++;
        senddata[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }
    senddata.resize(hexdatalen);
}
char tool::ConvertHexChar(char ch)
{
    if ((ch >= '0') && (ch <= '9'))
    {
        return ch-0x30;
    }else if ((ch >= 'A') && (ch <= 'F'))
    {
        return ch-'A'+10;
    }else if ((ch >= 'a') && (ch <= 'f'))
    {
        return ch-'a'+10;
    }else
    {
        return ch-ch;
    }
}


//send按钮点击事件槽函数
void tool::on_sendDataBtn_clicked()
{
    QString str = ui->lineEdit->text();
    if (!str.isEmpty())
    {
        //isHexSend = ui->isHexSend->isChecked();
        int len = str.length();
        //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加0
        if (len%2 == 1)
        {
            str = str.insert(len-1, '0');
        }


        QByteArray senddata;


        StringToHex(str, senddata);
        myCom->write(senddata);
    }
}

//清除发送框按钮点击事件槽函数
void tool::on_cleanSendBtn_clicked()
{
    ui->lineEdit->setText("");
}

//接收框显示最新数据
void tool::on_textBrowser_textChanged()
{
    ui->textBrowser->moveCursor(QTextCursor::End);
}
这样几乎就可以收发串口的数据了,但是肯定是不完善的.....



注意事项:

1、中文乱码问题:

在mian.cpp里添加以下代码,大部分是能够解决的:

//使程序可以处理中文
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForTr(codec);
    QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());
    QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());

2、接收框当接收数据超过当前框大小,后面数据会看不见,就需要tool.cpp最后一个槽函数来解决,这个可以见另一篇博客。http://blog.csdn.net/lingy_/article/details/74942037

3、接收转16进制显示的改写了,Qt自己封装了的,之前还傻乎乎的自己写...

4、发送按钮槽函数重新写了,改为发送16进制的数据(一般都是发16进制的命令吧=_=)

5、新增保存功能,在UI拉个pushbutton转到槽选择clicked()

要加头文件:

#include 
#include 
#include 
槽函数:

void tool::on_saveDataBtn_clicked()
{
    QString type = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation);

    QDir *temp = new QDir;
    bool exist = temp->exists(type + "/data");
    if(!exist)
        temp->mkdir(type + "/data");

    QDateTime datetime;
    QString timestr = datetime.currentDateTime().toString("yyyyMMddHHmmss");
    QString fileName = type + "/data/" + timestr + ".txt";

    QFile file(fileName);
    file.open(QIODevice::WriteOnly | QIODevice::Truncate);
    QString str = ui->textBrowser->toPlainText();
    QTextStream out(&file);
    out << str;
    file.close();
}

6、可以切换是否显示16进制,在UI添加一个CheckBox

然后重写接收:

void tool::readMyCom()
{
    QByteArray temp = myCom->readAll();

    //根据CheckBox是否选取来判断是否16进制显示
    if (ui->checkBox->isChecked())
    {
        ui->textBrowser->insertPlainText(temp.toHex());
    }else
    {
        ui->textBrowser->insertPlainText(temp);
    }
}
7、现在功能是比较齐全 的了,这篇博客就不在更新了。



你可能感兴趣的:(Qt)