mainwidget.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. #include "mainwidget.h"
  2. #include "ui_mainwidget.h"
  3. #include "Data_Ctrl.h"
  4. MainWidget::MainWidget(QWidget *parent)
  5. : QWidget(parent)
  6. , ui(new Ui::MainWidget)
  7. {
  8. ui->setupUi(this);
  9. ui->serialCB_3->clear();
  10. m_USBCtrl.SerialPortInit();
  11. connect(Data_Ctrl::getData()->serialPort,SIGNAL(readyRead()),this,SLOT(manual_serialPortReadyRead()));/*手动连接槽函数*/
  12. InitUI();
  13. InitConnect();
  14. //QString currentPath = QDir::currentPath();
  15. m_TotalCHNum=14;
  16. for (int i=0;i<64;i++) {
  17. m_PDUCHInfo[i].CHNum=i+1;
  18. m_PDUCHInfo[i].CHName=QString("CH%1").arg(i+1);
  19. m_chWidget[i].chid=i+1;
  20. }
  21. _timer_update_info = new QTimer(this);
  22. _timer_update_info->setInterval(1000);
  23. connect(_timer_update_info, SIGNAL(timeout()), this, SLOT(UpdateStatusInfo()));
  24. _timer_update_info->start();
  25. m_DevFile="/dev/bus/usb/001/003";
  26. on_Button_checkserial_clicked();
  27. on_Button_openserial_clicked();
  28. QTimer* timSend = new QTimer(this);
  29. timSend->setInterval(1000);// 设置默认定时时长1000ms
  30. // 定时查询PDU状态
  31. m_SerialInfo=new SerialInfo();
  32. QObject::connect(m_SerialInfo, &SerialInfo::addPDUInfo,this, &MainWidget::on_add_PDUStatus,Qt::QueuedConnection);
  33. QThread* pduthread = new QThread;
  34. m_SerialInfo->moveToThread(pduthread);
  35. QObject::connect(pduthread, &QThread::started, m_SerialInfo, &SerialInfo::on_startWork);
  36. QObject::connect(pduthread, &QThread::finished, m_SerialInfo, &SerialInfo::on_closeWork);
  37. pduthread->start();
  38. }
  39. MainWidget::~MainWidget()
  40. {
  41. delete ui;
  42. }
  43. void MainWidget::InitUI()
  44. {
  45. // 发送、接收计数清零
  46. sendNum = 0;
  47. recvNum = 0;
  48. // 状态栏的收、发计数标签
  49. lblSendNum = new QLabel(this);
  50. lblRecvNum = new QLabel(this);
  51. lblPortState = new QLabel(this);
  52. lblPortState->setText("Connected");
  53. //设置串口状态标签为绿色 表示已连接状态
  54. lblPortState->setStyleSheet("color:red");
  55. // 设置标签最小大小
  56. lblSendNum->setMinimumSize(100, 20);
  57. lblRecvNum->setMinimumSize(100, 20);
  58. lblPortState->setMinimumSize(550, 20);
  59. setNumOnLabel(lblSendNum, "S: ", sendNum);
  60. setNumOnLabel(lblRecvNum, "R: ", recvNum);
  61. // 从右往左依次添加
  62. ui->horizontalLayout_15->addWidget(lblPortState);
  63. ui->horizontalLayout_15->addWidget(lblSendNum);
  64. ui->horizontalLayout_15->addWidget(lblRecvNum);
  65. ui->pb_Debug->setIcon(QIcon(":/resource/Serial.png"));
  66. ui->label_INT->setStyleSheet("color: rgb(0, 218, 205);");
  67. ui->label_26->setStyleSheet("color: rgb(0, 218, 205);");
  68. ui->label_OUTT->setStyleSheet("color: orange;");
  69. ui->label_29->setStyleSheet("color: orange;");
  70. // 创建一个 QWidget,并添加一些内容
  71. ui->gridLayout->setContentsMargins(1, 1, 1, 1);
  72. ui->gridLayout->setHorizontalSpacing(20);
  73. ui->gridLayout->setVerticalSpacing(8);
  74. m_TotalCHNum=14;
  75. for (int i=0;i<m_TotalCHNum;i++) {
  76. ui->gridLayout->addWidget(&m_chWidget[i], i%((m_TotalCHNum+1)/2), i/((m_TotalCHNum+1)/2));
  77. }
  78. QString styleSheet = "QWidget { background-color: #rgb(11, 17, 45); }";
  79. //ui->MainWidget->setStyleSheet(styleSheet);
  80. }
  81. void MainWidget::InitConnect()
  82. {
  83. connect(ui->pb_Debug,SIGNAL(clicked()),this,SLOT(slot_changeDebugMode()));
  84. connect(ui->Button_checkserial_3,SIGNAL(clicked()),this,SLOT(on_Button_checkserial_clicked()));
  85. connect(ui->Button_openserial_3,SIGNAL(clicked()),this,SLOT(on_Button_openserial_clicked()));
  86. connect(ui->Button_clearrecive_3,SIGNAL(clicked()),this,SLOT(on_Button_clearrecive_clicked()));
  87. connect(ui->Button_tx_4,SIGNAL(clicked()),this,SLOT(on_Button_tx_clicked()));
  88. connect(ui->Button_cleartx_4,SIGNAL(clicked()),this,SLOT(on_Button_cleartx_clicked()));
  89. }
  90. void MainWidget::manual_serialPortReadyRead()
  91. {
  92. QByteArray recBuf = Data_Ctrl::getData()->serialPort->readAll();;
  93. QString str_rev;
  94. // 接收字节计数
  95. recvNum += recBuf.size();
  96. // 状态栏显示计数值
  97. setNumOnLabel(lblRecvNum, "R: ", recvNum);
  98. if(ui->check_hex_recive_3->checkState() == false){
  99. if(ui->check_timestamp_3->checkState() == Qt::Checked){
  100. QDateTime nowtime = QDateTime::currentDateTime();
  101. str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
  102. str_rev += QString(recBuf).append("\r\n");
  103. }
  104. else{
  105. // 在当前位置插入文本,不会发生换行。如果没有移动光标到文件结尾,会导致文件超出当前界面显示范围,界面也不会向下滚动。
  106. //ui->recvEdit->appendPlainText(buf);
  107. if(ui->check_changeline_3->checkState() == Qt::Checked){
  108. str_rev = QString(recBuf).append("\r\n");
  109. }
  110. else
  111. {
  112. str_rev = QString(recBuf);
  113. }
  114. }
  115. }else{
  116. // 16进制显示,并转换为大写
  117. QString str1 = recBuf.toHex().toUpper();//.data();
  118. // 添加空格
  119. QString str2;
  120. for(int i = 0; i<str1.length (); i+=2)
  121. {
  122. str2 += str1.mid (i,2);
  123. str2 += " ";
  124. }
  125. if(ui->check_timestamp_3->checkState() == Qt::Checked)
  126. {
  127. QDateTime nowtime = QDateTime::currentDateTime();
  128. str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
  129. str_rev += str2.append("\r\n");
  130. }
  131. else
  132. {
  133. if(ui->check_changeline_3->checkState() == Qt::Checked)
  134. str_rev += str2.append("\r\n");
  135. else
  136. str_rev = str2;
  137. }
  138. }
  139. ui->recive_Edit_4->insertPlainText(str_rev);
  140. ui->recive_Edit_4->moveCursor(QTextCursor::End);
  141. }
  142. void MainWidget::on_Button_openserial_clicked()
  143. {
  144. if (!use_java)
  145. {
  146. if(ui->baudrate_CB_3->currentText()=="1200")
  147. Data_Ctrl::getData()->baudRate=QSerialPort::Baud1200;
  148. else if(ui->baudrate_CB_3->currentText()=="2400")
  149. Data_Ctrl::getData()->baudRate=QSerialPort::Baud2400;
  150. else if(ui->baudrate_CB_3->currentText()=="4800")
  151. Data_Ctrl::getData()->baudRate=QSerialPort::Baud4800;
  152. else if(ui->baudrate_CB_3->currentText()=="9600")
  153. Data_Ctrl::getData()->baudRate=QSerialPort::Baud9600;
  154. else if(ui->baudrate_CB_3->currentText()=="19200")
  155. Data_Ctrl::getData()->baudRate=QSerialPort::Baud19200;
  156. else if(ui->baudrate_CB_3->currentText()=="38400")
  157. Data_Ctrl::getData()->baudRate=QSerialPort::Baud38400;
  158. else if(ui->baudrate_CB_3->currentText()=="57600")
  159. Data_Ctrl::getData()->baudRate=QSerialPort::Baud57600;
  160. else if(ui->baudrate_CB_3->currentText()=="115200")
  161. Data_Ctrl::getData()->baudRate=QSerialPort::Baud115200;
  162. // 获取串口数据位
  163. if(ui->databit_CB_3->currentText()=="8")
  164. Data_Ctrl::getData()->dataBits=QSerialPort::Data5;
  165. else if(ui->databit_CB_3->currentText()=="7")
  166. Data_Ctrl::getData()->dataBits=QSerialPort::Data6;
  167. else if(ui->databit_CB_3->currentText()=="6")
  168. Data_Ctrl::getData()->dataBits=QSerialPort::Data7;
  169. else if(ui->databit_CB_3->currentText()=="5")
  170. Data_Ctrl::getData()->dataBits=QSerialPort::Data8;
  171. // 获取串口停止位
  172. if(ui->stopbit_CB_3->currentText()=="1")
  173. Data_Ctrl::getData()->stopBits=QSerialPort::OneStop;
  174. else if(ui->stopbit_CB_3->currentText()=="1.5")
  175. Data_Ctrl::getData()->stopBits=QSerialPort::OneAndHalfStop;
  176. else if(ui->stopbit_CB_3->currentText()=="2")
  177. Data_Ctrl::getData()->stopBits=QSerialPort::TwoStop;
  178. // 获取串口奇偶校验位
  179. if(ui->checkbit_CB_3->currentText() == "None"){
  180. Data_Ctrl::getData()->checkBits = QSerialPort::NoParity;
  181. }else if(ui->checkbit_CB_3->currentText() == "Odd"){
  182. Data_Ctrl::getData()->checkBits = QSerialPort::OddParity;
  183. }else if(ui->checkbit_CB_3->currentText() == "Even"){
  184. Data_Ctrl::getData()->checkBits = QSerialPort::EvenParity;
  185. }
  186. // 初始化串口属性,设置 端口号、波特率、数据位、停止位、奇偶校验位数
  187. Data_Ctrl::getData()->serialPort->setPortName(m_DevFile);
  188. //申请USB设备权限
  189. //QMessageBox::information(this, "确认", "申请权限:"+m_DevFile);
  190. requestUsbPermission(m_DevFile);
  191. // 根据初始化好的串口属性,打开串口
  192. // 如果打开成功,反转打开按钮显示和功能。打开失败,无变化,并且弹出错误对话框。
  193. if(ui->Button_openserial_3->text() == "打开串口"){
  194. if(m_USBCtrl.SeralPortCtrl(SeralCtrlType::Seral_Open)){
  195. //QMessageBox::
  196. ui->Button_openserial_3->setText("关闭串口");
  197. // 让端口号下拉框不可选,避免误操作(选择功能不可用,控件背景为灰色)
  198. ui->serialCB_3->setEnabled(false);
  199. }else{
  200. QMessageBox::critical(this, "错误提示", "串口打开失败!!!\r\n该串口可能被占用\r\n请选择正确的串口");
  201. }
  202. //statusBar 状态栏显示端口状态
  203. QString sm = "%1 OPENED, %2, 8, NONE, 1";
  204. QString status = sm.arg(Data_Ctrl::getData()->serialPort->portName()).arg(Data_Ctrl::getData()->serialPort->baudRate());
  205. lblPortState->setText(status);
  206. lblPortState->setStyleSheet("color:green");
  207. }
  208. else
  209. {
  210. m_USBCtrl.SeralPortCtrl(SeralCtrlType::Seral_Close);
  211. ui->Button_openserial_3->setText("打开串口");
  212. // 端口号下拉框恢复可选,避免误操作
  213. ui->serialCB_3->setEnabled(true);
  214. //statusBar 状态栏显示端口状态
  215. QString sm = "%1 CLOSED";
  216. QString status = sm.arg(Data_Ctrl::getData()->serialPort->portName());
  217. lblPortState->setText(status);
  218. lblPortState->setStyleSheet("color:red");
  219. }
  220. }
  221. else
  222. {
  223. m_DevFile = ui->serialCB_3->currentText();
  224. requestUsbPermission(m_DevFile);
  225. if(ui->Button_openserial_3->text() == "打开串口"){
  226. requestUsbPermission(m_DevFile);
  227. QAndroidJniObject javaString = QAndroidJniObject::fromString(m_DevFile);
  228. jboolean res = QAndroidJniObject::callStaticMethod<jboolean>(
  229. "usb/USBListActivity",
  230. "OpenSerial",
  231. "(Ljava/lang/String;)Z",
  232. javaString.object<jstring>());
  233. if (res==true)
  234. {
  235. m_openflag=true;
  236. lblPortState->setText("connected");
  237. lblPortState->setStyleSheet("color:green");
  238. ui->Button_openserial_3->setText("关闭串口");
  239. //QMessageBox::information(this, "确认", "打开成功!");
  240. }
  241. else
  242. {
  243. m_openflag=false;
  244. lblPortState->setText("disconnected");
  245. lblPortState->setStyleSheet("color:red");
  246. ui->Button_openserial_3->setText("打开串口");
  247. QMessageBox::information(this, "确认", "打开失败!");
  248. }
  249. /*
  250. QAndroidJniObject javaString = QAndroidJniObject::fromString(m_DevFile);
  251. QAndroidJniObject restring = QAndroidJniObject::callStaticObjectMethod(
  252. "usb/USBListActivity",
  253. "OpenSerial",
  254. "(Ljava/lang/String;)Ljava/lang/String;",
  255. javaString.object<jstring>());
  256. QString recinfo=restring.toString();
  257. QMessageBox::information(this, "确认", recinfo);*/
  258. }
  259. else
  260. {
  261. QAndroidJniObject javaString = QAndroidJniObject::fromString(m_DevFile);
  262. jboolean res = QAndroidJniObject::callStaticMethod<jboolean>(
  263. "usb/USBListActivity",
  264. "closeSerial",
  265. "(Ljava/lang/String;)Z",
  266. javaString.object<jstring>());
  267. if (res==true)
  268. {
  269. m_openflag=false;
  270. lblPortState->setText("disconnected");
  271. lblPortState->setStyleSheet("color:red");
  272. ui->Button_openserial_3->setText("打开串口");
  273. //QMessageBox::information(this, "确认", "关闭成功!");
  274. }
  275. else
  276. {
  277. m_openflag=true;
  278. lblPortState->setText("connected");
  279. lblPortState->setStyleSheet("color:green");
  280. ui->Button_openserial_3->setText("关闭串口");
  281. QMessageBox::information(this, "确认", " 关闭失败!");
  282. }
  283. }
  284. }
  285. }
  286. /*发送数据*/
  287. void MainWidget::on_Button_tx_clicked()
  288. {
  289. if(!use_java)
  290. {
  291. QByteArray array;
  292. //Hex复选框
  293. if(ui->check_hexsend_4->checkState() == Qt::Checked){
  294. //array = QString2Hex(data); //HEX 16进制
  295. array = QByteArray::fromHex(ui->send_Edit_3->toPlainText().toUtf8()).data();
  296. }else{
  297. //array = data.toLatin1(); //ASCII
  298. array = ui->send_Edit_3->toPlainText().toLocal8Bit().data();
  299. }
  300. if(ui->check_sendnewline_4->checkState() == Qt::Checked){
  301. array.append("\r\n");
  302. }
  303. int a = Data_Ctrl::getData()->serialPort->write(array);
  304. // 发送字节计数并显示
  305. if(a > 0)
  306. {
  307. // 发送字节计数
  308. sendNum += a;
  309. // 状态栏显示计数值
  310. setNumOnLabel(lblSendNum, "S: ", sendNum);
  311. }
  312. else
  313. {
  314. ui->recive_Edit_4->insertPlainText("发送失败!!!!!");
  315. }
  316. }
  317. else
  318. {
  319. // 如发送成功,会返回发送的字符串,失败返回空字符串
  320. if(!m_openflag)
  321. {
  322. QMessageBox::information(this, "确认", " 发送失败!串口未打开!");
  323. return;
  324. }
  325. //int a = Data_Ctrl::getData()->serialPort->write(array);
  326. char OrderArray[8];
  327. OrderArray[0]=0x01;
  328. OrderArray[1]=0x03;
  329. OrderArray[2]=0x17;
  330. OrderArray[3]=0x70;
  331. OrderArray[4]=0x00;
  332. OrderArray[5]=0x02;
  333. OrderArray[6]=0xC0;
  334. OrderArray[7]=0x64;
  335. // 创建一个JNI环境并调用Java静态方法
  336. QAndroidJniEnvironment env;
  337. jbyteArray byteArray = env->NewByteArray(sizeof(OrderArray));
  338. env->SetByteArrayRegion(byteArray, 0, sizeof(OrderArray), reinterpret_cast<const jbyte*>(OrderArray));
  339. QAndroidJniObject sendbacktring = QAndroidJniObject::callStaticObjectMethod(
  340. "usb/USBListActivity",
  341. "writeData",
  342. "([B)Ljava/lang/String;", // 方法签名:接收字节数组并返回字符串
  343. byteArray // 参数
  344. );
  345. QString recsendinfo=sendbacktring.toString();
  346. // 发送字节计数并显示
  347. if(recsendinfo!="")
  348. {
  349. // 发送字节计数
  350. sendNum += 1;
  351. // 状态栏显示计数值
  352. setNumOnLabel(lblSendNum, "S: ", sendNum);
  353. QString hexString;
  354. QByteArray byteArray = recsendinfo.toLatin1(); // 将 QString 转换为 QByteArray,使用 UTF-8 编码
  355. for (char byte : byteArray) {
  356. // 使用 printf 格式化输出或 qDebug() 输出每个字节的十六进制表示
  357. hexString += QString("%1 ").arg(static_cast<unsigned char>(byte), 2, 16, QChar('0'));
  358. }
  359. ui->send_Edit_3->insertPlainText(hexString+"\n");
  360. }
  361. else
  362. {
  363. ui->send_Edit_3->insertPlainText("发送失败!!!!!\n");
  364. }
  365. on_Read_PDUStatus();
  366. }
  367. }
  368. void MainWidget::on_Button_clearrecive_clicked()
  369. {
  370. on_Read_PDUStatus();
  371. }
  372. void MainWidget::on_Button_cleartx_clicked()
  373. {
  374. ui->send_Edit_3->clear();
  375. ui->recive_Edit_4->clear();
  376. // 清除发送、接收字节计数
  377. sendNum = 0;
  378. recvNum = 0;
  379. // 状态栏显示计数值
  380. setNumOnLabel(lblSendNum, "S: ", sendNum);
  381. setNumOnLabel(lblRecvNum, "R: ", recvNum);
  382. }
  383. void MainWidget::on_check_autosend_stateChanged(int arg1)
  384. {
  385. // 获取复选框状态,未选为0,选中为2
  386. if(arg1 == 0){
  387. timSend->stop();
  388. // 时间输入框恢复可选
  389. ui->spin_sendtime_4->setEnabled(true);
  390. }else{
  391. // 对输入的值做限幅,小于10ms会弹出对话框提示
  392. if(ui->spin_sendtime_4->text().toInt() >= 10){
  393. timSend->start(ui->spin_sendtime_4->text().toInt());// 设置定时时长,重新计数
  394. // 让时间输入框不可选,避免误操作(输入功能不可用,控件背景为灰色)
  395. ui->spin_sendtime_4->setEnabled(false);
  396. }else{
  397. ui->check_autosend_4->setCheckState(Qt::Unchecked);
  398. QMessageBox::critical(this, "错误提示", "定时发送的最小间隔为 10ms\r\n请确保输入的值 >=10");
  399. }
  400. }
  401. }
  402. void MainWidget::on_Button_checkserial_clicked()
  403. {
  404. ui->serialCB_3->clear();
  405. if(!use_java)
  406. {
  407. //扫描串口设备文件
  408. foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
  409. {
  410. ui->serialCB_3->addItem(info.portName());
  411. }
  412. }
  413. else
  414. {
  415. // 检查USB串口设备
  416. bool findFlag=false;
  417. QAndroidJniObject usbService = QAndroidJniObject::getStaticObjectField("android/content/Context",
  418. "USB_SERVICE",
  419. "Ljava/lang/String;");
  420. if (!usbService.isValid())
  421. {
  422. //logger("fail to get usb service");
  423. return;
  424. }
  425. //QAndroidJniObject appContext = QJniObject(QNativeInterface::QAndroidApplication::context());
  426. QAndroidJniObject activity = QtAndroid::androidActivity();
  427. QAndroidJniObject usbManager = activity.callObjectMethod("getSystemService",
  428. "(Ljava/lang/String;)Ljava/lang/Object;",
  429. usbService.object<jstring>());
  430. if (!usbManager.isValid())
  431. {
  432. //logger("fail to get usb manager");
  433. return;
  434. }
  435. QAndroidJniObject usbDeviceListHashMap = usbManager.callObjectMethod("getDeviceList",
  436. "()Ljava/util/HashMap;");
  437. QAndroidJniObject devListKeySet = usbDeviceListHashMap.callObjectMethod("keySet",
  438. "()Ljava/util/Set;");
  439. QAndroidJniObject devListIter = devListKeySet.callObjectMethod("iterator",
  440. "()Ljava/util/Iterator;");
  441. jint devListSize = usbDeviceListHashMap.callMethod<jint>("size", "()I");
  442. QAndroidJniObject usbDevObj;
  443. QAndroidJniObject usbDevObjIter;
  444. for (int i = 0; i < devListSize; ++i)
  445. {
  446. usbDevObjIter = devListIter.callObjectMethod("next",
  447. "()Ljava/lang/Object;");
  448. usbDevObj = usbDeviceListHashMap.callObjectMethod("get",
  449. "(Ljava/lang/Object;)Ljava/lang/Object;",
  450. usbDevObjIter.object());
  451. m_DevVid = usbDevObj.callMethod<jint>("getVendorId", "()I");
  452. m_DevPid = usbDevObj.callMethod<jint>("getProductId", "()I");
  453. //QAndroidJniObject str((usbDevObj.callMethod<jstring>("getDeviceName", "()Ljava/lang/String;"));
  454. QAndroidJniObject str( usbDevObj.callObjectMethod(
  455. "getDeviceName",
  456. "()Ljava/lang/String;"
  457. ).object<jstring>());
  458. m_DevFile = str.toString();
  459. findFlag=true;
  460. ui->serialCB_3->addItem(m_DevFile);
  461. modifyUsbDeviceXml("device_filter.xml",QString::number(m_DevVid),QString::number(m_DevPid));
  462. }
  463. //if(findFlag) QMessageBox::information(this, "确认", "检测到USB设备:"+m_DevFile);
  464. }
  465. }
  466. void MainWidget::slot_changeDebugMode()
  467. {
  468. int nIndex=ui->stackedWidget_3->currentIndex();
  469. if(nIndex<1)
  470. {
  471. ui->stackedWidget_3->setCurrentIndex(1);
  472. }else
  473. {
  474. ui->stackedWidget_3->setCurrentIndex(0);
  475. }
  476. }
  477. void MainWidget::setNumOnLabel(QLabel *lbl, QString strS, long num)
  478. {
  479. // 标签显示
  480. QString strN;
  481. strN=QString("%1").arg(num);
  482. QString str = strS + strN;
  483. lbl->setText(str);
  484. }
  485. void MainWidget::UpdateStatusInfo()
  486. {
  487. QString strTemp;
  488. //更新传感器及日期时间
  489. //m_PDUAllInfo.Sensor_Temperature=24.5;
  490. //m_PDUAllInfo.Sensor_Humidity=66.72;
  491. // m_PDUAllInfo.Sensor_INTemperature=82.33;
  492. //m_PDUAllInfo.Sensor_OUTTemperature=53.89;
  493. strTemp=QString::number(m_PDUAllInfo.Sensor_Temperature, 'f', 2);
  494. ui->label_temperature->setText(strTemp);
  495. strTemp=QString::number(m_PDUAllInfo.Sensor_Humidity, 'f', 2);
  496. ui->label_humidity->setText(strTemp);
  497. if(!m_PDUAllInfo.Sensor_LeakFlag)
  498. {
  499. ui->label_water->setText("未浸入");
  500. ui->label_water->setStyleSheet("color: rgb(10, 197, 50);");
  501. }
  502. else
  503. {
  504. ui->label_water->setText("浸入");
  505. // 切换颜色
  506. QColor currentColor = ui->label_water->palette().color(QPalette::WindowText);
  507. if (currentColor == Qt::white) {
  508. ui->label_water->setStyleSheet("color: red;");
  509. } else {
  510. ui->label_water->setStyleSheet("color: white;");
  511. }
  512. }
  513. strTemp=QString::number(m_PDUAllInfo.Sensor_INTemperature, 'f', 2);//进液温度
  514. ui->label_INT->setText(strTemp);
  515. strTemp=QString::number(m_PDUAllInfo.Sensor_OUTTemperature, 'f', 2);//出液温度
  516. ui->label_OUTT->setText(strTemp);
  517. QDateTime currentDateTime = QDateTime::currentDateTime();
  518. QDate currentDate = currentDateTime.date();
  519. QTime currentTime = currentDateTime.time();
  520. // 以字符串形式显示当前日期和时间
  521. QString dateString = currentDate.toString("yyyy-MM-dd");
  522. QString timeString = currentTime.toString("HH:mm:ss");
  523. ui->label_Date->setText(dateString);
  524. ui->label_Time->setText(timeString);
  525. //更新总体电源状态
  526. //m_PDUAllInfo.AllVoltage_L1+=0.2;
  527. //m_PDUAllInfo.AllVoltage_L2+=0.6;
  528. //m_PDUAllInfo.AllVoltage_L3+=0.3;
  529. //m_PDUAllInfo.AllCurrent_L1+=0.1;
  530. //m_PDUAllInfo.AllCurrent_L2+=0.2;
  531. //m_PDUAllInfo.AllCurrent_L3+=0.3;
  532. //m_PDUAllInfo.AllPower_L1+=0.01;
  533. //m_PDUAllInfo.AllPower_L2+=0.02;
  534. // m_PDUAllInfo.AllPower_L3+=0.03;
  535. //m_PDUAllInfo.AllConsumption_L1+=0.05;
  536. //m_PDUAllInfo.AllConsumption_L2+=0.09;
  537. //m_PDUAllInfo.AllConsumption_L3+=0.03;
  538. strTemp=QString::number(m_PDUAllInfo.AllVoltage_L1, 'f', 2);
  539. ui->label_V1->setText(strTemp);
  540. strTemp=QString::number(m_PDUAllInfo.AllCurrent_L1, 'f', 2);
  541. ui->label_I1->setText(strTemp);
  542. strTemp=QString::number(m_PDUAllInfo.AllPower_L1, 'f', 2);
  543. //ui->label_P1->setText(strTemp);
  544. strTemp=QString::number(m_PDUAllInfo.AllConsumption_L1, 'f', 2);
  545. //ui->label_C1->setText(strTemp);
  546. strTemp=QString::number(m_PDUAllInfo.AllVoltage_L2, 'f', 2);
  547. ui->label_V2->setText(strTemp);
  548. strTemp=QString::number(m_PDUAllInfo.AllCurrent_L2, 'f', 2);
  549. ui->label_I2->setText(strTemp);
  550. strTemp=QString::number(m_PDUAllInfo.AllPower_L2, 'f', 2);
  551. //ui->label_P2->setText(strTemp);
  552. strTemp=QString::number(m_PDUAllInfo.AllConsumption_L2, 'f', 2);
  553. //ui->label_C2->setText(strTemp);
  554. strTemp=QString::number(m_PDUAllInfo.AllVoltage_L3, 'f', 2);
  555. ui->label_V3->setText(strTemp);
  556. strTemp=QString::number(m_PDUAllInfo.AllCurrent_L3, 'f', 2);
  557. ui->label_I3->setText(strTemp);
  558. strTemp=QString::number(m_PDUAllInfo.AllPower_L3, 'f', 2);
  559. //ui->label_P3->setText(strTemp);
  560. strTemp=QString::number(m_PDUAllInfo.AllConsumption_L3, 'f', 2);
  561. //ui->label_C3->setText(strTemp);
  562. //更新通道信息
  563. /*
  564. for (int i=0;i<64;i++) {
  565. m_PDUCHInfo[i].CHVoltage+=0.432;
  566. m_PDUCHInfo[i].CHPower+=0.343;
  567. m_PDUCHInfo[i].CHCurrent+=0.112;
  568. m_PDUCHInfo[i].CHConsumption+=0.063;
  569. m_PDUCHInfo[i].CHFactor=0.983;
  570. if(i%2==0)m_PDUCHInfo[i].CHStatus=true;
  571. }*/
  572. for (int i=0;i<m_TotalCHNum;i++) {
  573. m_chWidget[i].chid=i+1;
  574. m_chWidget[i].chV=m_PDUCHInfo[i].CHVoltage;
  575. m_chWidget[i].chI=m_PDUCHInfo[i].CHCurrent;
  576. m_chWidget[i].chStatus=m_PDUCHInfo[i].CHStatus;
  577. m_chWidget[i].UpdateStatusInfo();
  578. }
  579. }
  580. void MainWidget::requestUsbPermission(const QString &devicePath)
  581. {
  582. QAndroidJniObject activity = QtAndroid::androidActivity();
  583. if (!activity.isValid()) {
  584. qDebug() << "Failed to get Android activity.";
  585. return;
  586. }
  587. QAndroidJniObject context = activity.callObjectMethod("getApplicationContext", "()Landroid/content/Context;");
  588. if (!context.isValid()) {
  589. qDebug() << "Failed to get application context.";
  590. return;
  591. }
  592. // Get the USB manager from the system service.
  593. QAndroidJniObject usbServiceName = QAndroidJniObject::getStaticObjectField(
  594. "android/content/Context",
  595. "USB_SERVICE",
  596. "Ljava/lang/String;"
  597. );
  598. QAndroidJniObject usbManager = context.callObjectMethod(
  599. "getSystemService",
  600. "(Ljava/lang/String;)Ljava/lang/Object;",
  601. usbServiceName.object<jstring>());
  602. if (!usbManager.isValid()) {
  603. qDebug() << "Failed to get UsbManager.";
  604. return;
  605. }
  606. // Find the USB device by its path.
  607. QAndroidJniObject usbDevice = usbManager.callObjectMethod(
  608. "getDeviceList",
  609. "()Ljava/util/HashMap;"
  610. ).callObjectMethod(
  611. "get",
  612. "(Ljava/lang/Object;)Ljava/lang/Object;",
  613. QAndroidJniObject::fromString(devicePath).object<jobject>()
  614. );
  615. if (!usbDevice.isValid()) {
  616. qDebug() << "USB device not found: " << devicePath;
  617. QMessageBox::information(this, "确认", "USB device not found: " + devicePath);
  618. return;
  619. }
  620. // Check if we already have permission for this device.
  621. bool hasPermission = QAndroidJniObject::callStaticMethod<jboolean>(
  622. "android/hardware/usb/UsbManager",
  623. "hasPermission",
  624. "(Landroid/hardware/usb/UsbDevice;)Z",
  625. usbDevice.object<jobject>());
  626. if (hasPermission) {
  627. qDebug() << "USB device opened successfully.";
  628. //QMessageBox::information(this, "确认", "USB device opened successfully: " + devicePath);
  629. } else {
  630. qDebug() << "Requesting permission for USB device.";
  631. //QMessageBox::information(this, "确认", "Requesting permission for USB device: " + devicePath);
  632. // Create a PendingIntent to receive the result of the permission request.
  633. QAndroidJniObject intentFilter = QAndroidJniObject::fromString("com.example.ACTION_USB_PERMISSION");
  634. QAndroidJniObject intent("android/content/Intent", "(Ljava/lang/String;)V", intentFilter.object<jstring>());
  635. QAndroidJniObject pendingIntent = QAndroidJniObject::callStaticObjectMethod("android/app/PendingIntent",
  636. "getBroadcast",
  637. "(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;",
  638. context.object<jobject>(),
  639. 0,
  640. intent.object<jobject>(),
  641. 0x00000080); // FLAG_MUTABLE or FLAG_IMMUTABLE based on your target SDK
  642. usbManager.callMethod<void>("requestPermission",
  643. "(Landroid/hardware/usb/UsbDevice;Landroid/app/PendingIntent;)V",
  644. usbDevice.object<jobject>(),
  645. pendingIntent.object<jobject>());
  646. }
  647. }
  648. bool MainWidget::modifyUsbDeviceXml(const QString &filePath, const QString &newVendorId, const QString &newProductId)
  649. {
  650. QFile file(filePath);
  651. if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
  652. qWarning() << "Failed to open file for reading:" << file.errorString();
  653. return false;
  654. }
  655. // 读取文件内容到QDomDocument
  656. QDomDocument doc;
  657. if (!doc.setContent(&file)) {
  658. qWarning() << "Failed to parse XML file:" << file.errorString();
  659. file.close();
  660. return false;
  661. }
  662. file.close();
  663. // 查找<usb-device>元素并修改其属性
  664. QDomElement root = doc.firstChildElement("resources");
  665. QDomElement usbDevice = root.firstChildElement("usb-device");
  666. if (!usbDevice.isNull()) {
  667. usbDevice.setAttribute("vendor-id", newVendorId);
  668. usbDevice.setAttribute("product-id", newProductId);
  669. } else {
  670. qWarning() << "No <usb-device> element found in the XML file.";
  671. return false;
  672. }
  673. // 将修改后的内容写回文件
  674. if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
  675. qWarning() << "Failed to open file for writing:" << file.errorString();
  676. return false;
  677. }
  678. QTextStream out(&file);
  679. out << doc.toString(4); // 使用4个空格进行缩进,以便格式化输出
  680. file.close();
  681. return true;
  682. }
  683. QString MainWidget::on_Read_PDUStatus()
  684. {
  685. // 如接收成功,会返回接收的字符串,失败返回空字符串
  686. QString Allrecinfo="";
  687. for (int i=0;i<10;i++)
  688. {
  689. QAndroidJniObject recbacktring = QAndroidJniObject::callStaticObjectMethod(
  690. "usb/USBListActivity",
  691. "readData",
  692. "()Ljava/lang/String;");
  693. QString recinfo=recbacktring.toString();
  694. // 发送字节计数并显示
  695. if(recinfo!="")
  696. {
  697. QString hexString;
  698. QByteArray byteArray = recinfo.toLatin1(); // 将 QString 转换为 QByteArray,使用 UTF-8 编码
  699. for (char byte : byteArray) {
  700. // 使用 printf 格式化输出或 qDebug() 输出每个字节的十六进制表示
  701. hexString += QString("%1 ").arg(static_cast<unsigned char>(byte), 2, 16, QChar('0'));
  702. }
  703. Allrecinfo+=hexString;
  704. }
  705. else
  706. {
  707. break;
  708. }
  709. }
  710. // 发送字节计数并显示
  711. if(Allrecinfo!="")
  712. {
  713. // 发送字节计数
  714. recvNum += 1;
  715. // 状态栏显示计数值
  716. setNumOnLabel(lblRecvNum, "R: ", recvNum);
  717. ui->recive_Edit_4->insertPlainText(Allrecinfo+"\n");
  718. }
  719. else
  720. {
  721. //ui->recive_Edit_4->insertPlainText("接收失败!!!!!\n");
  722. }
  723. return Allrecinfo;
  724. }
  725. void MainWidget::on_add_PDUStatus(const QString &sendstr, const QString &recstr)
  726. {
  727. // 发送字节计数并显示
  728. if(sendstr!="")
  729. {
  730. // 发送字节计数
  731. sendNum += 1;
  732. // 状态栏显示计数值
  733. setNumOnLabel(lblSendNum, "S: ", sendNum);
  734. ui->send_Edit_3->insertPlainText(sendstr+"\n");
  735. }
  736. else
  737. {
  738. //ui->send_Edit_3->insertPlainText("发送失败!!!!!\n");
  739. }
  740. // 接收字节计数并显示
  741. if(recstr!="")
  742. {
  743. // 发送字节计数
  744. recvNum += 1;
  745. // 状态栏显示计数值
  746. setNumOnLabel(lblRecvNum, "R: ", recvNum);
  747. ui->recive_Edit_4->insertPlainText(recstr+"\n");
  748. }
  749. else
  750. {
  751. //ui->recive_Edit_4->insertPlainText("接收失败!!!!!\n");
  752. }
  753. }
  754. void MainWidget::on_check_autoprintf_stateChanged(int arg1)
  755. {
  756. // 获取复选框状态,未选为0,选中为2
  757. if(arg1 == 0){
  758. m_printflag=false;
  759. }else{
  760. m_printflag=true;
  761. }
  762. }