#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
PortCheck();
//时钟定时器
timer_calendar = new QTimer(this);//new一个QTimer对象
connect(timer_calendar,SIGNAL(timeout()),this,SLOT(timerUpdate()));//连接槽函数
timer_calendar->start(100);//每10ms溢出一次进入槽函数
connect(serial,SIGNAL(readyRead()),this,SLOT(DataShow()));//显示数据
//设置只能输入数字
ui->period->setValidator(new QRegExpValidator(QRegExp("[0-9]+$")));//只能输入数字
ui->timestamp->setValidator(new QRegExpValidator(QRegExp("[0-9]+$")));//只能输入数字
//设置定时发送定时器
timSend=new QTimer(this); // 定时发送-定时器
connect(timSend,SIGNAL(timeout()),this,SLOT(on_send_clicked()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::PortCheck()//串口检测(扫描串口)
{
ui->Port->clear();
QStringList serialports;
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
serialports<<info.portName()+ ":" + info.description();
ui->Port->addItems(serialports);
}
void MainWindow::timerUpdate()
{
QDateTime dateTime= QDateTime::currentDateTime();//获取系统当前的时间
QString str = dateTime .toString("hh:mm:ss");//格式化时间
ui->time->setText("|当前时间:"+str);
}
void MainWindow::on_port_switch_clicked(bool)
{
if(ui->port_switch->text()==QString("打开串口"))
{
//设置串口名
serial->setPortName(ui->Port->currentText().mid(0,4));
//设置波特率
serial->setBaudRate(ui->Baud_Rate->currentText().toInt());
//设置数据
switch(ui->Data_Bits->currentText().toInt())
{
case 5:serial->setDataBits(QSerialPort::Data5);break;
case 6:serial->setDataBits(QSerialPort::Data6);break;
case 7:serial->setDataBits(QSerialPort::Data7);break;
case 8:serial->setDataBits(QSerialPort::Data8);break;
default:serial->setDataBits(QSerialPort::UnknownDataBits);break;
}
//设置奇偶校验位
switch(ui->Parity_Bits->currentIndex())
{
case 0:serial->setParity(QSerialPort::NoParity);break;
case 1:serial->setParity(QSerialPort::EvenParity);break;
case 2:serial->setParity(QSerialPort::OddParity);break;
default:serial->setParity(QSerialPort::UnknownParity);break;
}
//设置停止位
switch (ui->Stop_Bits->currentIndex())
{
case 0:serial->setStopBits(QSerialPort::OneStop);break;
case 1:serial->setStopBits(QSerialPort::OneAndHalfStop);break;
case 2:serial->setStopBits(QSerialPort::TwoStop);break;
default:serial->setStopBits(QSerialPort::UnknownStopBits);break;
}
//设置流控制
serial->setFlowControl(QSerialPort::NoFlowControl);
bool ret = serial->open(QIODevice::ReadWrite);
//打开串口
if(!ret)
{
QMessageBox::about(NULL,"提示","打开串口失败!!!或其他错误。\r\n请选择正确的串口或该串口被占用");
return;
}
ui->port_switch->setText("关闭串口");
}
else {
serial->close();
ui->port_switch->setText("打开串口");
}
}
void MainWindow::DataShow()//显示接收数据
{
ui->Data_Window->insertPlainText(QString::fromLocal8Bit(serial->readAll()));
}
void MainWindow::on_web_clicked()//打开网页
{
QDesktopServices::openUrl(QUrl("https://www.baidu.com", QUrl::TolerantMode));
}
void MainWindow::on_send_clicked()//发送数据
{
if(ui->Send_Newline->checkState()){
serial->write(ui->Send_Area->toPlainText().toLocal8Bit()+"\r\n");
}
else
serial->write(ui->Send_Area->toPlainText().toLocal8Bit());
}
void MainWindow::on_Clear_Receive_clicked()//清除接收
{
ui->Data_Window->clear();
}
void MainWindow::on_Timed_Send_stateChanged(int arg1)//定时发送
{
// 获取复选框状态,未选为0,选中为2
if(arg1 == 0){
ui->period->setEnabled(true);//设置周期可调
timSend->stop();
}else{
timSend->setInterval(ui->period->text().toInt());// 设置定时时长
timSend->start(ui->period->text().toInt());//每个周期时长溢出
ui->period->setEnabled(false);//设置周期不可调
}
}
void MainWindow::on_Hex_Send_stateChanged(int arg)//16进制发送
{
QByteArray sendData;
int sendNum;
// 判断是否为16进制发送,将发送区全部的asc2转换为16进制字符串显示,发送的时候转换为16进制发送
if(ui->Hex_Send->checkState() == false){
// 字符串形式发送
sendData = ui->Send_Area->toPlainText().toLocal8Bit().data();
}else{
// 16进制发送
sendData = QByteArray::fromHex(ui->Send_Area->toPlainText().toUtf8()).data();
}
// 如发送成功,会返回发送的字节长度。失败,返回-1。
int a = serial->write(sendData);
// 发送字节计数并显示
if(a > 0)
{
// 发送字节计数
sendNum+= a;
// 状态栏显示计数值
setNumOnLabel(ui->send_num, "S: ", sendNum);
}
}
void MainWindow::on_clear_send_clicked()//清除发送
{
ui->Send_Area->clear();
}
void MainWindow::on_Hex_Show_clicked(bool)//16进制显示
{
QString str=ui->Data_Window->toPlainText();
int len=str.length();
if(ui->Hex_Show->isChecked()){
if(len%2 == 1) //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
{
str = str.insert(len-1,'0');
}
QByteArray senddata;
StringToHex(str,senddata);//将str字符串转换为16进制的形式
ui->Data_Window->setPlainText(senddata);}//发送到串口
}
void MainWindow::StringToHex(QString str, QByteArray &senddata)//字符串转换为十六进制数据0-F
{
int hexdata,lowhexdata;
int hexdatalen = 0;
int len = str.length();
senddata.resize(len/2);
char lstr,hstr;
for(int i=0; i<len; )
{
hstr=str[i].toLatin1();
if(hstr == ' ')
{
i++;
continue;
}
i++;
if(i >= len)
break;
lstr = str[i].toLatin1();
hexdata = ConvertHexChar(hstr);
lowhexdata = ConvertHexChar(lstr);
if((hexdata == 16) || (lowhexdata == 16))
break;
else
hexdata = hexdata*16+lowhexdata;
i++;
senddata[hexdatalen] = (char)hexdata;
hexdatalen++;
}
senddata.resize(hexdatalen);
}
char MainWindow::ConvertHexChar(char ch)
{
if((ch >= '0') && (ch <= '9'))
return ch-0x30;
else if((ch >= 'A') && (ch <= 'F'))
return ch-'A'+10;
else if((ch >= 'a') && (ch <= 'f'))
return ch-'a'+10;
else return ch-ch;//不在0-f范围内的会发送成0
}
void MainWindow::on_RTS_clicked(bool checked)
{
if(serial->isOpen())
serial->setRequestToSend(checked);
}
void MainWindow::on_DTR_clicked(bool checked)
{
if(serial->isOpen())
serial->setDataTerminalReady(checked);
}
void MainWindow::setNumOnLabel(QLabel *lbl, QString strS, long num)// 状态