文章目录

  • 一、上位机的信号和槽函数?
  • 二、上位机软件编程
    • 2.1.模块和类导入
    • 2.1.首先是写串口初始化
    • 2.1.串口读取
    • 2.2.串口写入
    • 2.3.清除数据框的内容
    • 2.4.自动搜索串口端口号
  • 三、全部代码展示
  • 四、UI设计 的一些设置
    • 4.1 改变颜色样式
    • 4.2 下拉框选择优先显示
  • 总结

本文是博主花一天写出来的上位机心得。主要包括上位机编写、Qt的json类的学习和使用


首先上一个上位机的图

一、上位机的信号和槽函数?

首先是我们要认识自动关联和手动关联
首先是自动关联是选择我们的组件右击选择转为槽

这时会在widget.h。添加一个槽函数的主程序

然后是在widget.c添加一个槽函数的源程序

然后是手动关联,这时就需要使用到一个函数
这个手动关联其实和LVGL的gui编程思维很想。信号就相当于状态,例如按键的信号有点击,开关。前沿按下,后沿按下等。然后是槽函数就相当于是事件处理函数。

connect(serialPort, //对象SIGNAL(readyRead()), //信号this,   //对象SLOT(DateRead())); //槽函数

二、上位机软件编程

2.1.模块和类导入

首先是 在.pro驱动文件添加模块

QT       += serialport


然后在widget.h添加类的头文件 在widget.c里面添加头文件

#include <QSerialPort>   //串口类
#include <QSerialPortInfo> //串口信息类
#include <QMessageBox> //错误提示类

#include <Qstring>
#include <QDebug>
#include <QFontDialog>
//解析json格式类
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>

2.1.首先是写串口初始化

在这之前要设置一下勾选串口按钮配置checkable。这个表示他有两种状态。打开和关闭

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//实例化 串口类serialPort = new QSerialPort(this);//清除串口ui->usartCp->clear();//扫描本机的串口,并且添加下拉框foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts() ){ui->usartCp->addItem(info.portName());}//手动关联,注意DataRead().connect(serialPort,SIGNAL(readyRead()),this,SLOT(DateRead()));
}Widget::~Widget()
{delete ui;
}void Widget::on_open_Usart_clicked(bool checked)
{if(checked){//设置要 打开的串口的名字serialPort->setPortName(ui->usartCp->currentText());//设置波特率serialPort->setBaudRate(ui->baundrateCb->currentText().toInt());//设置停止位switch(ui->stopCp->currentText().toInt()){case 1:serialPort->setStopBits(QSerialPort::OneStop);break;case 2:serialPort->setStopBits(QSerialPort::TwoStop);break;default:break;}//设置数据位switch(ui->dateCp->currentText().toInt()){case 5:serialPort->setDataBits(QSerialPort::Data5);break;case 6:serialPort->setDataBits(QSerialPort::Data6);break;case 7:serialPort->setDataBits(QSerialPort::Data7);break;case 8:serialPort->setDataBits(QSerialPort::Data8);break;default:break;}//设置校验位switch(ui->checkCb->currentIndex()){case 0:serialPort->setParity(QSerialPort::NoParity);break;case 1:serialPort->setParity(QSerialPort::EvenParity);break;case 2:serialPort->setParity(QSerialPort::OddParity);break;case 3:serialPort->setParity(QSerialPort::SpaceParity);break;case 4:serialPort->setParity(QSerialPort::MarkParity);break;default:break;}//设置数据流控为无serialPort->setFlowControl(QSerialPort::NoFlowControl);//判断串口是否被占用而打不开if(!serialPort->open(QIODevice::ReadWrite)){QMessageBox::about(this,"打开失败","串口打开失败可能被占用");serialPort->close();return;}//serialPort->open(QIODevice::ReadWrite);ui->usartCp->setEnabled(false);ui->baundrateCb->setEnabled(false);ui->stopCp->setEnabled(false);ui->dateCp->setEnabled(false);ui->checkCb->setEnabled(false);// ui->send_bit->setEnabled(true);ui->open_Usart->setText("关闭");}else{//关闭串口serialPort->close();ui->usartCp->setEnabled(true);ui->baundrateCb->setEnabled(true);ui->stopCp->setEnabled(true);ui->dateCp->setEnabled(true);ui->checkCb->setEnabled(true);// ui->send_bit->setEnabled(false);ui->open_Usart->setText("打开");}
}

2.1.串口读取

首先是在Widget.h声明接收串口数据的槽函数QByteArray DateRead();,

然后是手动关联槽函数看下面最后一段代码

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//实例化 串口类serialPort = new QSerialPort(this);//扫描本机的串口,并且添加下拉框ui->usartCp->clear();foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts() ){ui->usartCp->addItem(info.portName());}//手动关联槽函数connect(serialPort,SIGNAL(readyRead()),this,SLOT(DateRead()));
}

然后是写QByteArray DateRead();, 槽函数

QByteArray Widget::DateRead()  //接收数据
{//++++++++++++++++++++++++++++++++++这里是读取串口的数据并打印在文字显示栏++++++++++++++++++++++++++++++++++++++++++++++QByteArray temp=serialPort->readAll(); QString str=ui->recelives->toPlainText();str=QString::fromLocal8Bit(temp);ui->recelives->appendPlainText(str); //在recelives文字栏里面打印接收的数据//解析 JSON格式// QString json_str="{\"temp2\":15,\"yan\":29}";QByteArray recvData; recvData=temp; //获取字符串数据QString receive =QString::fromLocal8Bit(recvData.constData());//该变数据类型为string。// qDebug() << json_str ;QJsonDocument doc=QJsonDocument::fromJson(receive.toUtf8());QJsonObject obj=doc.object();
//提出Key为temp2的数据到Current里面,注意我们发送的数据是整形,那么提出来也是整形QJsonValue Current =obj.value("temp2");QJsonValue Voltage =obj.value("yan");QString Current_cp;//将整形数据Current.toInt()转换为字符串(QString)类型Current_cp.sprintf("%d",Current.toInt());QString Voltage_cp;Voltage_cp.sprintf("%d",Voltage.toInt());qDebug() << Current_cp ;qDebug() << Voltage_cp ;//ui->current_dat->display(Current.toInt());// ui->voltage_dat->dosplayVoltage.toInt()();ui->current_dat->display(Current_cp);//LCD_Number组件显示刷新,注意这里刷新的数据必须是字符串。ui->voltage_dat->display(Voltage_cp);temp.clear(); //释放temp数组的数据return temp;
}

上面代码设计到Qt的Json格式解析,我们把解析的数据放到特定的位置,下面就是特定的位置显示电流,电压,单片机通过串口发送JSON格式数据到上位机,然后上位机解析JSON格式,将数据提出了放到对应的位置

2.2.串口写入

这个没什么好说的,这里用自动关联就行。

void Widget::on_send_Out_clicked() //发送数据
{buff=ui->send_bit->toPlainText().toLocal8Bit().data();serialPort->write(buff);
}

2.3.清除数据框的内容

void Widget::on_send_Clear_clicked() //清除发送数据框
{ui->send_bit->clear();
}
void Widget::on_recelive_Clear_clicked()//清除接收数据框
{ui->recelives->clear();
}

2.4.自动搜索串口端口号

void Widget::on_open_Usart_2_clicked()  //搜索串口
{ui->usartCp->clear();foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts() ){ui->usartCp->addItem(info.portName());}
}

三、全部代码展示

widget.h头文件

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QSerialPort>   //串口类
#include <QSerialPortInfo> //串口信息类
#include <QMessageBox> //错误提示类QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_open_Usart_clicked(bool checked);void on_send_Out_clicked();void on_send_Clear_clicked();void on_open_Usart_2_clicked();QByteArray  DateRead();void on_recelive_Clear_clicked();QString getNumsFromStr(QString data);
private:Ui::Widget *ui;QSerialPort *serialPort;};
#endif // WIDGET_H

widget.c源文件

#include "widget.h"
#include "ui_widget.h"
#include <Qstring>
#include <QDebug>
#include <QFontDialog>
//解析json格式类
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>QByteArray buff;
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//实例化 串口类serialPort = new QSerialPort(this);//扫描本机的串口,并且添加下拉框ui->usartCp->clear();foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts() ){ui->usartCp->addItem(info.portName());}//读取数据connect(serialPort,SIGNAL(readyRead()),this,SLOT(DateRead()));
}Widget::~Widget()
{delete ui;
}void Widget::on_open_Usart_clicked(bool checked)
{if(checked){//设置要 打开的串口的名字serialPort->setPortName(ui->usartCp->currentText());//设置波特率serialPort->setBaudRate(ui->baundrateCb->currentText().toInt());//设置停止位switch(ui->stopCp->currentText().toInt()){case 1:serialPort->setStopBits(QSerialPort::OneStop);break;case 2:serialPort->setStopBits(QSerialPort::TwoStop);break;default:break;}//设置数据位switch(ui->dateCp->currentText().toInt()){case 5:serialPort->setDataBits(QSerialPort::Data5);break;case 6:serialPort->setDataBits(QSerialPort::Data6);break;case 7:serialPort->setDataBits(QSerialPort::Data7);break;case 8:serialPort->setDataBits(QSerialPort::Data8);break;default:break;}//设置校验位switch(ui->checkCb->currentIndex()){case 0:serialPort->setParity(QSerialPort::NoParity);break;case 1:serialPort->setParity(QSerialPort::EvenParity);break;case 2:serialPort->setParity(QSerialPort::OddParity);break;case 3:serialPort->setParity(QSerialPort::SpaceParity);break;case 4:serialPort->setParity(QSerialPort::MarkParity);break;default:break;}//设置数据流控为无serialPort->setFlowControl(QSerialPort::NoFlowControl);if(!serialPort->open(QIODevice::ReadWrite)){QMessageBox::about(this,"打开失败","串口打开失败可能被占用");serialPort->close();return;}//serialPort->open(QIODevice::ReadWrite);ui->usartCp->setEnabled(false);ui->baundrateCb->setEnabled(false);ui->stopCp->setEnabled(false);ui->dateCp->setEnabled(false);ui->checkCb->setEnabled(false);// ui->send_bit->setEnabled(true);ui->open_Usart->setText("关闭");}else{//关闭串口serialPort->close();ui->usartCp->setEnabled(true);ui->baundrateCb->setEnabled(true);ui->stopCp->setEnabled(true);ui->dateCp->setEnabled(true);ui->checkCb->setEnabled(true);// ui->send_bit->setEnabled(false);ui->open_Usart->setText("打开");}
}QByteArray Widget::DateRead()  //接收数据
{QByteArray temp=serialPort->readAll();QString str=ui->recelives->toPlainText();str=QString::fromLocal8Bit(temp);ui->recelives->appendPlainText(str);//解析 JSON格式// QString json_str="{\"temp2\":15,\"yan\":29}";QByteArray recvData;recvData=temp; //获取字符串数据QString receive =QString::fromLocal8Bit(recvData.constData());// qDebug() << json_str ;QJsonDocument doc=QJsonDocument::fromJson(receive.toUtf8());QJsonObject obj=doc.object();QJsonValue Current =obj.value("temp2");QJsonValue Voltage =obj.value("yan");QString Current_cp;Current_cp.sprintf("%d",Current.toInt());QString Voltage_cp;Voltage_cp.sprintf("%d",Voltage.toInt());qDebug() << Current_cp ;qDebug() << Voltage_cp ;//ui->current_dat->display(Current.toInt());// ui->voltage_dat->dosplayVoltage.toInt()();ui->current_dat->display(Current_cp);ui->voltage_dat->display(Voltage_cp);temp.clear();return temp;
}
QString Widget::getNumsFromStr(QString data){QString num;int j=0;for(int i=0;i<data.length();i++){if(data[i]>='0' && data[i]<='9'){num[j]=data[i];j++;}}return num;
}
void Widget::on_send_Out_clicked() //发送数据
{buff=ui->send_bit->toPlainText().toLocal8Bit().data();serialPort->write(buff);
}void Widget::on_send_Clear_clicked() //清除发送数据框
{ui->send_bit->clear();
}
void Widget::on_recelive_Clear_clicked()//清除接收数据框
{ui->recelives->clear();
}void Widget::on_open_Usart_2_clicked()  //搜索串口
{ui->usartCp->clear();foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts() ){ui->usartCp->addItem(info.portName());}
}

四、UI设计 的一些设置

4.1 改变颜色样式

首先选择我们要改变的组件,然后找到styleSheet属性,然后点击**…**

然后是选择颜色,里面第一个是文字颜色,下面是背景颜色。点击

然后选择颜色点击确定,就完成了。

4.2 下拉框选择优先显示


总结

这就是我今天写的上位机的代码和效果图,感觉还不错。

【QT上位机编写第三步】编写一个电压、电流显示串口上位机相关推荐

  1. 三步拆解一个数据分析体系

    在之前的文章中,我重点为大家介绍了以中台为核心的产品架构设计,但是只有产品功能在日常的运营过程中还是不够全面的,我们还需要另外一个辅助的工具. 1 为什么需要搭建数据分析体系 在进阶的产品经理工作中, ...

  2. 正点原子Linux开发板——Qt串口上位机实验

    前言: 最近在学习嵌入式qt开发,然后跟着教程编写了一个简单的串口上位机程序,在编写的时候还算比较顺利,但在调试的时候花了点功夫,折腾了一下午.最后还是理清了思路,解决了问题,特写此博客进行记录和总结 ...

  3. 如何三步搭建一套声纹系统

    背景介绍 声纹检索,顾名思义就是说话人识别,通过声音来验证或者识别说话人的声音.声纹识别的关键步骤就是声音向量化,将说话人的声音将其转化成结构化的向量.阿里云AnalyticDB向量版,提供了一套声纹 ...

  4. 三步完成博客打赏功能

    打赏功能简单概括一下就是别人进入你的博客园,能看到打赏,打赏可以通过支付宝和微信的方式来向你支付打赏金额,之前看到博客上许多人发这个功能,我就总结了一下,尽量用最简单的方式来让别人看懂,然后加以运用 ...

  5. STM32开发 -- Visual Studio C++编写串口上位机

    打算使用Visual Studio编写一个串口上位机程序,然后进行测试. 原来的上位机各种BUG,受不了了.自己写一个得了. 一.创建 MFC 工程 选择MFC应用: 应用程序类型选择 基于对话框: ...

  6. qt connect函数_Qt 串口上位机开发Rice 上位机 学习开发

    前几天分享了一个使用C#开发的串口上位机,那么今天教你如何100行QT代码实现一个串口上位机.如果你学习过C++,那么使用QT开发软件,就不是什么大问题了,QT很多时候使用在linux上.所以使用QT ...

  7. [教程]JS从糊涂到明白:一步一步编写计算器2 – 简化代码

     [文章原始发表:This Is WWW : http://www.plrsoft.cn/blog/?p=69  转载请注明出处]  我在上一篇文章"一步一步编写计算器 – 构建和兼容&qu ...

  8. ROS学习笔记三:编写第一个ROS节点程序

    在编写第一个ROS节点程序之前需要创建工作空间(workspace)和功能包(package). 一.创建工作空间(workspace) 创建一个catkin_ws: #注意:如果使用sudo一次性创 ...

  9. 神经网络与深度学习三:编写单隐层神经网络

    三:编写单隐层神经网络 1 神经网络概述 这篇文章你会学到如何实现一个神经网络,在我们深入学习技术细节之前,现在先大概快速的了解一下如何实现神经网络,如果你对某些内容不甚理解(后面的文章中会深入其中的 ...

最新文章

  1. 3-spark学习笔记-SparkAPI
  2. 初探百度大数据分析挖掘平台Jarvis
  3. BZOJ 1053 [HAOI2007]反素数ant
  4. 将多张连续的静态图转成gif动态图
  5. 广度(宽度)优先搜索思路总结
  6. 软件工程第二次作业——模仿实现主流网页
  7. 关于“程序员996”,大能发话了,能顶用吗?
  8. 【IDEA 教程系列第 14 篇】idea 快速跳转到错误位置
  9. 关于VS.NET中多个项目的工程相互引用和多个dll引用的问题! - antony--异域空间 - 博客园
  10. java解压7z格式的压缩包
  11. 新一代云数据库的引领者---AWS
  12. Docker磁盘空间满的解决办法
  13. 域名批量查询 网站域名批量查询
  14. 网站后门查杀工具推荐
  15. DevOps入门系列--前瞻性--前瞻性思维
  16. vue 数字变动动画实现
  17. Android ContentProvider之联系人数据库及操作
  18. 像学画画一样的学程序研发
  19. ORA-00054: 資源正被使用中, 請設定 NOWAIT 來取得它, 否則逾時到期
  20. HTML5 canvas图片爆炸特效

热门文章

  1. 我的七年,可能也是你的七年
  2. 企业带宽管理解决方案
  3. 拆机记录02——笔记本锂电池
  4. 美国普渡大学 计算机科学,普渡大学西拉法叶分校计算机科学系怎么样?
  5. 前端批量下载文件、图片、打包成压缩包,JZip和file-saver
  6. Unity-资源异步加载
  7. 【HDLBits 刷题 11】Circuits(7)Finite State Manchines 18-26
  8. JASS代码加翻译(第八篇)
  9. (生物信息学)R语言与统计学入门(五)—— Wilcoxon秩和检验法和Mann-Whitney U检验
  10. java实现正态分布(钟形曲线)