mainwindow.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include <QVBoxLayout>
  4. #include <QHBoxLayout>
  5. #include <QSplitter>
  6. #include <QListView>
  7. #include <QTableView>
  8. #include <QHeaderView>
  9. #include <QDateTime>
  10. #include <QDebug>
  11. #include <QItemSelectionModel>
  12. #include <QtCharts/QDateTimeAxis>
  13. #include <QtCharts/QValueAxis>
  14. #include <QMessageBox>
  15. MainWindow::MainWindow(QWidget *parent)
  16. : QMainWindow(parent),
  17. ui(new Ui::MainWindow),
  18. m_busCore(new SoftBusCore(this)),
  19. m_serialManager(new SerialManager(m_busCore, this)),
  20. m_dataTable(new QTableView(this)),
  21. m_serial_settingsModel(new QStandardItemModel(this)),
  22. m_deviceModel(new QStandardItemModel(this)),
  23. m_dataModel(new QStandardItemModel(this)),
  24. m_dataSeries(new QLineSeries())
  25. {
  26. ui->setupUi(this);
  27. // 初始化系统
  28. initializeSystem();
  29. // 创建UI
  30. createUI();
  31. // 创建连接
  32. createConnections();
  33. // 启动串口监控
  34. m_serialManager->startDiscovery();
  35. // 更新设备列表
  36. updateDeviceList();
  37. }
  38. MainWindow::~MainWindow()
  39. {
  40. // 停止串口监控
  41. m_serialManager->stopDiscovery();
  42. }
  43. void MainWindow::initializeSystem()
  44. {
  45. // 初始化数据库
  46. if (!m_busCore->initDB("raw_db", "bus_db"))
  47. {
  48. qCritical() << "Failed to initialize database";
  49. }
  50. // 注册串口设备
  51. foreach (const QString &portName, m_serialManager->getAvailablePorts())
  52. {
  53. DeviceInfo device;
  54. device.id = portName;
  55. device.type = "serial";
  56. device.address = portName;
  57. device.protocol = "modbus"; // 默认协议
  58. m_busCore->registerDevice(device);
  59. }
  60. }
  61. void MainWindow::createUI()
  62. {
  63. // 左侧设备列表
  64. ui->listV_device->setModel(m_deviceModel);
  65. // 右侧数据表格(上方为配置表格 ,下方为图表) )
  66. ui->tableV_serial_set->setModel(m_serial_settingsModel);
  67. ui->tableV_serial_set->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
  68. m_serial_settingsModel->setHorizontalHeaderLabels({"参数", "值"});
  69. SerialManager::SerialConfig config = m_serialManager->getSerialConfig();
  70. QList<QStandardItem *> baudRateRow;
  71. baudRateRow << new QStandardItem("波特率") << new QStandardItem(QString::number(config.baudRate));
  72. m_serial_settingsModel->appendRow(baudRateRow);
  73. QList<QStandardItem *> dataBitsRow;
  74. dataBitsRow << new QStandardItem("数据位") << new QStandardItem(QString::number(config.dataBits));
  75. m_serial_settingsModel->appendRow(dataBitsRow);
  76. QList<QStandardItem *> parityRow;
  77. parityRow << new QStandardItem("校验") << new QStandardItem(QString::number(config.parity));
  78. m_serial_settingsModel->appendRow(parityRow);
  79. QList<QStandardItem *> stopBitsRow;
  80. stopBitsRow << new QStandardItem("停止位") << new QStandardItem(QString::number(config.stopBits));
  81. m_serial_settingsModel->appendRow(stopBitsRow);
  82. QList<QStandardItem *> flowControlRow;
  83. flowControlRow << new QStandardItem("流控") << new QStandardItem(QString::number(config.flowControl));
  84. m_serial_settingsModel->appendRow(flowControlRow);
  85. // Raw Data Table
  86. ui->tableV_raw_data->setModel(m_dataModel);
  87. m_dataModel->setHorizontalHeaderLabels({"时间", "来源", "协议", "数据"});
  88. ui->tableV_raw_data->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
  89. ui->tableV_raw_data->setEditTriggers(QAbstractItemView::NoEditTriggers);
  90. ui->tableV_raw_data->setSelectionBehavior(QAbstractItemView::SelectRows);
  91. ui->tableV_raw_data->setSelectionMode(QAbstractItemView::SingleSelection);
  92. // ui->tableV_bus_data->setModel();
  93. }
  94. void MainWindow::createConnections()
  95. {
  96. // 设备注册/注销信号
  97. connect(m_busCore, &SoftBusCore::deviceRegistered, this, &MainWindow::updateDeviceList);
  98. connect(m_busCore, &SoftBusCore::deviceUnregistered, this, &MainWindow::updateDeviceList);
  99. // 总线消息存储信号
  100. connect(m_busCore, &SoftBusCore::busMessageStored, this, &MainWindow::updateChart);
  101. // 设备选择信号
  102. connect(ui->listV_device->selectionModel(), &QItemSelectionModel::currentChanged,this, &MainWindow::onDeviceSelected);
  103. // 串口管理器信号
  104. connect(m_serialManager, &SerialManager::portDiscovered, this, [this](const QString &portName, const QString &desc)
  105. {
  106. Q_UNUSED(desc);
  107. updateDeviceList(); });
  108. connect(m_serialManager, &SerialManager::portRemoved, this, [this](const QString &portName)
  109. { updateDeviceList(); });
  110. connect(m_serialManager, &SerialManager::dataReceived, this, &MainWindow::onSerialDataReceived);
  111. }
  112. void MainWindow::updateDeviceList()
  113. {
  114. m_deviceModel->clear();
  115. // 添加串口设备
  116. foreach (const QString &portName, m_serialManager->getAvailablePorts())
  117. {
  118. QStandardItem *item = new QStandardItem("串口: " + portName);
  119. item->setData(portName, Qt::UserRole);
  120. m_deviceModel->appendRow(item);
  121. }
  122. // 添加其他类型设备(CAN、以太网等)
  123. // ...
  124. }
  125. void MainWindow::onDeviceSelected(const QModelIndex &index)
  126. {
  127. if (index.isValid())
  128. {
  129. // 显示设备相关数据
  130. QString deviceId = index.data(Qt::UserRole).toString();
  131. m_currentDeviceId = deviceId;
  132. m_serialManager->openSerialPort(QSerialPortInfo(deviceId));
  133. showRawData(deviceId);
  134. showBusMessages(deviceId);
  135. }
  136. }
  137. void MainWindow::showRawData(const QString &deviceId)
  138. {
  139. m_dataModel->removeRows(0, m_dataModel->rowCount());
  140. // 查询最近10分钟的原始数据
  141. qint64 endTime = QDateTime::currentMSecsSinceEpoch();
  142. qint64 startTime = endTime - 10 * 60 * 1000;
  143. QList<QByteArray> rawData = m_busCore->queryRawData(deviceId, startTime, endTime);
  144. for (const QByteArray &data : rawData)
  145. {
  146. QList<QStandardItem *> row;
  147. // 时间戳是数据的前8个字节
  148. qint64 timestamp = *reinterpret_cast<const qint64 *>(data.constData());
  149. row << new QStandardItem(QDateTime::fromMSecsSinceEpoch(timestamp).toString("hh:mm:ss"));
  150. row << new QStandardItem(deviceId);
  151. row << new QStandardItem("RAW");
  152. row << new QStandardItem(data.mid(8).toHex());
  153. m_dataModel->appendRow(row);
  154. }
  155. }
  156. void MainWindow::showBusMessages(const QString &source)
  157. {
  158. // 查询最近10分钟的总线消息
  159. qint64 endTime = QDateTime::currentMSecsSinceEpoch();
  160. qint64 startTime = endTime - 10 * 60 * 1000;
  161. QList<BusMessage> messages = m_busCore->queryBusMessages(source, "data_processor", startTime, endTime);
  162. for (const BusMessage &msg : messages)
  163. {
  164. QList<QStandardItem *> row;
  165. row << new QStandardItem(QDateTime::fromMSecsSinceEpoch(msg.timestamp).toString("hh:mm:ss"));
  166. row << new QStandardItem(msg.source);
  167. row << new QStandardItem(msg.payload["protocol"].toString());
  168. QString dataStr;
  169. if (msg.payload["protocol"] == "modbus")
  170. {
  171. dataStr = QString("ID:%1 FN:%2")
  172. .arg(msg.payload["slave_id"].toInt())
  173. .arg(msg.payload["function_code"].toInt());
  174. }
  175. else
  176. {
  177. dataStr = msg.payload["raw_data"].toString();
  178. }
  179. row << new QStandardItem(dataStr);
  180. m_dataModel->appendRow(row);
  181. }
  182. }
  183. void MainWindow::updateChart(const BusMessage &message)
  184. {
  185. if (message.payload["protocol"] != "modbus")
  186. return;
  187. // 解析Modbus数据并更新图表
  188. QJsonArray dataArray = message.payload["data"].toArray();
  189. if (dataArray.size() > 0)
  190. {
  191. double value = dataArray[0].toDouble();
  192. qint64 timestamp = message.timestamp;
  193. m_dataSeries->append(timestamp, value);
  194. // 限制图表显示的数据点数量
  195. if (m_dataSeries->count() > 100)
  196. {
  197. m_dataSeries->removePoints(0, m_dataSeries->count() - 100);
  198. }
  199. }
  200. }
  201. // btn_fun
  202. // QCheckBox *checkBox_serial_hex;
  203. // QCheckBox *checkBox_serial_ascii;
  204. // QTextEdit *textEdit_serial;
  205. // QPushButton *btn_serial_clear;
  206. // QPushButton *btn_serial_send;
  207. void MainWindow::on_btn_serial_clear_clicked()
  208. {
  209. ui->textEdit_serial->clear();
  210. }
  211. void MainWindow::on_btn_serial_clear_send_clicked()
  212. {
  213. ui->lineEdit_serial_send->clear();
  214. }
  215. // 发送串口数据
  216. void MainWindow::on_btn_serial_send_clicked()
  217. {
  218. if (!m_serialManager->isPortOpen(m_currentDeviceId)) {
  219. QMessageBox::warning(this, "串口未打开", "请先打开串口设备");
  220. return;
  221. }
  222. QString dataToSend = ui->lineEdit_serial_send->text();
  223. if (dataToSend.isEmpty()) {
  224. QMessageBox::information(this, "发送数据", "请输入要发送的数据");
  225. return;
  226. }
  227. // 根据当前显示模式处理数据
  228. if (ui->checkBox_serial_hex->isChecked()) {
  229. // 十六进制模式 - 将输入视为十六进制字符串
  230. QByteArray hexData = QByteArray::fromHex(dataToSend.toLatin1());
  231. m_serialManager->writeData(m_currentDeviceId,hexData);
  232. } else {
  233. // ASCII模式 - 直接发送文本
  234. m_serialManager->writeData(m_currentDeviceId,dataToSend.toUtf8());
  235. }
  236. // 在接收区显示发送的数据(带发送标记)
  237. QString timestamp = QDateTime::currentDateTime().toString("[hh:mm:ss]");
  238. ui->textEdit_serial->append(QString("<span style='color:blue;'>%1 [发送] %2</span>")
  239. .arg(timestamp)
  240. .arg(dataToSend));
  241. // 清空发送输入框
  242. // ui->lineEdit_serial_send->clear();
  243. }
  244. // 处理接收到的串口数据
  245. void MainWindow::onSerialDataReceived(const QString &portName, const QByteArray &data)
  246. {
  247. QString displayData;
  248. QString timestamp = QDateTime::currentDateTime().toString("[hh:mm:ss]");
  249. if (ui->checkBox_serial_hex->isChecked()) {
  250. // 十六进制显示
  251. displayData = data.toHex(' ').toUpper();
  252. } else {
  253. // ASCII显示
  254. displayData = QString::fromUtf8(data);
  255. // 替换控制字符为可见表示
  256. displayData.replace('\r', "\\r");
  257. displayData.replace('\n', "\\n");
  258. displayData.replace('\t', "\\t");
  259. }
  260. ui->textEdit_serial->append(QString("<span style='color:green;'>%1 串口%2 [接收] %3</span>")
  261. .arg(timestamp)
  262. .arg(portName)
  263. .arg(displayData));
  264. }
  265. // 切换显示模式
  266. void MainWindow::on_checkBox_serial_hex_toggled(bool checked)
  267. {
  268. ui->checkBox_serial_ascii->setChecked(!checked);
  269. // 重新显示当前内容
  270. QString currentText = ui->textEdit_serial->toPlainText();
  271. ui->textEdit_serial->clear();
  272. ui->textEdit_serial->setText(currentText);
  273. }
  274. void MainWindow::on_checkBox_serial_ascii_toggled(bool checked)
  275. {
  276. ui->checkBox_serial_hex->setChecked(!checked);
  277. // 重新显示当前内容
  278. QString currentText = ui->textEdit_serial->toPlainText();
  279. ui->textEdit_serial->clear();
  280. ui->textEdit_serial->setText(currentText);
  281. }