You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

432 lines
14 KiB

2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
1 year ago
1 year ago
1 year ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #include "mainwindow.h"
  2. #include <QDateTime>
  3. #include <QMessageBox>
  4. #include <QtConcurrent>
  5. #include <QtCore/QVariant>
  6. #include <QtSerialPort/QSerialPort>
  7. #include <QtSerialPort/QSerialPortInfo>
  8. #include <QtWidgets/QLineEdit>
  9. #include "./ui_mainwindow.h"
  10. #include "iflytop_canbus/iflytop_canbus_master.hpp"
  11. #include "logger.hpp"
  12. #include "qt_serial_datachannel.hpp"
  13. #include "zexception.hpp"
  14. using namespace std;
  15. using namespace iflytop;
  16. using namespace zcr;
  17. typedef enum {
  18. kone_lead_ecg,
  19. kthree_lead_ecg,
  20. } device_type_t;
  21. static MainWindow *m_mainWindow;
  22. static QTDataChannel G_QTDataChannel;
  23. static QTDataChannel G_WaveDataChannel;
  24. static device_type_t m_devicetype;
  25. static IflytopCanbusMaster *m_canbusMaster;
  26. QT_REQUIRE_CONFIG(groupbox);
  27. #define TAG "MainWindow"
  28. static const char *fmt(const char *fmt, ...) {
  29. va_list args;
  30. va_start(args, fmt);
  31. static char buf[1024] = {0};
  32. vsnprintf(buf, sizeof(buf), fmt, args);
  33. va_end(args);
  34. return buf;
  35. }
  36. void MainWindow::log_output(QtMsgType type, const QMessageLogContext &context, const QString &msg) {}
  37. void MainWindow::doinui_slot(QFunction func) {
  38. if (func.get()) func.get()();
  39. }
  40. /***********************************************************************************************************************
  41. * PreviewShow *
  42. ***********************************************************************************************************************/
  43. void MainWindow::instructionPreviewShow(const char *fmt, ...) {
  44. va_list args;
  45. va_start(args, fmt);
  46. char buf[1024] = {0};
  47. vsnprintf(buf, sizeof(buf), fmt, args);
  48. va_end(args);
  49. QString text(buf);
  50. QString info;
  51. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz "));
  52. info.append(" |");
  53. info.append(text);
  54. emit doinui_signal(QFunction([this, info]() { ui->instructionPreview->append(info); }));
  55. }
  56. void MainWindow::instructionPreviewClear() { ui->instructionPreview->document()->clear(); }
  57. void MainWindow::reportPreviewShow(const char *fmt, ...) {
  58. va_list args;
  59. va_start(args, fmt);
  60. char buf[1024] = {0};
  61. vsnprintf(buf, sizeof(buf), fmt, args);
  62. va_end(args);
  63. QString text(buf);
  64. QString info;
  65. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz "));
  66. info.append(text);
  67. emit doinui_signal(QFunction([this, info]() {
  68. if (ui->reportPreview->document()->lineCount() > 1000) {
  69. ui->reportPreview->document()->clear();
  70. }
  71. ui->reportPreview->append(info);
  72. }));
  73. }
  74. void MainWindow::blockDataUploadPreviewShow(const char *fmt, ...) {
  75. va_list args;
  76. va_start(args, fmt);
  77. char buf[1024] = {0};
  78. vsnprintf(buf, sizeof(buf), fmt, args);
  79. va_end(args);
  80. QString text(buf);
  81. QString info;
  82. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz "));
  83. info.append(text);
  84. emit doinui_signal(QFunction([this, info]() {
  85. if (ui->uploadDataPreview->document()->lineCount() > 1000) {
  86. ui->uploadDataPreview->document()->clear();
  87. }
  88. ui->uploadDataPreview->append(info);
  89. }));
  90. }
  91. void MainWindow::rawDataPreviewShow(const char *fmt, ...) {
  92. va_list args;
  93. va_start(args, fmt);
  94. char buf[1024] = {0};
  95. vsnprintf(buf, sizeof(buf), fmt, args);
  96. va_end(args);
  97. QString text(buf);
  98. QString info;
  99. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz"));
  100. info.append(text);
  101. emit doinui_signal(QFunction([this, info]() {
  102. if (ui->rawDataPreview->document()->lineCount() > 1000) {
  103. ui->rawDataPreview->document()->clear();
  104. }
  105. ui->rawDataPreview->append(info);
  106. }));
  107. }
  108. // uploadDataPreview
  109. #pragma pack(push, 1)
  110. typedef struct {
  111. uint16_t header;
  112. int16_t wave1;
  113. int16_t wave2;
  114. int16_t wave3;
  115. int16_t wave4;
  116. int16_t wave5;
  117. uint8_t check;
  118. uint16_t tail;
  119. } Wave_t;
  120. #pragma pack(pop)
  121. void MainWindow::displayWave(int16_t wave1, int16_t wave2, int16_t wave3) {
  122. // 1. 生成波形数据
  123. Wave_t wave;
  124. wave.header = 0xAAAA;
  125. wave.wave1 = wave1;
  126. wave.wave2 = wave2;
  127. wave.wave3 = wave3;
  128. wave.wave4 = 0;
  129. wave.wave5 = 0;
  130. wave.tail = 0x5555;
  131. wave.check = 0;
  132. uint8_t check = 0;
  133. for (size_t i = 2; i < sizeof(wave) - 2; i++) {
  134. check += ((uint8_t *)&wave)[i];
  135. }
  136. wave.check = check;
  137. // 2. 发送波形数据
  138. G_WaveDataChannel.send((uint8_t *)&wave, sizeof(wave));
  139. }
  140. /***********************************************************************************************************************
  141. * UI相关构造 *
  142. ***********************************************************************************************************************/
  143. void MainWindow::constructBaseUI() {
  144. /**
  145. * @brief UI
  146. */
  147. {
  148. const auto infos = QSerialPortInfo::availablePorts();
  149. for (const QSerialPortInfo &info : infos) {
  150. ui->serialPortCB->addItem(info.portName());
  151. }
  152. }
  153. ui->serialBaudrateCB->addItem("9600");
  154. ui->serialBaudrateCB->addItem("14400");
  155. ui->serialBaudrateCB->addItem("19200");
  156. ui->serialBaudrateCB->addItem("38400");
  157. ui->serialBaudrateCB->addItem("57600");
  158. ui->serialBaudrateCB->addItem("115200");
  159. ui->serialBaudrateCB->addItem("460800");
  160. ui->serialBaudrateCB->addItem("500000");
  161. ui->serialBaudrateCB->addItem("2000000");
  162. ui->serialBaudrateCB->setCurrentIndex(6);
  163. connect(ui->serialPortRefreshKey, &QPushButton::clicked, this, [this](bool check) {
  164. ui->serialPortCB->clear();
  165. const auto infos = QSerialPortInfo::availablePorts();
  166. for (const QSerialPortInfo &info : infos) {
  167. ui->serialPortCB->addItem(info.portName());
  168. }
  169. });
  170. connect(ui->serialOpenKey, &QPushButton::clicked, this, [=](bool check) {
  171. // 打开串口
  172. if (ui->serialOpenKey->text() == "打开") {
  173. G_QTDataChannel.setPortName(ui->serialPortCB->currentText().toStdString());
  174. G_QTDataChannel.setBaudRate(ui->serialBaudrateCB->currentText().toInt());
  175. G_QTDataChannel.setDataBits(QSerialPort::Data8);
  176. G_QTDataChannel.setParity(QSerialPort::NoParity);
  177. G_QTDataChannel.setFlowControl(QSerialPort::NoFlowControl);
  178. G_QTDataChannel.setStopBits(QSerialPort::OneStop);
  179. /**
  180. * @brief
  181. */
  182. if (!G_QTDataChannel.open()) {
  183. QMessageBox::about(NULL, "提示", "串口无法打开,串口不存在或已被占??");
  184. return;
  185. }
  186. ui->serialOpenKey->setText("关闭");
  187. // 下拉菜单控件使能
  188. ui->serialBaudrateCB->setEnabled(false);
  189. ui->serialPortCB->setEnabled(false);
  190. ui->serialPortRefreshKey->setEnabled(false);
  191. IflytopCanbusMaster::ins()->updateChannelConfig();
  192. } else {
  193. G_QTDataChannel.close();
  194. ui->serialOpenKey->setText("打开");
  195. ui->serialBaudrateCB->setEnabled(true);
  196. ui->serialPortCB->setEnabled(true);
  197. ui->serialPortRefreshKey->setEnabled(true);
  198. }
  199. });
  200. /**
  201. * @brief UI
  202. */
  203. {
  204. const auto infos = QSerialPortInfo::availablePorts();
  205. for (const QSerialPortInfo &info : infos) {
  206. ui->waveSerialPortCB->addItem(info.portName());
  207. }
  208. }
  209. ui->waveSerialBaudrateCB->addItem("9600");
  210. ui->waveSerialBaudrateCB->addItem("14400");
  211. ui->waveSerialBaudrateCB->addItem("19200");
  212. ui->waveSerialBaudrateCB->addItem("38400");
  213. ui->waveSerialBaudrateCB->addItem("57600");
  214. ui->waveSerialBaudrateCB->addItem("115200");
  215. ui->waveSerialBaudrateCB->addItem("460800");
  216. ui->waveSerialBaudrateCB->addItem("500000");
  217. ui->waveSerialBaudrateCB->addItem("2000000");
  218. // ui->waveSerialBaudrateCB->addItems
  219. ui->waveSerialBaudrateCB->setCurrentIndex(6);
  220. connect(ui->waveSerialPortRefreshKey, &QPushButton::clicked, this, [this](bool check) {
  221. ui->waveSerialPortCB->clear();
  222. const auto infos = QSerialPortInfo::availablePorts();
  223. for (const QSerialPortInfo &info : infos) {
  224. ui->waveSerialPortCB->addItem(info.portName());
  225. }
  226. });
  227. connect(ui->waveSerialOpenKey, &QPushButton::clicked, this, [=](bool check) {
  228. // 打开串口
  229. if (ui->waveSerialOpenKey->text() == "打开") {
  230. G_WaveDataChannel.setPortName(ui->waveSerialPortCB->currentText().toStdString());
  231. G_WaveDataChannel.setBaudRate(ui->waveSerialBaudrateCB->currentText().toInt());
  232. G_WaveDataChannel.setDataBits(QSerialPort::Data8);
  233. G_WaveDataChannel.setParity(QSerialPort::NoParity);
  234. G_WaveDataChannel.setFlowControl(QSerialPort::NoFlowControl);
  235. G_WaveDataChannel.setStopBits(QSerialPort::OneStop);
  236. if (!G_WaveDataChannel.open()) {
  237. QMessageBox::about(NULL, "提示", "串口无法打开,串口不存在或已被占??");
  238. return;
  239. }
  240. ui->waveSerialOpenKey->setText("关闭");
  241. // 下拉菜单控件使能
  242. ui->waveSerialBaudrateCB->setEnabled(false);
  243. ui->waveSerialPortCB->setEnabled(false);
  244. ui->waveSerialPortRefreshKey->setEnabled(false);
  245. } else {
  246. G_WaveDataChannel.close();
  247. ui->waveSerialOpenKey->setText("打开");
  248. ui->waveSerialBaudrateCB->setEnabled(true);
  249. ui->waveSerialPortCB->setEnabled(true);
  250. ui->waveSerialPortRefreshKey->setEnabled(true);
  251. }
  252. });
  253. }
  254. void MainWindow::displayInfo(bool suc, QString info) {}
  255. /***********************************************************************************************************************
  256. * *
  257. ***********************************************************************************************************************/
  258. /**
  259. * @brief
  260. *
  261. * +TAB---------------------------------+
  262. * |---BOX---------------------------|
  263. * | |Button|Param|Param| |
  264. * | |Button|Param|Param| |
  265. * | |Button|Param|Param| |
  266. * |---------------------------------|
  267. * |---BOX---------------------------|
  268. * | |Button|Param|Param| |
  269. * | |Button|Param|Param| |
  270. * | |Button|Param|Param| |
  271. * |---------------------------------|
  272. *
  273. *
  274. */
  275. QWidget *MainWindow::allocNewTab(QString zh_name) {
  276. QWidget *newtab = new QWidget();
  277. QVBoxLayout *verticalLayout = new QVBoxLayout(newtab); // 设置布局
  278. newtab->setLayout(verticalLayout);
  279. // 添加Tab
  280. ui->buttonTabWidget->addTab(newtab, QString());
  281. ui->buttonTabWidget->setTabText(ui->buttonTabWidget->indexOf(newtab), zh_name);
  282. return newtab;
  283. }
  284. void MainWindow::endAllocNewTab(QWidget *tab) {
  285. QVBoxLayout *layout = qobject_cast<QVBoxLayout *>(tab->layout());
  286. layout->addItem(new QSpacerItem(20, 445, QSizePolicy::Minimum, QSizePolicy::Expanding));
  287. }
  288. QGroupBox *MainWindow::allocNewBox(QWidget *tab, QString zh_name, int column) {
  289. QVBoxLayout *tablayout = qobject_cast<QVBoxLayout *>(tab->layout());
  290. QGroupBox *groupBox = new QGroupBox(tab); // 创建BOX
  291. QGridLayout *gridLayout = new QGridLayout(groupBox); // 创建布局
  292. groupBox->setLayout(gridLayout); // 设置布局
  293. gridLayout->setColumnMinimumWidth(column, column);
  294. tablayout->addWidget(groupBox);
  295. return groupBox;
  296. }
  297. void MainWindow::endAllocNewBox(QGroupBox *box) { //
  298. QGridLayout *layout = qobject_cast<QGridLayout *>(box->layout());
  299. QSpacerItem *verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
  300. layout->addItem(verticalSpacer, layout->rowCount(), 0, 1, 1);
  301. }
  302. void MainWindow::addNewButtonStyle1(QWidget *box, QString zh_name, QStringList params, std::function<void(int argn, const char **args)> onButtonClick) { //
  303. QGridLayout *layout = qobject_cast<QGridLayout *>(box->layout());
  304. int rowcnt = layout->rowCount();
  305. QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
  306. sizePolicy.setHorizontalStretch(1);
  307. sizePolicy.setVerticalStretch(0);
  308. QPushButton *button = new QPushButton(box);
  309. button->setText(zh_name);
  310. button->setMinimumHeight(30);
  311. button->setSizePolicy(sizePolicy);
  312. layout->addWidget(button, rowcnt, 0, 1, 1);
  313. QList<QLineEdit *> lineEdits;
  314. for (int i = 0; i < params.size(); i++) {
  315. QLineEdit *lineEdit = new QLineEdit(box);
  316. lineEdit->setMinimumHeight(30);
  317. // lineEdit->sizePolicy().setHorizontalStretch(1);
  318. lineEdit->setSizePolicy(sizePolicy);
  319. lineEdit->setPlaceholderText(params[i]);
  320. lineEdits.push_back(lineEdit);
  321. layout->addWidget(lineEdit, rowcnt, i + 1, 1, 1);
  322. }
  323. connect(button, &QPushButton::clicked, this, [onButtonClick, lineEdits, this]() {
  324. vector<string> params;
  325. for (int i = 0; i < lineEdits.size(); i++) {
  326. params.push_back(lineEdits[i]->text().toStdString());
  327. }
  328. char *args[params.size()];
  329. for (int i = 0; i < params.size(); i++) {
  330. args[i] = (char *)params[i].c_str();
  331. }
  332. try {
  333. onButtonClick(params.size(), (const char **)args);
  334. } catch (const std::zexception &e) {
  335. processException(e);
  336. }
  337. });
  338. }
  339. MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
  340. /**
  341. * @brief QT初始化
  342. */
  343. ui->setupUi(this);
  344. m_mainWindow = this;
  345. qRegisterMetaType<int32_t>("int32_t");
  346. qRegisterMetaType<uint32_t>("uint32_t");
  347. qRegisterMetaType<float>("float");
  348. qRegisterMetaType<function<void()>>("function<void()>");
  349. qRegisterMetaType<QFunction>("QFunction");
  350. connect(this, SIGNAL(doinui_signal(QFunction)), this, SLOT(doinui_slot(QFunction)));
  351. /**
  352. * @brief
  353. */
  354. constructBaseUI();
  355. constructAppUI();
  356. /**
  357. * @brief
  358. */
  359. G_QTDataChannel.init();
  360. G_WaveDataChannel.init();
  361. IflytopCanbusMaster::ins()->initialize(&G_QTDataChannel);
  362. }
  363. MainWindow::~MainWindow() { delete ui; }
  364. void MainWindow::processException(const zexception &e) { //
  365. instructionPreviewShow("%s", e.what());
  366. }
  367. void MainWindow::constructAppUI() {
  368. {
  369. QWidget *tab = allocNewTab("模块操作");
  370. {
  371. QGroupBox *box = allocNewBox(tab, "模块基础操作", 4);
  372. addNewButtonStyle1(box, "扫描模块", {"deviceId"}, [](int argn, const char **args) { //
  373. IflytopCanbusMaster::ins()->callcmd(atoi(args[0]), kmodule_ping);
  374. });
  375. endAllocNewBox(box);
  376. }
  377. endAllocNewTab(tab);
  378. }
  379. }