mainwidget.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. #include "mainwidget.h"
  2. #include "ui_mainwidget.h"
  3. #include "Data_Ctrl.h"
  4. #include <QMessageBox>
  5. MainWidget::MainWidget(QWidget *parent)
  6. : QWidget(parent)
  7. , ui(new Ui::MainWidget)
  8. {
  9. ui->setupUi(this);
  10. ui->serialCB->clear();
  11. m_USBCtrl.SerialPortInit();
  12. connect(Data_Ctrl::getData()->serialPort,SIGNAL(readyRead()),this,SLOT(manual_serialPortReadyRead()));/*手动连接槽函数*/
  13. InitUI();
  14. InitConnect();
  15. // 定时发送-定时器
  16. timSend = new QTimer;
  17. timSend->setInterval(1000);// 设置默认定时时长1000ms
  18. connect(timSend, &QTimer::timeout, this, [=](){
  19. on_Button_tx_clicked();
  20. });
  21. }
  22. MainWidget::~MainWidget()
  23. {
  24. delete ui;
  25. }
  26. void MainWidget::InitUI()
  27. {
  28. //通过QSerialPortInfo查找可用串口
  29. foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
  30. {
  31. ui->serialCB->addItem(info.portName());
  32. }
  33. // 发送、接收计数清零
  34. sendNum = 0;
  35. recvNum = 0;
  36. // 状态栏的收、发计数标签
  37. lblSendNum = new QLabel(this);
  38. lblRecvNum = new QLabel(this);
  39. lblPortState = new QLabel(this);
  40. lblPortState->setText("Connected");
  41. //设置串口状态标签为绿色 表示已连接状态
  42. lblPortState->setStyleSheet("color:red");
  43. // 设置标签最小大小
  44. lblSendNum->setMinimumSize(100, 20);
  45. lblRecvNum->setMinimumSize(100, 20);
  46. lblPortState->setMinimumSize(550, 20);
  47. setNumOnLabel(lblSendNum, "S: ", sendNum);
  48. setNumOnLabel(lblRecvNum, "R: ", recvNum);
  49. // 从右往左依次添加
  50. ui->horizontalLayout_7->addWidget(lblPortState);
  51. ui->horizontalLayout_7->addWidget(lblSendNum);
  52. ui->horizontalLayout_7->addWidget(lblRecvNum);
  53. }
  54. void MainWidget::InitConnect()
  55. {
  56. connect(ui->pb_Debug,SIGNAL(clicked()),this,SLOT(slot_changeDebugMode()));
  57. connect(ui->Button_checkserial,SIGNAL(clicked()),this,SLOT(on_Button_checkserial_clicked()));
  58. connect(ui->Button_openserial,SIGNAL(clicked()),this,SLOT(on_Button_openserial_clicked()));
  59. connect(ui->Button_clearrecive,SIGNAL(clicked()),this,SLOT(on_Button_clearrecive_clicked()));
  60. connect(ui->Button_tx,SIGNAL(clicked()),this,SLOT(on_Button_tx_clicked()));
  61. connect(ui->Button_cleartx,SIGNAL(clicked()),this,SLOT(on_Button_cleartx_clicked()));
  62. }
  63. void MainWidget::manual_serialPortReadyRead()
  64. {
  65. QByteArray recBuf = Data_Ctrl::getData()->serialPort->readAll();;
  66. QString str_rev;
  67. // 接收字节计数
  68. recvNum += recBuf.size();
  69. // 状态栏显示计数值
  70. setNumOnLabel(lblRecvNum, "R: ", recvNum);
  71. if(ui->check_hex_recive->checkState() == false){
  72. if(ui->check_timestamp->checkState() == Qt::Checked){
  73. QDateTime nowtime = QDateTime::currentDateTime();
  74. str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
  75. str_rev += QString(recBuf).append("\r\n");
  76. }
  77. else{
  78. // 在当前位置插入文本,不会发生换行。如果没有移动光标到文件结尾,会导致文件超出当前界面显示范围,界面也不会向下滚动。
  79. //ui->recvEdit->appendPlainText(buf);
  80. if(ui->check_changeline->checkState() == Qt::Checked){
  81. str_rev = QString(recBuf).append("\r\n");
  82. }
  83. else
  84. {
  85. str_rev = QString(recBuf);
  86. }
  87. }
  88. }else{
  89. // 16进制显示,并转换为大写
  90. QString str1 = recBuf.toHex().toUpper();//.data();
  91. // 添加空格
  92. QString str2;
  93. for(int i = 0; i<str1.length (); i+=2)
  94. {
  95. str2 += str1.mid (i,2);
  96. str2 += " ";
  97. }
  98. if(ui->check_timestamp->checkState() == Qt::Checked)
  99. {
  100. QDateTime nowtime = QDateTime::currentDateTime();
  101. str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
  102. str_rev += str2.append("\r\n");
  103. }
  104. else
  105. {
  106. if(ui->check_changeline->checkState() == Qt::Checked)
  107. str_rev += str2.append("\r\n");
  108. else
  109. str_rev = str2;
  110. }
  111. }
  112. ui->recive_Edit->insertPlainText(str_rev);
  113. ui->recive_Edit->moveCursor(QTextCursor::End);
  114. }
  115. void MainWidget::on_Button_openserial_clicked()
  116. {
  117. if(ui->baudrate_CB->currentText()=="1200")
  118. Data_Ctrl::getData()->baudRate=QSerialPort::Baud1200;
  119. else if(ui->baudrate_CB->currentText()=="2400")
  120. Data_Ctrl::getData()->baudRate=QSerialPort::Baud2400;
  121. else if(ui->baudrate_CB->currentText()=="4800")
  122. Data_Ctrl::getData()->baudRate=QSerialPort::Baud4800;
  123. else if(ui->baudrate_CB->currentText()=="9600")
  124. Data_Ctrl::getData()->baudRate=QSerialPort::Baud9600;
  125. else if(ui->baudrate_CB->currentText()=="19200")
  126. Data_Ctrl::getData()->baudRate=QSerialPort::Baud19200;
  127. else if(ui->baudrate_CB->currentText()=="38400")
  128. Data_Ctrl::getData()->baudRate=QSerialPort::Baud38400;
  129. else if(ui->baudrate_CB->currentText()=="57600")
  130. Data_Ctrl::getData()->baudRate=QSerialPort::Baud57600;
  131. else if(ui->baudrate_CB->currentText()=="115200")
  132. Data_Ctrl::getData()->baudRate=QSerialPort::Baud115200;
  133. // 获取串口数据位
  134. if(ui->databit_CB->currentText()=="8")
  135. Data_Ctrl::getData()->dataBits=QSerialPort::Data5;
  136. else if(ui->databit_CB->currentText()=="7")
  137. Data_Ctrl::getData()->dataBits=QSerialPort::Data6;
  138. else if(ui->databit_CB->currentText()=="6")
  139. Data_Ctrl::getData()->dataBits=QSerialPort::Data7;
  140. else if(ui->databit_CB->currentText()=="5")
  141. Data_Ctrl::getData()->dataBits=QSerialPort::Data8;
  142. // 获取串口停止位
  143. if(ui->stopbit_CB->currentText()=="1")
  144. Data_Ctrl::getData()->stopBits=QSerialPort::OneStop;
  145. else if(ui->stopbit_CB->currentText()=="1.5")
  146. Data_Ctrl::getData()->stopBits=QSerialPort::OneAndHalfStop;
  147. else if(ui->stopbit_CB->currentText()=="2")
  148. Data_Ctrl::getData()->stopBits=QSerialPort::TwoStop;
  149. // 获取串口奇偶校验位
  150. if(ui->checkbit_CB->currentText() == "None"){
  151. Data_Ctrl::getData()->checkBits = QSerialPort::NoParity;
  152. }else if(ui->checkbit_CB->currentText() == "Odd"){
  153. Data_Ctrl::getData()->checkBits = QSerialPort::OddParity;
  154. }else if(ui->checkbit_CB->currentText() == "Even"){
  155. Data_Ctrl::getData()->checkBits = QSerialPort::EvenParity;
  156. }
  157. // 初始化串口属性,设置 端口号、波特率、数据位、停止位、奇偶校验位数
  158. Data_Ctrl::getData()->serialPort->setPortName(ui->serialCB->currentText());
  159. // 根据初始化好的串口属性,打开串口
  160. // 如果打开成功,反转打开按钮显示和功能。打开失败,无变化,并且弹出错误对话框。
  161. if(ui->Button_openserial->text() == "打开串口"){
  162. if(m_USBCtrl.SeralPortCtrl(SeralCtrlType::Seral_Open)){
  163. //QMessageBox::
  164. ui->Button_openserial->setText("关闭串口");
  165. // 让端口号下拉框不可选,避免误操作(选择功能不可用,控件背景为灰色)
  166. ui->serialCB->setEnabled(false);
  167. }else{
  168. QMessageBox::critical(this, "错误提示", "串口打开失败!!!\r\n该串口可能被占用\r\n请选择正确的串口");
  169. }
  170. //statusBar 状态栏显示端口状态
  171. QString sm = "%1 OPENED, %2, 8, NONE, 1";
  172. QString status = sm.arg(Data_Ctrl::getData()->serialPort->portName()).arg(Data_Ctrl::getData()->serialPort->baudRate());
  173. lblPortState->setText(status);
  174. lblPortState->setStyleSheet("color:green");
  175. }else{
  176. m_USBCtrl.SeralPortCtrl(SeralCtrlType::Seral_Close);
  177. ui->Button_openserial->setText("打开串口");
  178. // 端口号下拉框恢复可选,避免误操作
  179. ui->serialCB->setEnabled(true);
  180. //statusBar 状态栏显示端口状态
  181. QString sm = "%1 CLOSED";
  182. QString status = sm.arg(Data_Ctrl::getData()->serialPort->portName());
  183. lblPortState->setText(status);
  184. lblPortState->setStyleSheet("color:red");
  185. }
  186. }
  187. /*发送数据*/
  188. void MainWidget::on_Button_tx_clicked()
  189. {
  190. QByteArray array;
  191. //Hex复选框
  192. if(ui->check_hexsend->checkState() == Qt::Checked){
  193. //array = QString2Hex(data); //HEX 16进制
  194. array = QByteArray::fromHex(ui->send_Edit->toPlainText().toUtf8()).data();
  195. }else{
  196. //array = data.toLatin1(); //ASCII
  197. array = ui->send_Edit->toPlainText().toLocal8Bit().data();
  198. }
  199. if(ui->check_sendnewline->checkState() == Qt::Checked){
  200. array.append("\r\n");
  201. }
  202. // 如发送成功,会返回发送的字节长度。失败,返回-1。
  203. int a = Data_Ctrl::getData()->serialPort->write(array);
  204. // 发送字节计数并显示
  205. if(a > 0)
  206. {
  207. // 发送字节计数
  208. sendNum += a;
  209. // 状态栏显示计数值
  210. setNumOnLabel(lblSendNum, "S: ", sendNum);
  211. }
  212. }
  213. void MainWidget::on_Button_clearrecive_clicked()
  214. {
  215. ui->recive_Edit->clear();
  216. // 清除发送、接收字节计数
  217. sendNum = 0;
  218. recvNum = 0;
  219. // 状态栏显示计数值
  220. setNumOnLabel(lblSendNum, "S: ", sendNum);
  221. setNumOnLabel(lblRecvNum, "R: ", recvNum);
  222. }
  223. void MainWidget::on_Button_cleartx_clicked()
  224. {
  225. ui->recive_Edit->clear();
  226. // 清除发送字节计数
  227. sendNum = 0;
  228. // 状态栏显示计数值
  229. setNumOnLabel(lblSendNum, "S: ", sendNum);
  230. }
  231. void MainWidget::on_check_autosend_stateChanged(int arg1)
  232. {
  233. // 获取复选框状态,未选为0,选中为2
  234. if(arg1 == 0){
  235. timSend->stop();
  236. // 时间输入框恢复可选
  237. ui->spin_sendtime->setEnabled(true);
  238. }else{
  239. // 对输入的值做限幅,小于10ms会弹出对话框提示
  240. if(ui->spin_sendtime->text().toInt() >= 10){
  241. timSend->start(ui->spin_sendtime->text().toInt());// 设置定时时长,重新计数
  242. // 让时间输入框不可选,避免误操作(输入功能不可用,控件背景为灰色)
  243. ui->spin_sendtime->setEnabled(false);
  244. }else{
  245. ui->check_autosend->setCheckState(Qt::Unchecked);
  246. QMessageBox::critical(this, "错误提示", "定时发送的最小间隔为 10ms\r\n请确保输入的值 >=10");
  247. }
  248. }
  249. }
  250. void MainWidget::on_Button_checkserial_clicked()
  251. {
  252. ui->serialCB->clear();
  253. //通过QSerialPortInfo查找可用串口
  254. foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
  255. {
  256. ui->serialCB->addItem(info.portName());
  257. }
  258. }
  259. void MainWidget::slot_changeDebugMode()
  260. {
  261. int nIndex=ui->stackedWidget->currentIndex();
  262. if(nIndex<2)
  263. {
  264. ui->stackedWidget->setCurrentIndex(2);
  265. }else
  266. {
  267. ui->stackedWidget->setCurrentIndex(1);
  268. }
  269. }
  270. void MainWidget::setNumOnLabel(QLabel *lbl, QString strS, long num)
  271. {
  272. // 标签显示
  273. QString strN;
  274. strN.sprintf("%ld", num);
  275. QString str = strS + strN;
  276. lbl->setText(str);
  277. }