本次设计主要基于QT5.9平台设计了一款智能控制系统的上位机软件客户端,该软件可实现对电表、水表等仪器进行远程的数据读取与显示。为了保证客户的隐私,添加了用户登录等功能。具体效果如下:
#include "workscene.h"
#include "ui_workscene.h"
#include
#include
#include
//#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
#include "myvalue.h"
#include
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()<
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
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