一、串口简介
一说到串口,就应该想到串口的几个参数:
- 波特率
- 数据位
- 停止位
- 校验位
对于串口助手来说,还要有一个确定的端口号,有了端口号才知道具体和哪个设备通信。
二、项目规划
编写一个串口助手,我们需要先把逻辑功能梳理清除,我也是个初学者,就从最简单的开始,先实现必备的几个功能,包括:数据的发送和接收,信息框的清除,串口的状态指示。
有了一个总体的规划,下面我们就可以动手开始做了,对于QT项目的开发,我们可以把它分成两部分,一部分是界面布局,另一部分是逻辑代码。
三、界面布局
先上我的布局图:
这就是我的整体布局,其中实现了部分功能,HEX显示和发送还有发送新行没有实现,其他都实现了。
下面介绍每部分的控件选择:
-
文字显示(除去按钮,按钮可以直接写)
-
参数选择
-
状态指示灯
状态指示灯同第一个文字显示的,都是使用的Label控件实现的。 -
按钮
-
发送框
-
接收框
四、逻辑代码
- 工程文件需要添加串口需要用到的 serialport
2.头文件中需要引用串口
3. 源文件中需要引用串口信息等用到的文件
除此大框架之外,再就是具体的逻辑代码了,下面将逻辑代码展示出来,包括:端口扫描,打开串口,数据发送与接收,发送框清空,接收框清空,关闭串口。
widget.cpp:
#include "widget.h"
#include "ui_widget.h"
#include <QSerialPortInfo>//使用串口
#include <QMessageBox>//弹窗提示框
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QStringList serialNamePort;
serialport = new QSerialPort(this);//头文件中定义了指针
connect(serialport, SIGNAL(readyRead()), this, SLOT(readyRead_slots()));//当有数据进来的时候会触发这个槽函数
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())//自动搜索串口信息
{
serialNamePort << info.portName();//将搜索到的串口信息给定义的类
}
ui->chuankouhcb->addItems(serialNamePort);//将搜索到的串口加到串口号combo Box控件中
setLED(ui->label_led1, 0, 16);//串口指示灯——没有打开是灰色
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_dakaibt_clicked()
{
QSerialPort::BaudRate botel = QSerialPort::Baud9600;
QSerialPort::DataBits shujuw = QSerialPort::Data8;
QSerialPort::StopBits tingzhiw = QSerialPort::OneStop;
QSerialPort::Parity jiaoyanw =QSerialPort::NoParity;
//波特率选择
switch(ui->botelcb->currentText().toInt())
{
case 4800:
botel = QSerialPort::Baud4800;
break;
case 9600:
botel = QSerialPort::Baud9600;
break;
case 115200:
botel = QSerialPort::Baud115200;
}
//数据位选择
if(ui->shujuwcb->currentText() == "5"){
shujuw = QSerialPort::Data5;
}else if(ui->shujuwcb->currentText() == "6"){
shujuw = QSerialPort::Data6;
}else if(ui->shujuwcb->currentText() == "7"){
shujuw = QSerialPort::Data7;
}else if(ui->shujuwcb->currentText() == "8"){
shujuw = QSerialPort::Data8;
}
//停止位选择
if(ui->tingzhiwcb->currentText() == "1"){
tingzhiw = QSerialPort::OneStop;
}else if(ui->tingzhiwcb->currentText() == "1.5"){
tingzhiw = QSerialPort::OneAndHalfStop;
}else if(ui->tingzhiwcb->currentText() == "2"){
tingzhiw = QSerialPort::TwoStop;
}
//校验位选择
if(ui->jiaoyanwcb->currentText() == "none"){
jiaoyanw = QSerialPort::NoParity;
}
//串口属性设置
serialport->setPortName(ui->chuankouhcb->currentText());//设置端口号
serialport->setBaudRate(botel);
serialport->setDataBits(shujuw);
serialport->setStopBits(tingzhiw);
serialport->setParity(jiaoyanw);
//判断串口是否打开成功
if(serialport->open(QIODevice::ReadWrite) == true)
{
setLED(ui->label_led1, 2, 16);
}
else
{
QMessageBox::information(this, "提示", "打开失败");
}
}
void Widget::on_buanbibt_clicked()//关闭按钮
{
setLED(ui->label_led1, 0, 16);
serialport->close();//关闭串口
}
void Widget::readyRead_slots()//接收数据
{
QString buf;
buf = QString(serialport->readAll());
ui->jieshouEdit->appendPlainText(buf);
}
void Widget::on_fasongbt_clicked()//发送按钮
{
serialport->write(ui->fasongEdit->text().toUtf8().data());
}
void Widget::on_qingchufbt_clicked()//发送清除
{
ui->fasongEdit->clear();
}
void Widget::on_qingchujsbt_clicked()//接收框清除
{
ui->jieshouEdit->clear();
}
void Widget::on_chuankouhcb_activated(const QString &arg1)
{
}
void Widget::on_chuankouhcb_customContextMenuRequested(const QPoint &pos)
{
}
//**********************自定义函数*******************/
// 该函数将label控件变成一个圆形指示灯,需要指定颜色color以及直径size
// color 0:grey 1:red 2:green 3:yellow
// size 单位是像素
void setLED(QLabel* label, int color, int size)
{
// 将label中的文字清空
label->setText("");
// 先设置矩形大小
// 如果ui界面设置的label大小比最小宽度和高度小,矩形将被设置为最小宽度和最小高度;
// 如果ui界面设置的label大小比最小宽度和高度大,矩形将被设置为最大宽度和最大高度;
QString min_width = QString("min-width: %1px;").arg(size); // 最小宽度:size
QString min_height = QString("min-height: %1px;").arg(size); // 最小高度:size
QString max_width = QString("max-width: %1px;").arg(size); // 最小宽度:size
QString max_height = QString("max-height: %1px;").arg(size); // 最小高度:size
// 再设置边界形状及边框
QString border_radius = QString("border-radius: %1px;").arg(size/2); // 边框是圆角,半径为size/2
QString border = QString("border:1px solid black;"); // 边框为1px黑色
// 最后设置背景颜色
QString background = "background-color:";
switch (color) {
case 0:
// 灰色
background += "rgb(190,190,190)";
break;
case 1:
// 红色
background += "rgb(255,0,0)";
break;
case 2:
// 绿色
background += "rgb(0,255,0)";
break;
case 3:
// 黄色
background += "rgb(255,255,0)";
break;
default:
break;
}
const QString SheetStyle = min_width + min_height + max_width + max_height + border_radius + border + background;
label->setStyleSheet(SheetStyle);
}
void Widget::on_pushButton_clicked()//刷新按钮
{
QStringList serialNamePort;
ui->chuankouhcb->clear();
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())//自动搜索串口信息
{
serialNamePort << info.portName();//将搜索到的串口信息给定义的类
}
ui->chuankouhcb->addItems(serialNamePort);//将搜索到的串口加到串口号combo Box控件中
}
void Widget::on_radioButton_clicked(bool checked)//接收16进制显示
{
}
void Widget::on_hexfb_clicked(bool checked)//发送16进制显示
{
}