#include "rescueloadwidget.h" #include #include "qdatetime.h" #include "qjsonarray.h" #include "ui_rescueloadwidget.h" #include #include #include #include #include #include #include #include #include #include RescueLoadWidget::RescueLoadWidget(QWidget *parent) : QWidget(parent) , ui(new Ui::RescueLoadWidget) { ui->setupUi(this); initialModel(); // 初始化数据model initialUi(); // 初始化表格样式 // 数据交互和视图设置 rescueLoad = new RescueLoad(this); rescueLoad->startCommunication(); // todo: 转移到子线程中运行 rescueLoad->sendMessage(QString("Hello")); connect(rescueLoad, &RescueLoad::dataUpdate, rescueLoad, [=](){ imsiDataModel->setDataMap(rescueLoad->getDataMap()); }); // 地图组件, 必须在RescueLoad和ImsiDataModel初始化后加载 openQLocationMap(); } RescueLoadWidget::~RescueLoadWidget() { ui->deviceDetail->clearContents(); delete protoItem; delete standardItem; delete ui; } // 使用QLocation加载地图模块 (fixme: 能显示地图,但是无法向qml传递数据) void RescueLoadWidget::openQLocationMap() { QQuickView *qmlView = new QQuickView(); qmlView->rootContext()->setContextProperty("imsiDataModel", imsiDataModel); // 注意,先绑定属性,再设置qml qmlView->setSource(QUrl("qrc:/places_map.qml")); QWidget *container = QWidget::createWindowContainer(qmlView, this); ui->mapGroup->setLayout(new QVBoxLayout); ui->mapGroup->layout()->addWidget(container); qDebug()<<"搜救地图开启"<getDataMap().keys().size(); // 接收QML的信号 QObject* object = (QObject* )qmlView->rootObject(); connect(object, SIGNAL(locationClicked(QString)), this, SLOT(updateDetailTable(QString))); } void RescueLoadWidget::initialUi() { // 设备imsi列表样式 setTable(ui->deviceview); setTable(ui->bnameview); setTable(ui->wnameview); // 单元格样式 protoItem = new QTableWidgetItem; protoItem->setTextAlignment(Qt::AlignCenter); standardItem = new QStandardItem; standardItem->setTextAlignment(Qt::AlignCenter); QFont font = QFont("Microsoft YaHei UI", 12); protoItem->setFont(font); standardItem->setFont(font); setDeviceDetail(ui->deviceDetail); } void RescueLoadWidget::setTable(QTableView* tableView) { // 设置样式表 tableView->setStyleSheet( "QTableView::item {" " background-color: transparent;" " color: white;" "}" ); QFont font = QFont("Microsoft YaHei UI", 12); tableView->horizontalHeader()->setFont(font); tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // 可拉伸填充 tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter); //表头信息显示居中 tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);//对第2列单独设置固定宽度 tableView->setColumnWidth(1, 100);//设置固定宽度 tableView->verticalHeader()->setFont(font); tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); tableView->verticalHeader()->setDefaultAlignment(Qt::AlignCenter); tableView->verticalHeader()->setFixedWidth(35); // 行表头(序号)设置固定宽度 // tableWidget->verticalHeader()->hide(); //将默认序号隐藏 tableView->setShowGrid(true); tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); // 不可编辑 // 选中行更新详细信息 tableView->setSelectionBehavior(QAbstractItemView::SelectRows); // 选中行 // 单击后选中并显示详情,再次点击取消选中 connect(tableView, &QTableView::clicked, this, [=](QModelIndex index) { static int preRow = -1; // 记录前一个点击事件所在行 int curRow = index.row(); QModelIndex imsiIndex = index.model()->index(curRow, 0); // note 第一列必须为imsi值 QString imsi =tableView->model()->data(imsiIndex).toString(); QItemSelectionModel* selectModel = tableView->selectionModel(); if (curRow == preRow) { // 取消选中状态 if (selectModel->isSelected(index)) { selectModel->select(index, QItemSelectionModel::Deselect | QItemSelectionModel::Rows); preRow = -1; //取消后重置,否则无法选中 return; } } selectModel->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); preRow = curRow; updateDetailTable(imsi); }); // 选中行更新名单编辑区 connect(tableView->selectionModel(), &QItemSelectionModel::selectionChanged, tableView, [=]() { QModelIndexList selectedIndexes = tableView->selectionModel()->selectedIndexes(); QAbstractItemModel* model = tableView->model(); ui->namelistEdit->clear(); QString selectedText; for (const QModelIndex &index : selectedIndexes) { if (index.column() == 0) { selectedText = model->data(index).toString(); ui->namelistEdit->appendPlainText(selectedText.trimmed()); } } ui->namelistEdit->show(); // qDebug() << "选择状态变更: selcted: " << selectedIndexes; }); } void RescueLoadWidget::initialModel() { QStringList headers = QStringList()<<"IMSI"<<"运营商"; wnamelistModel = new QStandardItemModel(this); wnamelistModel->setHorizontalHeaderLabels(headers); wnamelistModel->setColumnCount(2); ui->wnameview->setModel(wnamelistModel); bnamelistModel = new QStandardItemModel(this); bnamelistModel->setHorizontalHeaderLabels(headers); bnamelistModel->setColumnCount(2); ui->bnameview->setModel(bnamelistModel); imsiDataModel = new ImsiTableModel(this); ui->deviceview->setModel(imsiDataModel); } void RescueLoadWidget::setDeviceDetail(QTableWidget* deviceDetail) { // 设备详情表样式 deviceDetail->setStyleSheet( "QTableWidget::item {" " background-color: transparent;" " color: white;" "}" ); deviceDetail->verticalHeader()->setFont(QFont("Microsoft YaHei UI", 12)); deviceDetail->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); deviceDetail->verticalHeader()->setDefaultAlignment(Qt::AlignCenter); deviceDetail->setEditTriggers(QAbstractItemView::NoEditTriggers); // 不可编辑 deviceDetail->setShowGrid(true); // 初始化 for (int i=0; irowCount(); i++) { QTableWidgetItem *item = protoItem->clone(); deviceDetail->setItem(i, 0, item); } deviceDetail->show(); qDebug() << "设备详细信息初始化完成"; } // 更新指定imsi的详细信息 void RescueLoadWidget::updateDetailTable(const QString imsi) { const QMap& dataMap = rescueLoad->getDataMap(); if (!dataMap.contains(imsi)) return; ImsiData data = rescueLoad->getDataMap().value(imsi); qDebug()<<"更新详细信息start: " << imsi; ui->deviceDetail->item(0, 0)->setText(data.imsi); ui->deviceDetail->item(1, 0)->setText(data.operatorName); ui->deviceDetail->item(2, 0)->setText(data.longitude); ui->deviceDetail->item(3, 0)->setText(data.latitude); ui->deviceDetail->item(4, 0)->setText(QString::number(data.altitude)); ui->deviceDetail->item(5, 0)->setText(data.fcn); ui->deviceDetail->item(6, 0)->setText(QString::number(data.rssi)); ui->deviceDetail->item(7, 0)->setText(data.createDate); ui->deviceDetail->show(); qDebug()<<"更新详细信息end: " << imsi; } slots void RescueLoadWidget::on_start4G_clicked() { // 开启4g功放 rescueLoad->sendMessage(QString("{\"cmd\": \"startCell\"}")); // 时间同步 rescueLoad->syncTime(); } slots void RescueLoadWidget::on_stop4G_clicked() { rescueLoad->sendMessage(QString("{\"cmd\": \"stopCell\"}")); } slots void RescueLoadWidget::on_start5G_clicked() { // 开启5g功放 rescueLoad->sendMessage(QString("{\"cmd\": \"startCell_5g\"}")); // 时间同步 rescueLoad->syncTime(); } slots void RescueLoadWidget::on_stop5G_clicked() { rescueLoad->sendMessage(QString("{\"cmd\": \"stopCell_5g\"}")); } slots void RescueLoadWidget::on_addblistBtn_clicked() { QList namelistToSend = getNameListEditList(); // 输入量,用于更新namelist QString type = ui->namelistConfigType->currentText().toUpper(); QString sendType; if (type.startsWith("ADD")) { sendType = "ADD"; } else if (type.startsWith("SUB")) { sendType = "SUB"; } else if (type.startsWith("SAVE")) { sendType = "SAVE"; } else { return; } rescueLoad->sendNameList("block", sendType, QList(), namelistToSend); updateWBnamelist("B", sendType, namelistToSend); } slots void RescueLoadWidget::on_addwlistBtn_clicked() { QList namelistToSend = getNameListEditList(); // 输入量,用于更新namelist QString type = ui->namelistConfigType->currentText().toUpper(); QString sendType; if (type.startsWith("ADD")) { sendType = "ADD"; } else if (type.startsWith("SUB")) { sendType = "SUB"; } else if (type.startsWith("SAVE")) { sendType = "SAVE"; } else { return; } rescueLoad->sendNameList("block", sendType, namelistToSend, QList()); updateWBnamelist("W", sendType, namelistToSend); } /** 获取编辑区的imsi列表*/ QList RescueLoadWidget::getNameListEditList(){ QTextBlock block = ui->namelistEdit->document()->firstBlock(); QList namelist; while (block.isValid()) { QString tmp = block.text().trimmed(); if (! tmp.isEmpty()) { namelist.append(tmp); } block = block.next(); } return namelist; } // 更新黑名单和白名单的数据与显示 void RescueLoadWidget::updateWBnamelist(QString listType, QString sendType, QList &namelistToUpdate) { QStandardItemModel *namelistModel = listType=="W"? wnamelistModel: bnamelistModel; QSet &namelistToShow = listType=="W"? wnamelist : bnamelist; // 更新黑/白名单列表 if (sendType == "ADD") { // 新增 for(const QString &imsi: namelistToUpdate) { namelistToShow.insert(imsi); } } else if (sendType == "SUB") { // 删除 for(const QString &imsi: namelistToUpdate) { namelistToShow.remove(imsi); } } else if (sendType == "SAVE") { // 替换现有在列表 namelistToShow.clear(); for(const QString &imsi: namelistToUpdate) { namelistToShow.insert(imsi); } } // 列表显示更新 namelistModel->clear(); namelistModel->setColumnCount(2); namelistModel->setRowCount(namelistToShow.size()); namelistModel->setHorizontalHeaderLabels(QStringList()<<"IMSI"<<"运营商"); int i = 0; for (const QString &imsi : namelistToShow) { QStandardItem *item1 =standardItem->clone(); QStandardItem *item2 =standardItem->clone(); item1->setText(imsi); item2->setText(ImsiData::getOperatorNameByImsi(imsi)); namelistModel->setItem(i, 0, item1); namelistModel->setItem(i, 1, item2); i ++ ; } qDebug() << "名单数据更新end"<< namelistModel->rowCount(); }