Merge branch 'shiyi' 合并搜救载荷功能,mainwindow优化

pull/3/head
shiyi 7 months ago
commit c9e7f83451

6
.gitignore vendored

@ -8,3 +8,9 @@ app/
=======
*.tmp
>>>>>>> Stashed changes
/.qm/
/.qtc_clangd/
/debug/
/release/
/.idea/
/.vscode/

@ -1,8 +1,10 @@
QT += core gui webenginewidgets
QT += network
QT += quickwidgets qml
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# CONFIG += console
QMAKE_PROJECT_DEPTH = 0
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
@ -24,7 +26,9 @@ SOURCES += \
homepagedlg.cpp \
main.cpp \
mainwindow.cpp \
qweb.cpp
qweb.cpp \
rescueload.cpp \
rescueloadwidget.cpp
HEADERS += \
DCFrameCkCmd.h \
@ -40,7 +44,9 @@ HEADERS += \
global.h \
homepagedlg.h \
mainwindow.h \
qweb.h
qweb.h \
rescueload.h \
rescueloadwidget.h
FORMS += \
Src/GDDC/gddcCmdDlg.ui \
@ -50,7 +56,8 @@ FORMS += \
Src/GDDC/gddcdlg.ui \
homepagedlg.ui \
mainwindow.ui \
qweb.ui
qweb.ui \
rescueloadwidget.ui
TRANSLATIONS += \
PayloadAPP_zh_CN.ts
@ -63,9 +70,11 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
mainwindow.qrc
mainwindow.qrc \
map/places_map.qrc
DISTFILES += \
config.ini \
res/Qss/qss.qss \
style.qss

@ -22,10 +22,10 @@
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
<enum>QSizePolicy::Policy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -36,7 +36,7 @@
</spacer>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<widget class="QWidget" name="image" native="true">
<property name="toolTip">
<string/>
</property>
@ -54,10 +54,10 @@
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
<enum>QSizePolicy::Policy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>

@ -33,7 +33,7 @@ MainWindow::MainWindow(QWidget *parent)
QString style = QLatin1String(file.readAll());
qApp->setStyleSheet(style);
qDebug()<<style;
// qDebug()<<style;
file.close();
}
else
@ -70,20 +70,21 @@ void MainWindow::initWindow()
m_GDDCdlg = new GDDCdlg(this);
m_HomePagedlg = new HomePageDlg(this);
m_rescueLoadWidget = new RescueLoadWidget(this);
mWeb = new CWebEngineView();
mWeb->setPage(new CustomWebEnginePage());
mWeb->load(QUrl("http://192.168.150.1"));
// mWeb = new QWebEngineView(this);
// 设置栈窗口,多页面共享同一窗口
ui->stackedWidget->addWidget(mWeb);
ui->stackedWidget->addWidget(m_GDDCdlg);
ui->stackedWidget->addWidget(m_HomePagedlg);
ui->stackedWidget->addWidget(m_rescueLoadWidget);
ui->SubPage->addWidget(mWeb);
ui->SubPage->addWidget(m_GDDCdlg);
ui->SubPage->addWidget(m_HomePagedlg);
// mWeb->show();
mWeb->hide();
m_HomePagedlg->hide();
m_HomePagedlg->show();
// 初始栈窗口显示主页
ui->stackedWidget->setCurrentWidget(m_HomePagedlg);
}
void MainWindow::initButton()
@ -234,9 +235,7 @@ void MainWindow::toolButton_clicked()
{
changeBtnColor(1);
//m_HomePagedlg->move(130,80);
m_HomePagedlg->show(); //显示窗口
m_GDDCdlg->hide();
mWeb->hide();
ui->stackedWidget->setCurrentWidget(m_HomePagedlg);
process->kill();
}
//光电吊舱
@ -245,27 +244,24 @@ void MainWindow::toolButton_2_clicked()
changeBtnColor(2);
//m_GDDCdlg->move(130,80);
m_GDDCdlg->show(); //显示窗口
m_HomePagedlg->hide();
mWeb->hide();
ui->stackedWidget->setCurrentWidget(m_GDDCdlg);
}
//L链
void MainWindow::toolButton_3_clicked()
{
changeBtnColor(3);
mWeb->show();
m_HomePagedlg->hide();
m_GDDCdlg->hide();
// mWeb->load(QUrl("http://192.168.1.10"));
ui->stackedWidget->setCurrentWidget(mWeb);
}
//自组网
void MainWindow::toolButton_4_clicked()
{
changeBtnColor(4);
m_HomePagedlg->hide();
m_GDDCdlg->hide();
mWeb->load(QUrl("http://192.168.1.10"));
mWeb->show();
// mWeb->load(QUrl("http://192.168.1.10"));
// mWeb->show();
ui->stackedWidget->setCurrentWidget(mWeb);
//process->kill();
}
@ -273,23 +269,18 @@ void MainWindow::toolButton_4_clicked()
void MainWindow::toolButton_5_clicked()
{
changeBtnColor(5);
m_HomePagedlg->hide();
m_GDDCdlg->hide();
mWeb->load(QUrl("http://192.168.150.1"));
mWeb->show();
// mWeb->load(QUrl("http://192.168.150.1"));
// mWeb->show();
ui->stackedWidget->setCurrentWidget(mWeb);
}
//Ku卫通
void MainWindow::toolButton_6_clicked()
{
changeBtnColor(6);
m_HomePagedlg->hide();
m_GDDCdlg->hide();
mWeb->load(QUrl("http://192.168.0.2"));
mWeb->show();
// mWeb->load(QUrl("http://192.168.0.2"));
// mWeb->show();
ui->stackedWidget->setCurrentWidget(mWeb);
}
@ -297,21 +288,14 @@ void MainWindow::toolButton_6_clicked()
void MainWindow::toolButton_7_clicked()
{
changeBtnColor(7);
m_HomePagedlg->hide();
m_GDDCdlg->hide();
// mWeb->stop();
mWeb->load(QUrl("https://baidu.com"));
mWeb->show();
//
ui->stackedWidget->setCurrentWidget(m_rescueLoadWidget);
}
//三维建模
void MainWindow::toolButton_8_clicked()
{
changeBtnColor(8);
m_HomePagedlg->hide();
m_GDDCdlg->hide();
ui->stackedWidget->setCurrentWidget(mWeb);
process->setWorkingDirectory("D:/QTdemo/playerApp/app"); // 设置工作目录
process->start("D:/QTdemo/playerApp/app/XCOM V2.0.exe"); // 启动exe并传递参数
}

@ -4,7 +4,7 @@
#include <QMainWindow>
#include "Src/GDDC/gddcdlg.h"
#include "homepagedlg.h"
#include "rescueloadwidget.h"
#include <QPushButton>
#include <QLabel>
#include <QAction>
@ -52,8 +52,10 @@ private slots:
public:
GDDCdlg *m_GDDCdlg;
HomePageDlg *m_HomePagedlg;
RescueLoadWidget *m_rescueLoadWidget;
//QWeb *m_qWeb;
QWebEngineView *mWeb;
private:
QProcess *process;
QString exeDirPathName = "";

@ -178,6 +178,30 @@
</layout>
</widget>
</item>
<item row="2" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QStackedWidget" name="stackedWidget">
<widget class="QWidget" name="Page1">
<layout class="QVBoxLayout" name="SubPage"/>
</widget>
</widget>
</item>
</layout>
</item>
<item row="3" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="statusBar">

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

@ -0,0 +1,201 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
//! [Imports]
import QtQuick
import QtPositioning
import QtLocation
//! [Imports]
MapView {
anchors.fill: parent
id: mapview
//! [Initialize Plugin]
map.plugin: Plugin {
id: myPlugin
name: "osm"
//specify plugin parameters if necessary
PluginParameter {
name: "osm.mapping.providersrepository.disabled"
value: "true"
}
PluginParameter {
name: "osm.mapping.providersrepository.address"
value: "http://maps-redirect.qt.io/osm/5.6/"
}
//PluginParameter {...}
//...
}
map.activeMapType: map.supportedMapTypes[map.supportedMapTypes.length - 2]
map.center: QtPositioning.coordinate(30.67, 120.07)
map.zoomLevel: 10
// map.activeMapType: MapType.HybridMap
// map.onSupportedMapTypesChanged: {
// map.activeMapType = map.supportedMapTypes[map.supportedMapTypes.length - 1]
// }
// Component.onCompleted: {console.log(map.supportedMapTypes)}
//
// signal locationClicked(string imsi)
signal indexClicked(int row)
MapItemView {
id: itemview
parent: mapview.map
// model: testModel
model: imsiDataModel
z:2
delegate: MapQuickItem {
id: location
// property bool isSelected: false //
property string imsi: model.imsi
property double latitude: model.latitude
property double longitude: model.longitude
coordinate: QtPositioning.coordinate(latitude, longitude)
//
anchorPoint.x: image.width * 0.5
anchorPoint.y: image.height
sourceItem: Item {
width: image.width
height: image.height
Image {
id: image
source: "marker"
property double imageWidth: 20
property double imageHeight: 25
width: itemMouse.containsMouse ? imageWidth*1.25 : imageWidth
height: itemMouse.containsMouse ? imageHeight*1.25: imageHeight
Text {
anchors.centerIn: parent
text: (model.row + 1)
font.pixelSize: image.width*0.5
color: "black"
horizontalAlignment: Text.AlignRight //
verticalAlignment: Text.AlignBottom //
}
}
MouseArea {
id: itemMouse
anchors.fill: parent
hoverEnabled: true
propagateComposedEvents: true
cursorShape: Qt.PointingHandCursor
onClicked: {
indexClicked(model.row)
}
}
}
}
}
//
ListModel {
id: listSelectModel
}
MapItemView {
parent: mapview.map
// model: testModel
model: listSelectModel
z:3
delegate: MapQuickItem { //
z: itemview.z + 1
// property string imsi: model.imsi
property double latitude: model.latitude
property double longitude: model.longitude
property string imagesource: "selectlocation.png"
property bool selected: true
coordinate: QtPositioning.coordinate(latitude, longitude)
//
anchorPoint.x: selectimgae.width * 0.5
anchorPoint.y: selectimgae.height
sourceItem: Item {
Image {
id: selectimgae
source: imagesource
property double imageWidth: 30
property double imageHeight: 30
width: imageWidth
height: imageHeight
}
}
}
}
// //
Connections {
target: imsiSelectModel
function onSelectionChanged (selected, deselected) {
var indexs = imsiSelectModel.selectedIndexes
// if (indexs.length === 0) {
listSelectModel.clear()
// }
for (var i=0; i<indexs.length; i++){
if (indexs[i].column === 0) {
listSelectModel.append({
"latitude": imsiDataModel.data(indexs[i], imsiDataModel.getRole("latitude")), // 258
"longitude": imsiDataModel.data(indexs[i], imsiDataModel.getRole("longitude")) //257
});// 258);
}
}
}
}
// Connections {
// target: imsiDataModel
// function onDetailUpdated (imsi, longitude, latitude){
// listSelectModel.clear()
// listSelectModel.append({"imsi":imsi, "latitude": latitude, "longitude": longitude});
// console.log(listSelectModel.length)
// }
// }
// MouseArea {
// anchors.fill: parent
// hoverEnabled: false
// propagateComposedEvents: true
// onClicked: {
// listSelectModel.clear()
// mouse.accepted()
// }
// }
//
HoverHandler {
// MouseAreahover
id: mapHoverHandler
acceptedDevices: PointerDevice.Mouse
onPointChanged: {
var position = mapview.map.toCoordinate(point.position)
coordinatesDisplay.latitude = position.latitude
coordinatesDisplay.longitude = position.longitude
}
}
Rectangle {
id: coordinatesDisplay
width: 270
height: 20
anchors.right: parent.right
anchors.bottom: parent.bottom
color: "transparent" //
property double latitude
property double longitude
Text {
anchors.centerIn: parent
text: "Latitude: " + parent.latitude.toFixed(
7) + " Longitude: " + parent.longitude.toFixed(7)
color: "black"
horizontalAlignment: Text.AlignRight //
verticalAlignment: Text.AlignBottom //
}
}
}

@ -0,0 +1,8 @@
<RCC>
<qresource prefix="/">
<file>marker.png</file>
<file>places_map.qml</file>
<file>selectlocation.png</file>
</qresource>
<qresource prefix="/map"/>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -200,8 +200,7 @@ QFrame#frameGDDCPage
QTableView
{
color: rgb(255, 255, 255);
font-family:"微软雅黑";
font-size:9pt;
font: 12pt "Microsoft YaHei UI";
border:none;
background-color: rgba(50, 50, 50, 50); /*rgba(150, 223, 155, 50)*/
selection-background-color: rgba(96, 96, 96, 0); /*选中区域的背景色,设置成透明96,96,96*/
@ -215,7 +214,7 @@ QTableWidget::item {
/*设置单元格背景颜色*/
QTableWidget::item:selected
{
/*background-color:#CCFFE5;*/
background-color:#CCFFE5;
}
/*设置表头背景颜色、角落颜色*/
QHeaderView::section,QTableCornerButton:section
@ -232,7 +231,7 @@ QHeaderView::section,QTableCornerButton:section
}
QHeaderView::section:checked
{
background-color: rgb(96, 96, 96 );
background-color: rgb(11, 11, 11);
}
/*设置表格中的水平线和垂直线*/
QTableWidget::horizontalHeader

@ -0,0 +1,358 @@
#include "rescueload.h"
#include <QDateTime>
#include <QDir>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMessageBox>
// ==================== ImsiData数据类 start =======================
QHash<QString, QString> ImsiData::operatorMap = {
{"00", "移动"}, {"02", "移动"}, {"04", "移动"}, {"07", "移动"}, {"08", "移动"}, {"13", "移动"},
{"01", "联通"}, {"06", "联通"}, {"09", "联通"}, {"10", "联通"},
{"03", "电信"}, {"05", "电信"}, {"11", "电信"}, {"12", "电信"},
{"15", "广电"}, {"20","铁通"}
};
ImsiData::ImsiData(const QJsonObject& json)
{
if (json.contains("latitude"))
this->latitude = json.value("latitude").toString();
if (json.contains("longitude"))
this->longitude = json.value("longitude").toString();
if (json.contains("altitude"))
this->altitude = json.value("altitude").toInt();
if (json.contains("create_date"))
this->createDate = json.value("create_date").toString();
if (json.contains("rssi"))
this->rssi = json.value("rssi").toInt();
if (json.contains("fcn"))
this->fcn = json.value("fcn").toString();
if (json.contains("imsi"))
this->imsi = json.value("imsi").toString();
this->operatorName = getOperatorNameByImsi(this->imsi); // 第4、5位
}
ImsiData::ImsiData(const ImsiData& from)
{
this->latitude = from.latitude;
this->longitude = from.longitude;
this->altitude = from.altitude;
this->createDate = from.createDate;
this->rssi = from.rssi;
this->fcn = from.fcn;
this->imsi = from.imsi;
this->operatorName = from.operatorName;
}
QString ImsiData::getOperatorNameByImsi(QString imsi)
{
return operatorMap.value(imsi.mid(3,2));
}
// ==================== ImsiData数据类 end =======================
// ===================== ImsiTableModel start ==================================
ImsiTableModel::ImsiTableModel(QObject *parent)
: QAbstractTableModel(parent)
{
// Set names to the role name hash container (QHash<int, QByteArray>)
// model.name, model.hue, model.saturation, model.brightness
m_roleNames[imsiRole] = "imsi";
m_roleNames[latitudeRole] = "latitude";
m_roleNames[longitudeRole] = "longitude";
m_roleNames[dateRole] = "createDate";
m_roleNames[altitudeRole] = "altitude";
m_roleNames[rssiRole] = "rssi";
m_roleNames[fcnRole] = "fcn";
m_roleNames[operatorRole] = "operator";
m_horizontalHeader = {"IMSI", "运营商"};
m_defaultDir = QString("./搜救信息"); // 默认目录
// 检查并创建默认目录
QDir dir(m_defaultDir);
if (!dir.exists()) {
dir.mkpath(".");
}
}
ImsiTableModel::~ImsiTableModel()
{
QString timeStr = QDateTime::currentDateTime().toString("yyyy-MM-ddThh-mm-ss");
QString defaultPath = QString("%1/搜救信息%2.csv").arg(getSaveDir(), timeStr);
saveDataListToCsv(defaultPath);
}
QVariant ImsiTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(orientation == Qt::Horizontal) { //水平表头
if(Qt::DisplayRole == role && section < m_horizontalHeader.count()) {
return m_horizontalHeader[section];
}
}
return QAbstractItemModel::headerData(section,orientation,role);
}
int ImsiTableModel::rowCount(const QModelIndex &parent) const
{
// For list models only the root node (an invalid parent) should return the list's size. For all
// other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
Q_UNUSED(parent)
return m_dataMap.count();
}
int ImsiTableModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return 2;
}
QVariant ImsiTableModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
int column = index.column();
int row = index.row();
QString imsi = m_imsiList.at(row);
ImsiData data = m_dataMap.value(imsi);
switch (role) {
case Qt::DisplayRole:
if (column == 1) {
return data.operatorName;
} else if (column == 0) {
return data.imsi;
}
break;
// 对齐处理
case Qt::TextAlignmentRole:
return Qt::AlignCenter;
break;
case imsiRole:
return data.imsi;
case latitudeRole:
return data.latitude;
case longitudeRole:
return data.longitude;
case dateRole:
return data.createDate;
case altitudeRole:
return data.altitude;
case rssiRole:
return data.rssi;
case fcnRole:
return data.fcn;
default:
break;
}
return QVariant();
}
QModelIndex ImsiTableModel::index(int row, int column, const QModelIndex &parent) const
{
if (parent.isValid() || row < 0 || column < 0 || row >= rowCount() || column >= columnCount())
return QModelIndex();
// Create and return a QModelIndex for the given row and column
return createIndex(row, column);
}
void ImsiTableModel::setDataMap(const QHash<QString, ImsiData> &dataMap)
{
beginResetModel();
this->m_dataMap = dataMap;
this->m_imsiList = dataMap.keys();
for (int i = 0; i < m_imsiList.size(); ++i) {
m_imsiIndex.insert(m_imsiList[i], i);
}
endResetModel();
}
void ImsiTableModel::updateData(const ImsiData &data)
{
QString imsi = data.imsi;
if (m_dataMap.contains(imsi)) {
// 更新现有数据
m_dataMap[imsi] = data;
int row = m_imsiIndex.value(imsi);
emit dataChanged(index(row, 0), index(row, columnCount() - 1));
} else {
// 插入新数据
beginInsertRows(QModelIndex(), m_imsiList.size(), m_imsiList.size());
m_imsiList.append(imsi);
m_dataMap.insert(imsi, data);
endInsertRows();
}
}
int ImsiTableModel::getRole(QString rolename)
{
if (rolename == "latitude")
return latitudeRole;
else if (rolename == "longitude")
return longitudeRole;
else
return -1;
}
QHash<int, QByteArray> ImsiTableModel::roleNames() const
{
return m_roleNames;
}
void ImsiTableModel::saveDataListToCsv(const QString& filePath, const QString& delimiter) {
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qWarning("Could not open file for writing.");
return;
}
QTextStream out(&file);
QStringList row;
row << "IMSI" << "运营商" << "经度" << "纬度" << "海拔高度" << "频点" << "强度" << "记录时间"; // CSV header
out << row.join(delimiter) << "\n";
for (const QString& imsi : m_imsiList) {
row.clear();
ImsiData data = m_dataMap.value(imsi);
row << data.imsi
<< data.operatorName
<< data.longitude
<< data.latitude
<< QString::number(data.altitude)
<< data.fcn
<< QString::number(data.rssi)
<< data.createDate;
out << row.join(delimiter) << "\n";
}
file.close();
}
// ======================= ImsiTableModel end=====================
// ======================= RescuLoad start===========================
RescueLoad::RescueLoad(QObject *parent)
:QObject(parent), remoteIp("10.10.10.50"), remotePort(8056)
{
// remoteIp = "127.0.0.1";
}
RescueLoad::~RescueLoad() {}
void RescueLoad::startCommunication()
{
udpSocket = new QUdpSocket(this);
connect(udpSocket, &QUdpSocket::readyRead, this, &RescueLoad::readData);
}
void RescueLoad::sendMessage(const QString &message)
{
QByteArray datagram = message.toUtf8();
udpSocket->writeDatagram(datagram, QHostAddress(remoteIp), remotePort);
}
void RescueLoad::sendMessage(const QByteArray &datagram)
{
udpSocket->writeDatagram(datagram, QHostAddress(remoteIp), remotePort);
}
void RescueLoad::readData()
{
while (udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
// qDebug() << "Received response from" << sender.toString() << ":" << senderPort;
// qDebug() << "Data:" << datagram;
handleMessage(datagram);
}
}
void RescueLoad::handleMessage(const QByteArray &datagram) {
QJsonParseError json_error;
QJsonDocument jsonDoc(QJsonDocument::fromJson(datagram, &json_error));
if(json_error.error != QJsonParseError::NoError || !jsonDoc.isObject()){
qDebug() << "json error!";
return;
}
QJsonObject baseObj = jsonDoc.object();
QJsonValue vType = baseObj.value("type");
QJsonValue vMsg = baseObj.value("msg");
// if (!vType.isDouble() || !vMsg.isString()) return;
int type = vType.toInt();
QString msg = vMsg.toString();
// if ("success" != msg) return;
switch (type) {
case 1: // 4G心跳包
// todo
sendMessage(QString("{\"cmd\": \"heartbeat\"}")); // 定时回心跳,或者单独开定时器
break;
case 2: // 5G心跳包
sendMessage(QString("{\"cmd\": \"heartbeat\"}"));
break;
case 3:{ // IMSI数据
QJsonArray array = baseObj.value("data").toArray();
for (int i = 0; i < array.size(); i++){
QJsonObject json = array.at(i).toObject();
ImsiData data(json);
// ImsiData data;
emit dataUpdate(data);
}
break;
}
default:
break;
}
}
void RescueLoad::syncTime()
{
QString timeStr = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
QJsonObject timeObj;
timeObj.insert("datetime", timeStr);
QJsonObject sendObj;
sendObj.insert("cmd", "syncTime");
sendObj.insert("params", timeObj);
sendMessage(QJsonDocument(sendObj).toJson(QJsonDocument::Compact));
}
/**
* @brief RescueLoad::sendNameList
* @param action: 'reject'/'block'/'reject2lte'/'release2lte', #imsi
* @param type: 'ADD'/'SUB'/'SAVE' #ADD:SUB:SAVE:
* @param wnamelist: IMSI
* @param bnamelist: IMSI
*/
void RescueLoad::sendNameList(const QString action, const QString type, const QList<QString> &wnamelist, const QList<QString> &bnamelist)
{
QJsonObject paramsObj;
paramsObj.insert("action", action);
paramsObj.insert("type", type);
paramsObj.insert("wnamelist", QJsonArray::fromStringList(wnamelist));
paramsObj.insert("bnamelist", QJsonArray::fromStringList(bnamelist));
QJsonObject sendObj;
sendObj.insert("cmd", "msg_set_namelist");
sendObj.insert("params", paramsObj);
sendMessage(QJsonDocument(sendObj).toJson(QJsonDocument::Compact));
}
// ============================ RescueLoad end=================================

@ -0,0 +1,122 @@
#ifndef RESCUELOAD_H
#define RESCUELOAD_H
#include "qjsonarray.h"
#include "qtmetamacros.h"
#include <QObject>
#include <QString>
#include <QUdpSocket>
#include <QAbstractItemModel>
#include <QMouseEvent>
/**
* @brief
* ImsiData:
* ImsiTableModel: Imsi
* RescueLoad:
*/
//搜救载荷移动身份识别码数据
class ImsiData
{
public:
static QHash<QString, QString> operatorMap;
static QString getOperatorNameByImsi(QString imsi);
public:
ImsiData(){};
ImsiData(const QJsonObject& json);
ImsiData(const ImsiData& from);
~ImsiData(){};
public:
QString imsi;
QString operatorName;
QString longitude;
QString latitude;
int altitude; // 海拔高度
QString fcn; // 频点/BAND
int rssi; // 强度
QString createDate;
} /*ImsiData*/;
class ImsiTableModel : public QAbstractTableModel
{
Q_OBJECT
public:
enum RoleNames {
imsiRole = Qt::UserRole,
latitudeRole = Qt::UserRole+2,
longitudeRole = Qt::UserRole+3,
altitudeRole = Qt::UserRole+4,
dateRole = Qt::UserRole+5,
rssiRole = Qt::UserRole+6,
fcnRole = Qt::UserRole+7,
operatorRole = Qt::UserRole+8,
};
public:
explicit ImsiTableModel(QObject *parent = nullptr);
virtual ~ImsiTableModel();
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_INVOKABLE QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override;
void setDataMap(const QHash<QString, ImsiData>& dataMap );
void updateData(const ImsiData &data);
QHash<QString, ImsiData>& getDataMap(){
return m_dataMap;
}
QString getSaveDir() {return m_defaultDir;}
Q_INVOKABLE int getRole(QString);
void saveDataListToCsv(const QString &filePath, const QString &delimiter = ",");
signals:
void detailUpdated(QString, double, double);
protected:
// return the roles mapping to be used by QML
virtual QHash<int, QByteArray> roleNames() const override;
private:
QHash<QString, ImsiData> m_dataMap; // 用于存储数据不需要排序时用QHash即可
QList<QString> m_imsiList; // 用于同步TableView的行索引
QHash<QString, int> m_imsiIndex; // 用于更新数据时获取行索引
QHash<int, QByteArray> m_roleNames;
QStringList m_horizontalHeader;
QString m_defaultDir;
};
class RescueLoad: public QObject
{
Q_OBJECT
public:
RescueLoad(QObject *parent);
~RescueLoad();
// udp通信
public:
void startCommunication(); // 在工作线程中运行
void sendMessage(const QString &message);
void sendMessage(const QByteArray &datagram);
void syncTime();
void sendNameList(const QString action, const QString type, const QList<QString> &wnamelist, const QList<QString> &bnamelist);
signals:
void dataUpdate(ImsiData data);
private slots:
void readData();
public :
QString remoteIp;
int remotePort;
private:
QUdpSocket* udpSocket;
void handleMessage(const QByteArray &datagram);
};
#endif // RESCUELOAD_H

@ -0,0 +1,363 @@
#include "rescueloadwidget.h"
#include <QQuickWidget>
#include "qjsonarray.h"
#include "ui_rescueloadwidget.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QQuickView>
#include <QUrl>
#include <QRandomGenerator>
#include <QTextBlock>
#include <QtQml>
#include <QQmlContext>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include <QFileDialog>
#include <QMessageBox>
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, [=](ImsiData data){
imsiDataModel->updateData(data);
});
// 地图组件, 必须在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->rootContext()->setContextProperty("imsiSelectModel", ui->deviceview->selectionModel()); // 注意先绑定属性再设置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()<<"搜救地图开启"<<imsiDataModel->getDataMap().keys().size();
// 接收QML的信号
QObject* object = (QObject* )qmlView->rootObject();
// connect(object, SIGNAL(locationClicked(QString)), this, SLOT(updateDetailTable(QString)));
QObject::connect(object, SIGNAL(indexClicked(int)), this, SLOT(tableIndexClicked(int)));
}
void RescueLoadWidget::tableIndexClicked(int row){
// qDebug()<<row;
emit ui->deviceview->clicked(imsiDataModel->index(row));
}
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;
if (tableView == ui->deviceview){
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; i<deviceDetail->rowCount(); i++) {
QTableWidgetItem *item = protoItem->clone();
deviceDetail->setItem(i, 0, item);
}
deviceDetail->show();
qDebug() << "设备详细信息初始化完成";
}
// 更新指定imsi的详细信息
void RescueLoadWidget::updateDetailTable(const QString imsi)
{
const QHash<QString, ImsiData>& dataMap = imsiDataModel->getDataMap();
if (!dataMap.contains(imsi)) return;
ImsiData data = imsiDataModel->getDataMap().value(imsi);
// qDebug()<<"更新详细信息start: " << imsi;
emit imsiDataModel->detailUpdated(imsi, data.longitude.toDouble(), data.latitude.toDouble());
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->sendMessage(QString("{\"cmd\": \"heartbeat\"}"));
// 时间同步
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->sendMessage(QString("{\"cmd\": \"heartbeat\"}"));
// 时间同步
rescueLoad->syncTime();
}
slots void RescueLoadWidget::on_stop5G_clicked()
{
rescueLoad->sendMessage(QString("{\"cmd\": \"stopCell_5g\"}"));
}
slots void RescueLoadWidget::on_addblistBtn_clicked()
{
QList<QString> 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<QString>(), namelistToSend);
updateWBnamelist("B", sendType, namelistToSend);
}
slots void RescueLoadWidget::on_addwlistBtn_clicked()
{
QList<QString> 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<QString>());
updateWBnamelist("W", sendType, namelistToSend);
}
/** 获取编辑区的imsi列表*/
QList<QString> RescueLoadWidget::getNameListEditList(){
QTextBlock block = ui->namelistEdit->document()->firstBlock();
QList<QString> 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<QString> &namelistToUpdate)
{
QStandardItemModel *namelistModel = listType=="W"? wnamelistModel: bnamelistModel;
QSet<QString> &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();
}
void RescueLoadWidget::on_ipportBtn_clicked()
{
QString newIp = ui->ipEdit->text().trimmed();
int newPort = ui->portEdit->text().trimmed().toInt();
rescueLoad->remoteIp = newIp;
rescueLoad->remotePort = newPort;
}
void RescueLoadWidget::on_saveFileButton_clicked()
{
QString timeStr = QDateTime::currentDateTime().toString("yyyy-MM-ddThh-mm-ss");
QString defaultPath = QString("%1/搜救信息%2.csv").arg(imsiDataModel->getSaveDir(), timeStr);
QString filePath = QFileDialog::getSaveFileName(this, tr("保存文件"), defaultPath, tr("CSV 文件 (*.csv)"));
qDebug()<< filePath;
if (!filePath.isEmpty()) {
imsiDataModel->saveDataListToCsv(filePath);
}
}

@ -0,0 +1,71 @@
#ifndef RESCUELOADWIDGET_H
#define RESCUELOADWIDGET_H
#include "rescueload.h"
#include <QStandardItem>
#include <QTableWidget>
#include <QWidget>
namespace Ui {
class RescueLoadWidget;
}
// 搜救页面
class RescueLoadWidget : public QWidget
{
Q_OBJECT
public:
explicit RescueLoadWidget(QWidget *parent = nullptr);
~RescueLoadWidget();
private:
Ui::RescueLoadWidget *ui;
QTableWidgetItem *protoItem; // 单元格模版
QStandardItem *standardItem; // 单元格模版
QSet<QString> wnamelist;
QSet<QString> bnamelist;
ImsiTableModel* imsiDataModel;
QStandardItemModel* wnamelistModel;
QStandardItemModel* bnamelistModel;
public:
RescueLoad* rescueLoad;
void initialUi();
void openQLocationMap();
private slots:
void on_start4G_clicked();
void on_stop4G_clicked();
void on_start5G_clicked();
void on_stop5G_clicked();
void on_addwlistBtn_clicked();
void on_addblistBtn_clicked();
void updateDetailTable(const QString imsi);
void tableIndexClicked(int row);
void on_ipportBtn_clicked();
void on_saveFileButton_clicked();
private:
void setDeviceTable(QTableWidget* tableWidget);
void addNewData();
void deleteData();
void syncTime();
void setDeviceDetail(QTableWidget *);
QList<QString> getNameListEditList();
void updateWBnamelist(QString, QString, QList<QString>&);
void setTable(QTableView *tableWidget);
void initialModel();
};
#endif // RESCUELOADWIDGET_H

@ -0,0 +1,726 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RescueLoadWidget</class>
<widget class="QWidget" name="RescueLoadWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1106</width>
<height>684</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="mapGroup">
<property name="minimumSize">
<size>
<width>650</width>
<height>450</height>
</size>
</property>
<property name="title">
<string>搜救信息位置图</string>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>330</width>
<height>250</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>320</width>
<height>300</height>
</size>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="allDevicesTab">
<attribute name="title">
<string>设备检索列表</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPushButton" name="saveFileButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>保存当前检索的设备列表到文件</string>
</property>
</widget>
</item>
<item>
<widget class="QTableView" name="deviceview">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ctrl + C 可复制单元格内容&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">color:black;
background-color:transparent;
</string>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="blackListTab">
<attribute name="title">
<string>黑名单</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QTableView" name="bnameview">
<property name="showGrid">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="whiteListTab">
<attribute name="title">
<string>白名单</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QTableView" name="wnameview">
<property name="showGrid">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>320</width>
<height>275</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>300</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="title">
<string>设备详情</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="topMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QTableWidget" name="deviceDetail">
<property name="minimumSize">
<size>
<width>0</width>
<height>240</height>
</size>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ctrl + C 可复制单元格内容&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="columnCount">
<number>1</number>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>40</number>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>160</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderCascadingSectionResizes">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>25</number>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>30</number>
</attribute>
<attribute name="verticalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
<row>
<property name="text">
<string>设备IMSI</string>
</property>
</row>
<row>
<property name="text">
<string>运营商</string>
</property>
</row>
<row>
<property name="text">
<string>经度</string>
</property>
</row>
<row>
<property name="text">
<string>纬度</string>
</property>
</row>
<row>
<property name="text">
<string>海拔高度</string>
</property>
</row>
<row>
<property name="text">
<string>频点</string>
</property>
</row>
<row>
<property name="text">
<string>强度</string>
</property>
</row>
<row>
<property name="text">
<string>时间</string>
</property>
</row>
<column/>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="minimumSize">
<size>
<width>310</width>
<height>180</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>400</width>
<height>16777215</height>
</size>
</property>
<property name="title">
<string>功能控制</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>13</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>载荷IP:</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="ipEdit">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>10.10.10.50</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>端口:</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="portEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>8056</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ipportBtn">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>修改</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>13</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>13</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="start4G">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>90</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>开启4G功放</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>18</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="start5G">
<property name="minimumSize">
<size>
<width>90</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>开启5G功放</string>
</property>
</widget>
</item>
<item row="0" column="4">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>25</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>13</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="stop4G">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>90</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>停止4G功放</string>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>18</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="stop5G">
<property name="minimumSize">
<size>
<width>90</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>停止5G功放</string>
</property>
</widget>
</item>
<item row="1" column="4">
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>25</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<widget class="QGroupBox" name="groupBox_3">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>370</width>
<height>210</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>220</height>
</size>
</property>
<property name="title">
<string>黑/白名单设置</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<property name="topMargin">
<number>12</number>
</property>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>名单配置模式</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter|Qt::AlignVCenter">
<widget class="QComboBox" name="namelistConfigType">
<property name="minimumSize">
<size>
<width>160</width>
<height>30</height>
</size>
</property>
<item>
<property name="text">
<string>ADD: 增加名单</string>
</property>
</item>
<item>
<property name="text">
<string>SUB: 删除名单</string>
</property>
</item>
<item>
<property name="text">
<string>SAVE: 名单替换</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>137</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="addblistBtn">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>配置黑名单</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addwlistBtn">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>配置白名单</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QPlainTextEdit" name="namelistEdit">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;点击输入IMSI或选择右侧列表项导入&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="styleSheet">
<string notr="true">color:white;
background-color:transparent;
</string>
</property>
<property name="plainText">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
Loading…
Cancel
Save