赞
踩
本文是博主花一天写出来的上位机心得。主要包括上位机编写、Qt的json类的学习和使用
首先上一个上位机的图
首先是我们要认识自动关联和手动关联
首先是自动关联是选择我们的组件右击选择转为槽
这时会在widget.h。添加一个槽函数的主程序
然后是在widget.c添加一个槽函数的源程序
然后是手动关联,这时就需要使用到一个函数
这个手动关联其实和LVGL的gui编程思维很想。信号就相当于状态,例如按键的信号有点击,开关。前沿按下,后沿按下等。然后是槽函数就相当于是事件处理函数。
connect(serialPort, //对象
SIGNAL(readyRead()), //信号
this, //对象
SLOT(DateRead())); //槽函数
首先是 在.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>
在这之前要设置一下勾选串口按钮配置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("打开"); } }
首先是在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格式,将数据提出了放到对应的位置
这个没什么好说的,这里用自动关联就行。
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());
}
}
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_NAMESPACE class Widget : public QWidget { Q_OBJECT public: 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()); } }
首先选择我们要改变的组件,然后找到styleSheet属性,然后点击**…**
然后是选择颜色,里面第一个是文字颜色,下面是背景颜色。点击
然后选择颜色点击确定,就完成了。
这就是我今天写的上位机的代码和效果图,感觉还不错。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。