IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 基于QT平台的智能控制系统客户端 -> 正文阅读

[C++知识库]基于QT平台的智能控制系统客户端

系列文章目录

本次设计主要基于QT5.9平台设计了一款智能控制系统的上位机软件客户端,该软件可实现对电表、水表等仪器进行远程的数据读取与显示。为了保证客户的隐私,添加了用户登录等功能。具体效果如下:
登录界面

主界面

一、主程序代码

#include "workscene.h"
#include "ui_workscene.h"
#include <QDebug>
#include <QTime>
#include <QPainter>
//#include "myserial.h"
//#include "myvalue.h"

WorkScene::WorkScene(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::WorkScene)
{
    ui->setupUi(this);
    currentTime = new QLabel(this);
    time_cp = startTimer(1000);
    time_updata_map = startTimer(10);

    my_init_status();
    ui->statusbar->setSizeGripEnabled(false);

    myser = new MySerial(this);

    connect(ui->ser_config,&QAction::triggered,[=](){
//       myser = new MySerial(this);
        myser->show();
    });

    curr_equipment_num->setText(ui->box_equip_num->currentText());

    this->setWindowTitle("主界面");
}

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

//时间更新
void WorkScene::timeUpdate()
{
    //获取当前系统时间
    QDateTime time_data = QDateTime::currentDateTime();
    QString str = time_data.toString("yyyy/MM/dd hh:mm:ss");
    currentTime->setText(str);
}

//用于更新界面数据
void WorkScene::mapUpdate()
{
    calcData(Myvalue->get_ans_value());
    ui->lineEdit_ans1->setText(QString::number(dianliu));
    ui->lineEdit_ans2->setText(QString::number(dianya));
    ui->lineEdit_ans3->setText(QString::number(yali));

    curr_equipment_num->setText(ui->box_equip_num->currentText());
    curr_equipment_type->setText(ui->box_equip_type->currentText());
}

//重载timerEvent函数
void WorkScene::timerEvent(QTimerEvent * event)
{
    if(event->timerId() == time_cp)
    {
        timeUpdate();
    }
    if(event->timerId() == time_updata_map)
    {
        mapUpdate();
    }
}


void WorkScene::valvv()
{
    Myvalue = new MyValue(this);
    QString str = Myvalue->get_ans_value() + "mmm";
    qDebug() << str;
    qDebug() << "kk";
//    ui->lineEdit_ans->setText(str);
}

void WorkScene::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPixmap pix;
    pix.load(":/res/444.png");
    painter.drawPixmap(0,0,this->width(),this->height(),pix);
}

//计算结果
void WorkScene::calcData(QByteArray data)
{
    QByteArray data_num;
    if(data[0] == '\xAA' && data[1] == '\xAA')
    {
        data_num.append(data[2]);
        data_num.append(data[3]);
        bool ok;
        dianliu = (data_num.toHex().toInt(&ok,16)) / 100.00;
    }
    else if(data[0] == '\xBB' && data[1] == '\xBB')
    {
        data_num.append(data[2]);
        data_num.append(data[3]);
        bool ok;
        dianya = (data_num.toHex().toInt(&ok,16)) / 100.00;
    }
    else if(data[0] == '\xCC' && data[1] == '\xCC')
    {
        data_num.append(data[2]);
        data_num.append(data[3]);
        bool ok;
        yali = (data_num.toHex().toInt(&ok,16)) / 100.00;
    }
    else
    {
        dianliu = 0;
        dianya = 0;
        yali = 0;
    }
}

//采集命令使能触发信号
void WorkScene::on_btn_dianliu_clicked()
{
    qDebug() << "电流采集命令已发送!";
    myser->tx_dianliu_code();

}

void WorkScene::on_btn_dianya_clicked()
{
    qDebug() << "电压采集命令已发送!";
    myser->tx_dianya_code();
}

void WorkScene::on_btn_yali_clicked()
{
    qDebug() << "压力采集命令已发送!";
    myser->tx_yali_code();
}

//状态栏初始化
void WorkScene::my_init_status()
{
    curr_equipment_num_text = new QLabel("仪表设备号:",this);
    curr_equipment_num = new QLabel("",this);
    curr_equipment_type_text = new QLabel("仪表类型:");
    curr_equipment_type = new QLabel("",this);

    currentTime->setStyleSheet("color:white;");
    curr_equipment_num_text->setStyleSheet("color:white;");
    curr_equipment_num->setStyleSheet("color:white;");
    curr_equipment_type->setStyleSheet("color:white;");
    curr_equipment_type_text->setStyleSheet("color:white;");

    curr_equipment_num_text->setFixedWidth(70);
    curr_equipment_num->setFixedWidth(15);
    curr_equipment_type_text->setFixedWidth(60);
    curr_equipment_type->setFixedWidth(30);

    ui->statusbar->addPermanentWidget(currentTime);
    ui->statusbar->addWidget(curr_equipment_num_text);
    ui->statusbar->addWidget(curr_equipment_num);
    ui->statusbar->addWidget(curr_equipment_type_text);
    ui->statusbar->addWidget(curr_equipment_type);
}

二、串口代码

#include "myserial.h"
#include "ui_myserial.h"
#include <QtSerialPort/QSerialPortInfo>
#include "myvalue.h"
#include <QDebug>

MySerial::MySerial(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MySerial)
{
    ui->setupUi(this);
    serialPort = new QSerialPort(this); //实例化一个串口对象   (打开串口后,serialport就被实例化,在串口关闭之前,各个接口都能使用)
    on_btn_get_serial_clicked();  //获得可用串口
//    update_time = new QTimer(this);
//    update_time->start();
//    connect(update_time,&QTimer::timeout,this,[=](){
//        if(serialPort->open(QIODevice::ReadWrite))
//        {
//            ui->btn_open_close->setText(tr("关闭串口"));
//        }
//    });

    connect(this,&MySerial::has_data,this,[=](){
        qDebug() << "接收到数据了";
    });
}

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

//获取可用串口
void MySerial::on_btn_get_serial_clicked()
{
//    qDebug() << "进入检测串口函数";
    ui->box_choose_serial->clear();

    const auto infos = QSerialPortInfo::availablePorts();
    for(const QSerialPortInfo &info : infos)
    {
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            ui->box_choose_serial->addItem(info.portName());
//            qDebug()<<info.portName();
            serial.close();
        }
    }
}

//打开或者关闭串口
void MySerial::on_btn_open_close_clicked()
{
    if(ui->btn_open_close->text() == tr("打开串口"))
    {
//        serialPort = new QSerialPort; //实例化一个串口对象   (打开串口后,serialport就被实例化,在串口关闭之前,各个接口都能使用)
        //开始配置串口
        serialPort->setPortName(ui->box_choose_serial->currentText());//串口号的配置
        qDebug() <<ui->box_choose_serial->currentText();
        if(serialPort->open(QIODevice::ReadWrite))  //判断串口的打开方式是否为可读可写
        {
            //串口波特率的配置
            switch (ui->box_rate->currentIndex()) {
            case 0:
                serialPort->setBaudRate(QSerialPort::Baud115200);
                break;
            case 1:
                serialPort->setBaudRate(QSerialPort::Baud9600);
                break;
            case 2:
                serialPort->setBaudRate(QSerialPort::Baud4800);
                break;
            default:
                break;
            }
            switch (ui->box_shuju->currentIndex())
            {
            case 0:
                serialPort->setDataBits(QSerialPort::Data8);
                break;
            case 1:
                serialPort->setDataBits(QSerialPort::Data7);
                break;
            case 2:
                serialPort->setDataBits(QSerialPort::Data6);
                break;
            case 3:
                serialPort->setDataBits(QSerialPort::Data5);
                break;
            default:
                break;
            }
            //串口停止位配置   1位停止位
            serialPort->setStopBits(QSerialPort::OneStop);
            //串口校验位配置   没有校验位
            serialPort->setParity(QSerialPort::NoParity);

            connect(serialPort,&QSerialPort::readyRead,this, &MySerial::readToHex);

            ui->btn_open_close->setText(tr("关闭串口"));
        }
        else
        {
            QMessageBox::warning(NULL , "提示", "串口打开失败,资源未创建或串口可能被占用!");
            return;
        }
    }
    else
    {
        //关闭串口状态
        serialPort->clear();
        serialPort->close();
        serialPort->deleteLater();  //使用这个析构函数函数来释放申请的空间

        ui->btn_open_close->setText(tr("打开串口"));
    }
}

//读数据
void MySerial::readToHex()
{
    qDebug() << "触发信号";
    emit this->has_data();  //触发信号,表示接收到了数据

    QByteArray buf = serialPort->readAll();
    QString rece_str = "";
    QDataStream out(&buf,QIODevice::ReadOnly);
    while (!out.atEnd())
    {
        qint8 outChar = 0;
        out >> outChar;   //每字节填充一次,直到结束
        //十六进制转换
        QString str = QString("%1").arg(outChar&0xFF,2,16,QLatin1Char('0'));
        rece_str.append(str.toUpper()); //将str的16进制转换为大写
        rece_str.append("");           //每接收两个字符就加一个空格
    }
    MyValue * myval = new MyValue(this);
    myval->set_ans_value(buf);
}

//发送电流采集命令
void MySerial::tx_dianliu_code()
{
    myCom = new MyCommand(this);
    sendData = myCom->command_dianliu_code();
    serialPort->write(sendData);
}

//发送电压采集命令
void MySerial::tx_dianya_code()
{
    myCom = new MyCommand(this);
    sendData = myCom->command_dianya_code();
    serialPort->write(sendData);
}

//发送压力采集命令
void MySerial::tx_yali_code()
{
    myCom = new MyCommand(this);
    sendData = myCom->command_yali_code();
    serialPort->write(sendData);
}

三、命令管理文件

#include "mycommand.h"
#include <QDebug>
MyCommand::MyCommand(QWidget *parent) : QMainWindow(parent)
{

}
MyCommand::~MyCommand()
{

}
//电流采集命令
QByteArray MyCommand::command_dianliu_code()
{
    QString str;
    str = "21 01 22";
    return StringToHex(str);
}

//电压采集命令
QByteArray MyCommand::command_dianya_code()
{
    QString str;
    str = "21 02 23";
    return StringToHex(str);
}

//压力采集命令
QByteArray MyCommand::command_yali_code()
{
    QString str;
    str = "21 03 24";
    return StringToHex(str);
}

QByteArray MyCommand::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; )
    {
        //char lstr,
        hstr=str[i].toLatin1();
        if(hstr == ' ')
        {
            i++;
            continue;
        }
        i++;
        if(i >= len)
            break;
        lstr = str[i].toLatin1();
        hexdata = ConvertHexChart(hstr);
        lowhexdata = ConvertHexChart(lstr);
        if((hexdata == 16) || (lowhexdata == 16))
            break;
        else
            hexdata = hexdata*16+lowhexdata;
        i++;
        senddata[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }
    senddata.resize(hexdatalen);
    return senddata;
}

char MyCommand::ConvertHexChart(char ch)
{
  			 if((ch >= '0') && (ch <= '9'))
   {

      		 return ch-0x30;  // 0x30 对应 ‘0’
   }
   else if((ch >= 'A') && (ch <= 'F'))
   {
       return ch-'A'+10;
   }
   else if((ch >= 'a') && (ch <= 'f'))
   {
       return ch-'a'+10;
   }
   else
   {
      return -1;//不在0-f范围内的会发送成0
   }

}

等等


总结

以上就是今天要讲的内容,具体工程文件可通过下面链接下载!

https://download.csdn.net/download/goujimin/20667219

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:18:35  更:2022-03-24 00:19:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:53:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码