设备详情

hzk
123 3 days ago
parent 10b95148f4
commit 98ef0e33c8

@ -1,5 +1,5 @@
{
"currentState": "memory_saved",
"currentState": "role_activated_with_memory",
"stateHistory": [
{
"from": "initial",
@ -92,7 +92,31 @@
"--tags",
"项目进展 Qt开发 BattlefieldExplorationSystem 设备管理 地图集成 Phase4完成"
]
},
{
"from": "memory_saved",
"command": "init",
"timestamp": "2025-06-21T10:53:24.434Z",
"args": [
{
"workingDirectory": "/home/hzk/Software_Architecture/src/Client"
}
]
},
{
"from": "initialized",
"command": "welcome",
"timestamp": "2025-06-21T10:53:28.298Z",
"args": []
},
{
"from": "role_discovery",
"command": "action",
"timestamp": "2025-06-21T10:53:32.598Z",
"args": [
"qt-ui-developer"
]
}
],
"lastUpdated": "2025-06-19T10:34:01.577Z"
"lastUpdated": "2025-06-21T10:53:32.605Z"
}

@ -4,8 +4,8 @@
"metadata": {
"version": "2.0.0",
"description": "project 级资源注册表",
"createdAt": "2025-06-19T10:21:01.701Z",
"updatedAt": "2025-06-19T10:21:01.702Z",
"createdAt": "2025-06-21T10:53:24.437Z",
"updatedAt": "2025-06-21T10:53:24.439Z",
"resourceCount": 1
},
"resources": [
@ -17,9 +17,9 @@
"description": "专业角色,提供特定领域的专业能力",
"reference": "@project://.promptx/resource/domain/qt-ui-developer/qt-ui-developer.role.md",
"metadata": {
"createdAt": "2025-06-19T10:21:01.701Z",
"updatedAt": "2025-06-19T10:21:01.701Z",
"scannedAt": "2025-06-19T10:21:01.701Z"
"createdAt": "2025-06-21T10:53:24.438Z",
"updatedAt": "2025-06-21T10:53:24.438Z",
"scannedAt": "2025-06-21T10:53:24.438Z"
}
}
],

@ -6,14 +6,539 @@
<rect>
<x>0</x>
<y>0</y>
<width>1184</width>
<height>734</height>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
<string>设备详情</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>8</number>
</property>
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>12</number>
</property>
<item>
<layout class="QHBoxLayout" name="headerLayout">
<property name="spacing">
<number>12</number>
</property>
<item>
<widget class="QLabel" name="deviceIconLabel">
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string>🤖</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="styleSheet">
<string>font-size: 48px;</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="headerInfoLayout">
<property name="spacing">
<number>4</number>
</property>
<item>
<widget class="QLabel" name="deviceNameLabel">
<property name="font">
<font>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>设备名称</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="deviceIdLabel">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>设备ID: DEV001</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="deviceTypeLabel">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>设备类型: 无人机</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="headerSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="deviceStatusLabel">
<property name="minimumSize">
<size>
<width>80</width>
<height>30</height>
</size>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>在线</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="styleSheet">
<string>color: white; background-color: green; border-radius: 15px; padding: 5px;</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="separator">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="basicInfoTab">
<attribute name="title">
<string>基本信息</string>
</attribute>
<layout class="QFormLayout" name="basicInfoLayout">
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="formAlignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
<property name="horizontalSpacing">
<number>12</number>
</property>
<property name="verticalSpacing">
<number>8</number>
</property>
<property name="leftMargin">
<number>16</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>16</number>
</property>
<property name="bottomMargin">
<number>12</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_ip">
<property name="text">
<string>IP地址:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="ipAddressValue">
<property name="text">
<string>192.168.1.100</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_port">
<property name="text">
<string>端口:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="portValue">
<property name="text">
<string>8080</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_location">
<property name="text">
<string>位置坐标:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="locationValue">
<property name="text">
<string>116.40, 39.90</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_signal">
<property name="text">
<string>信号强度:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QProgressBar" name="signalStrengthBar">
<property name="value">
<number>85</number>
</property>
<property name="format">
<string>%p%</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_battery">
<property name="text">
<string>电池电量:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QProgressBar" name="batteryLevelBar">
<property name="value">
<number>95</number>
</property>
<property name="format">
<string>%p%</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_firmware">
<property name="text">
<string>固件版本:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="firmwareValue">
<property name="text">
<string>v2.1.0</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="statusInfoTab">
<attribute name="title">
<string>状态信息</string>
</attribute>
<layout class="QFormLayout" name="statusInfoLayout">
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="formAlignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
<property name="horizontalSpacing">
<number>12</number>
</property>
<property name="verticalSpacing">
<number>8</number>
</property>
<property name="leftMargin">
<number>16</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>16</number>
</property>
<property name="bottomMargin">
<number>12</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_lastHeartbeat">
<property name="text">
<string>最后心跳:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lastHeartbeatValue">
<property name="text">
<string>2024-01-01 12:30:45</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_createdAt">
<property name="text">
<string>创建时间:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="createdAtValue">
<property name="text">
<string>2024-01-01 08:00:00</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_updatedAt">
<property name="text">
<string>更新时间:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="updatedAtValue">
<property name="text">
<string>2024-01-01 12:30:45</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_workingTime">
<property name="text">
<string>运行时长:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="workingTimeValue">
<property name="text">
<string>4小时30分钟</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="operationTab">
<attribute name="title">
<string>操作控制</string>
</attribute>
<layout class="QVBoxLayout" name="operationLayout">
<property name="spacing">
<number>8</number>
</property>
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>12</number>
</property>
<item>
<layout class="QHBoxLayout" name="controlButtonsLayout">
<property name="spacing">
<number>8</number>
</property>
<item>
<widget class="QPushButton" name="connectButton">
<property name="text">
<string>连接</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="disconnectButton">
<property name="text">
<string>断开</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="locateButton">
<property name="text">
<string>定位</string>
</property>
</widget>
</item>
<item>
<spacer name="controlSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="operationLogGroup">
<property name="title">
<string>操作日志</string>
</property>
<layout class="QVBoxLayout" name="logLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>8</number>
</property>
<property name="topMargin">
<number>8</number>
</property>
<property name="rightMargin">
<number>8</number>
</property>
<property name="bottomMargin">
<number>8</number>
</property>
<item>
<widget class="QTableWidget" name="operationLogTable">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<column>
<property name="text">
<string>时间</string>
</property>
</column>
<column>
<property name="text">
<string>操作</string>
</property>
</column>
<column>
<property name="text">
<string>结果</string>
</property>
</column>
<column>
<property name="text">
<string>操作员</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="buttonLayout">
<property name="spacing">
<number>8</number>
</property>
<item>
<spacer name="buttonSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="refreshButton">
<property name="text">
<string>刷新</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="closeButton">
<property name="text">
<string>关闭</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
<connections>
<connection>
<sender>closeButton</sender>
<signal>clicked()</signal>
<receiver>DeviceDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>745</x>
<y>569</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
</connections>
</ui>

@ -2,6 +2,11 @@
#define DEVICEDIALOG_H
#include <QDialog>
#include <QProgressBar>
#include <QTableWidget>
#include <QLabel>
#include <QPushButton>
#include <QTabWidget>
QT_BEGIN_NAMESPACE
namespace Ui {
@ -9,6 +14,11 @@ class DeviceDialog;
}
QT_END_NAMESPACE
/**
* @brief
*
*
*/
class DeviceDialog : public QDialog
{
Q_OBJECT
@ -17,10 +27,130 @@ public:
explicit DeviceDialog(QWidget *parent = nullptr);
~DeviceDialog();
void addDeviceInfo(QString name, QString type, QString status, QString position);
/**
* @brief
* @param deviceId ID
* @param name
* @param type
* @param ip IP
* @param port
* @param longitude
* @param latitude
* @param state
* @param signalStrength
* @param batteryLevel
* @param firmwareVersion
* @param lastHeartbeat
* @param createdAt
* @param updatedAt
*/
void setDeviceInfo(const QString &deviceId, const QString &name, const QString &type,
const QString &ip, int port, double longitude, double latitude,
int state, int signalStrength, int batteryLevel,
const QString &firmwareVersion, const QString &lastHeartbeat,
const QString &createdAt, const QString &updatedAt);
/**
* @brief
* @param deviceId ID
*/
void loadOperationLogs(const QString &deviceId);
/**
* @brief
*/
void refreshDeviceInfo();
public slots:
/**
* @brief
*/
void onConnectClicked();
/**
* @brief
*/
void onDisconnectClicked();
/**
* @brief
*/
void onLocateClicked();
/**
* @brief
*/
void onRefreshClicked();
signals:
/**
* @brief
* @param deviceId ID
*/
void deviceConnectRequested(const QString &deviceId);
/**
* @brief
* @param deviceId ID
*/
void deviceDisconnectRequested(const QString &deviceId);
/**
* @brief
* @param deviceId ID
*/
void deviceLocationRequested(const QString &deviceId);
private:
/**
* @brief UI
*/
void setupStyle();
/**
* @brief
*/
void connectSignals();
/**
* @brief
* @param type
*/
void setDeviceIcon(const QString &type);
/**
* @brief
* @param state
*/
void setStatusLabel(int state);
/**
* @brief
* @param createdTime
* @return
*/
QString calculateWorkingTime(const QString &createdTime);
/**
* @brief
*/
void initializeOperationLogTable();
/**
* @brief
* @param operation
* @param operatorName
*/
void logOperation(const QString &operation, const QString &operatorName);
/**
* @brief
*/
void setHighContrastFonts();
private:
Ui::DeviceDialog *ui;
QString m_currentDeviceId; ///< 当前显示的设备ID
};
#endif // DEVICEDIALOG_H

@ -1,18 +1,52 @@
/**
* @file DeviceDialog.cpp
* @brief
* @author CasualtySightPlus Team
* @date 2024-01-01
* @version 2.0
*/
#include "ui/dialogs/DeviceDialog.h"
#include "build/ui_DeviceDialog.h"
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>
// Qt headers
#include <QMessageBox>
#include <QDateTime>
#include <QTableWidgetItem>
#include <QHeaderView>
#include <QDebug>
#include <QFont>
#include <QPalette>
// Qt SQL headers
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
DeviceDialog::DeviceDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::DeviceDialog)
{
ui->setupUi(this);
setWindowTitle("机器人列表");
setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
setStyleSheet("background-color: rgba(255, 255, 255, 150);"); // 设置透明度为 150 的白色背景
// 设置窗口属性
setWindowTitle("设备详情");
setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
setModal(true);
// 初始化UI样式
setupStyle();
// 连接信号槽
connectSignals();
// 初始化操作日志表格
initializeOperationLogTable();
// 强制设置高对比度字体
setHighContrastFonts();
qDebug() << "DeviceDialog created successfully";
}
DeviceDialog::~DeviceDialog()
@ -20,18 +54,606 @@ DeviceDialog::~DeviceDialog()
delete ui;
}
void DeviceDialog::addDeviceInfo(QString name, QString type, QString status, QString position)
void DeviceDialog::setDeviceInfo(const QString &deviceId, const QString &name, const QString &type,
const QString &ip, int port, double longitude, double latitude,
int state, int signalStrength, int batteryLevel,
const QString &firmwareVersion, const QString &lastHeartbeat,
const QString &createdAt, const QString &updatedAt)
{
m_currentDeviceId = deviceId;
// 设置设备图标
setDeviceIcon(type);
// 设置基本信息
ui->deviceNameLabel->setText(name);
ui->deviceIdLabel->setText(QString("设备ID: %1").arg(deviceId));
QString typeDisplayName = (type == "uav") ? "无人机" :
(type == "dog") ? "地面机器人" : "未知设备";
ui->deviceTypeLabel->setText(QString("设备类型: %1").arg(typeDisplayName));
// 设置状态标签
setStatusLabel(state);
// 定义数值标签的强对比度样式
QString valueStyle = "QLabel {"
" color: rgb(255, 255, 255);" // 纯白色字体
" background: rgba(100, 200, 255, 0.2);"
" border: 1px solid rgba(100, 200, 255, 0.4);"
" border-radius: 4px;"
" padding: 4px 8px;"
" font-weight: bold;"
" font-size: 13px;"
"}";
// 设置网络信息 - 直接应用样式
ui->ipAddressValue->setText(ip);
ui->ipAddressValue->setStyleSheet(valueStyle);
ui->portValue->setText(QString::number(port));
ui->portValue->setStyleSheet(valueStyle);
// 设置位置信息 - 直接应用样式
ui->locationValue->setText(QString("%1, %2").arg(longitude, 0, 'f', 6).arg(latitude, 0, 'f', 6));
ui->locationValue->setStyleSheet(valueStyle);
// 设置信号强度和电池电量
ui->signalStrengthBar->setValue(signalStrength);
ui->batteryLevelBar->setValue(batteryLevel);
// 设置固件版本 - 直接应用样式
ui->firmwareValue->setText(firmwareVersion.isEmpty() ? "未知" : firmwareVersion);
ui->firmwareValue->setStyleSheet(valueStyle);
// 设置时间信息 - 直接应用样式
ui->lastHeartbeatValue->setText(lastHeartbeat.isEmpty() ? "无数据" : lastHeartbeat);
ui->lastHeartbeatValue->setStyleSheet(valueStyle);
ui->createdAtValue->setText(createdAt);
ui->createdAtValue->setStyleSheet(valueStyle);
ui->updatedAtValue->setText(updatedAt);
ui->updatedAtValue->setStyleSheet(valueStyle);
// 计算并设置运行时长 - 直接应用样式
ui->workingTimeValue->setText(calculateWorkingTime(createdAt));
ui->workingTimeValue->setStyleSheet(valueStyle);
// 设置所有标签的样式
QString labelStyle = "QLabel {"
" color: rgb(255, 255, 255);" // 纯白色
" font-weight: 600;"
" font-size: 13px;"
"}";
// 应用到所有标签标题
ui->label_ip->setStyleSheet(labelStyle);
ui->label_port->setStyleSheet(labelStyle);
ui->label_location->setStyleSheet(labelStyle);
ui->label_signal->setStyleSheet(labelStyle);
ui->label_battery->setStyleSheet(labelStyle);
ui->label_firmware->setStyleSheet(labelStyle);
ui->label_lastHeartbeat->setStyleSheet(labelStyle);
ui->label_createdAt->setStyleSheet(labelStyle);
ui->label_updatedAt->setStyleSheet(labelStyle);
ui->label_workingTime->setStyleSheet(labelStyle);
// 设置头部标签样式
QString headerStyle = "QLabel {"
" color: rgb(255, 255, 255);"
" font-weight: bold;"
"}";
ui->deviceNameLabel->setStyleSheet(headerStyle);
ui->deviceIdLabel->setStyleSheet(headerStyle);
ui->deviceTypeLabel->setStyleSheet(headerStyle);
// 加载操作日志
loadOperationLogs(deviceId);
qDebug() << "Device info set for:" << deviceId << name;
}
void DeviceDialog::loadOperationLogs(const QString &deviceId)
{
// 连接数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "DeviceDialog_LogQuery");
db.setHostName("localhost");
db.setPort(3306);
db.setDatabaseName("Client");
db.setUserName("root");
db.setPassword("hzk200407140238");
if (!db.open()) {
qWarning() << "Failed to connect to database for operation logs:" << db.lastError().text();
return;
}
// 查询操作日志
QSqlQuery query(db);
QString sql = "SELECT operation_time, operation, operation_result, operator "
"FROM device_operation_logs "
"WHERE device_id = ? "
"ORDER BY operation_time DESC "
"LIMIT 50";
query.prepare(sql);
query.addBindValue(deviceId);
if (!query.exec()) {
qWarning() << "Failed to query operation logs:" << query.lastError().text();
db.close();
return;
}
// 清空表格
ui->operationLogTable->setRowCount(0);
// 填充数据
int row = 0;
while (query.next()) {
ui->operationLogTable->insertRow(row);
QString operationTime = query.value(0).toString();
QString operation = query.value(1).toString();
QString result = query.value(2).toString();
QString operatorName = query.value(3).toString();
ui->operationLogTable->setItem(row, 0, new QTableWidgetItem(operationTime));
ui->operationLogTable->setItem(row, 1, new QTableWidgetItem(operation));
ui->operationLogTable->setItem(row, 2, new QTableWidgetItem(result));
ui->operationLogTable->setItem(row, 3, new QTableWidgetItem(operatorName.isEmpty() ? "系统" : operatorName));
// 根据操作结果设置颜色
QTableWidgetItem *resultItem = ui->operationLogTable->item(row, 2);
if (result == "success") {
resultItem->setBackground(QBrush(QColor(144, 238, 144))); // 浅绿色
} else if (result == "failed") {
resultItem->setBackground(QBrush(QColor(255, 182, 193))); // 浅红色
} else if (result == "timeout") {
resultItem->setBackground(QBrush(QColor(255, 255, 224))); // 浅黄色
}
row++;
}
db.close();
qDebug() << "Loaded" << row << "operation log entries for device" << deviceId;
}
void DeviceDialog::refreshDeviceInfo()
{
if (m_currentDeviceId.isEmpty()) {
return;
}
// 连接数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "DeviceDialog_Refresh");
db.setHostName("localhost");
db.setPort(3306);
db.setDatabaseName("Client");
db.setUserName("root");
db.setPassword("hzk200407140238");
if (!db.open()) {
qWarning() << "Failed to connect to database for refresh:" << db.lastError().text();
QMessageBox::warning(this, "错误", "无法连接到数据库");
return;
}
// 查询设备信息
QSqlQuery query(db);
QString sql = "SELECT name, device_type, ip, port, longitude, latitude, state, "
"signal_strength, battery_level, firmware_version, last_heartbeat, "
"created_at, updated_at "
"FROM devices WHERE id = ?";
query.prepare(sql);
query.addBindValue(m_currentDeviceId);
if (!query.exec() || !query.next()) {
qWarning() << "Failed to query device info:" << query.lastError().text();
QMessageBox::warning(this, "错误", "无法获取设备信息");
db.close();
return;
}
// 更新设备信息
QString name = query.value("name").toString();
QString type = query.value("device_type").toString();
QString ip = query.value("ip").toString();
int port = query.value("port").toInt();
double longitude = query.value("longitude").toDouble();
double latitude = query.value("latitude").toDouble();
int state = query.value("state").toInt();
int signalStrength = query.value("signal_strength").toInt();
int batteryLevel = query.value("battery_level").toInt();
QString firmwareVersion = query.value("firmware_version").toString();
QString lastHeartbeat = query.value("last_heartbeat").toString();
QString createdAt = query.value("created_at").toString();
QString updatedAt = query.value("updated_at").toString();
db.close();
// 更新显示
setDeviceInfo(m_currentDeviceId, name, type, ip, port, longitude, latitude,
state, signalStrength, batteryLevel, firmwareVersion,
lastHeartbeat, createdAt, updatedAt);
QMessageBox::information(this, "刷新完成", "设备信息已更新");
}
void DeviceDialog::onConnectClicked()
{
if (!m_currentDeviceId.isEmpty()) {
emit deviceConnectRequested(m_currentDeviceId);
// 记录操作日志
logOperation("connect", "用户操作");
}
}
void DeviceDialog::onDisconnectClicked()
{
if (!m_currentDeviceId.isEmpty()) {
emit deviceDisconnectRequested(m_currentDeviceId);
// 记录操作日志
logOperation("disconnect", "用户操作");
}
}
void DeviceDialog::onLocateClicked()
{
if (!m_currentDeviceId.isEmpty()) {
emit deviceLocationRequested(m_currentDeviceId);
// 记录操作日志
logOperation("locate", "用户操作");
}
}
void DeviceDialog::onRefreshClicked()
{
refreshDeviceInfo();
}
void DeviceDialog::setupStyle()
{
// 设置对话框整体样式
setStyleSheet(
"QDialog {"
" background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1,"
" stop:0 rgb(20, 30, 40), stop:1 rgb(30, 40, 50));"
" color: rgb(255, 255, 255);" // 纯白色字体
"}"
// 标签样式 - 最强对比度
"QLabel {"
" color: rgb(255, 255, 255);" // 纯白色
" background: transparent;"
" font-size: 14px;" // 增大字体
" font-weight: 600;" // 加粗
" padding: 3px 6px;" // 适当内边距
"}"
// 表单布局样式 - 更紧凑
"QFormLayout {"
" spacing: 8px;" // 减少行间距
"}"
// 数值标签样式 - 突出显示
"QLabel[class='value-label'] {"
" color: rgb(100, 200, 255);" // 蓝色突出显示数值
" font-weight: 600;"
" background: rgba(100, 200, 255, 0.1);"
" border: 1px solid rgba(100, 200, 255, 0.2);"
" border-radius: 3px;"
" padding: 4px 8px;"
" margin: 1px;"
"}"
// 进度条样式 - 更清晰
"QProgressBar {"
" border: 2px solid rgba(100, 200, 255, 0.4);"
" border-radius: 6px;"
" text-align: center;"
" background-color: rgba(45, 65, 95, 0.4);"
" color: rgb(255, 255, 255);" // 白色文字
" font-weight: bold;"
" font-size: 12px;"
" min-height: 20px;" // 减少高度使更紧凑
" max-height: 20px;"
"}"
"QProgressBar::chunk {"
" background: qlineargradient(x1:0, y1:0, x2:1, y2:0,"
" stop:0 rgba(100, 200, 255, 0.8),"
" stop:1 rgba(50, 150, 255, 1.0));"
" border-radius: 4px;"
"}"
// 按钮样式 - 更清晰
"QPushButton {"
" background: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
" stop:0 rgba(45, 65, 95, 0.9), "
" stop:1 rgba(25, 40, 65, 0.9));"
" color: rgb(255, 255, 255);" // 纯白字体
" border: 2px solid rgba(100, 200, 255, 0.6);"
" padding: 6px 12px;" // 减少按钮内边距
" border-radius: 5px;"
" font-weight: bold;"
" font-size: 12px;"
" min-height: 24px;" // 减少按钮高度
"}"
"QPushButton:hover {"
" background: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
" stop:0 rgba(100, 200, 255, 0.8), "
" stop:1 rgba(45, 120, 180, 0.8));"
" border: 2px solid rgba(100, 200, 255, 1.0);"
" color: rgb(255, 255, 255);"
"}"
"QPushButton:pressed {"
" background: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
" stop:0 rgba(100, 200, 255, 1.0), "
" stop:1 rgba(45, 120, 180, 1.0));"
"}"
// 选项卡样式 - 更清晰
"QTabWidget::pane {"
" border: 1px solid rgba(100, 200, 255, 0.4);"
" background: rgba(15, 22, 32, 0.6);"
" margin-top: 2px;" // 减少顶部边距
"}"
"QTabBar::tab {"
" background: rgba(45, 65, 95, 0.7);"
" color: rgb(220, 230, 242);"
" padding: 6px 12px;" // 减少选项卡内边距
" margin-right: 1px;"
" border-top-left-radius: 4px;"
" border-top-right-radius: 4px;"
" font-size: 12px;"
" font-weight: 600;"
" min-height: 20px;"
"}"
"QTabBar::tab:selected {"
" background: rgba(100, 200, 255, 0.9);"
" color: rgb(255, 255, 255);"
"}"
"QTabBar::tab:hover:!selected {"
" background: rgba(100, 200, 255, 0.5);"
"}"
// 表格样式 - 最强对比度
"QTableWidget {"
" background-color: rgba(10, 15, 25, 0.95);"
" alternate-background-color: rgba(20, 25, 35, 0.95);"
" gridline-color: rgba(100, 200, 255, 0.4);"
" color: rgb(255, 255, 255);" // 纯白色
" font-size: 12px;" // 增大字体
" font-weight: 500;"
" selection-background-color: rgba(100, 200, 255, 0.6);"
"}"
"QTableWidget::item {"
" padding: 4px 6px;" // 减少单元格内边距
" border: none;"
"}"
"QHeaderView::section {"
" background-color: rgba(45, 65, 95, 0.9);"
" color: rgb(255, 255, 255);"
" padding: 6px 8px;" // 减少表头内边距
" border: 1px solid rgba(100, 200, 255, 0.4);"
" font-weight: bold;"
" font-size: 11px;"
"}"
// 分组框样式
"QGroupBox {"
" color: rgb(240, 248, 255);"
" font-weight: bold;"
" font-size: 12px;"
" border: 2px solid rgba(100, 200, 255, 0.4);"
" border-radius: 5px;"
" margin-top: 8px;" // 减少顶部边距
" padding-top: 5px;"
"}"
"QGroupBox::title {"
" subcontrol-origin: margin;"
" left: 8px;"
" padding: 0 4px 0 4px;"
" color: rgb(100, 200, 255);"
"}"
);
}
void DeviceDialog::connectSignals()
{
// 连接按钮信号
connect(ui->connectButton, &QPushButton::clicked, this, &DeviceDialog::onConnectClicked);
connect(ui->disconnectButton, &QPushButton::clicked, this, &DeviceDialog::onDisconnectClicked);
connect(ui->locateButton, &QPushButton::clicked, this, &DeviceDialog::onLocateClicked);
connect(ui->refreshButton, &QPushButton::clicked, this, &DeviceDialog::onRefreshClicked);
}
void DeviceDialog::setDeviceIcon(const QString &type)
{
if (type == "uav") {
ui->deviceIconLabel->setText("🚁");
ui->deviceIconLabel->setStyleSheet("font-size: 48px; color: #52C2F2;");
} else if (type == "dog") {
ui->deviceIconLabel->setText("🤖");
ui->deviceIconLabel->setStyleSheet("font-size: 48px; color: #52C2F2;");
} else {
ui->deviceIconLabel->setText("");
ui->deviceIconLabel->setStyleSheet("font-size: 48px; color: #888888;");
}
}
void DeviceDialog::setStatusLabel(int state)
{
// 创建一个新的机器人信息部件
QWidget *widget = new QWidget();
QVBoxLayout *layout = new QVBoxLayout(widget);
layout->addWidget(new QLabel("机器人名称:" + name));
layout->addWidget(new QLabel("机器人类型:" + type));
layout->addWidget(new QLabel("机器人状态:" + status));
layout->addWidget(new QLabel("机器人位置:" + position));
layout->addStretch();
widget->setLayout(layout);
QString statusText;
QString statusStyle;
switch (state) {
case 0: // 离线
statusText = "离线";
statusStyle = "color: white; background-color: #FF6B6B; border-radius: 15px; padding: 5px;";
break;
case 1: // 在线
statusText = "在线";
statusStyle = "color: white; background-color: #4ECDC4; border-radius: 15px; padding: 5px;";
break;
case 2: // 工作中
statusText = "工作中";
statusStyle = "color: white; background-color: #45B7D1; border-radius: 15px; padding: 5px;";
break;
case 3: // 错误
statusText = "错误";
statusStyle = "color: white; background-color: #FF8C42; border-radius: 15px; padding: 5px;";
break;
default:
statusText = "未知";
statusStyle = "color: white; background-color: #888888; border-radius: 15px; padding: 5px;";
break;
}
ui->deviceStatusLabel->setText(statusText);
ui->deviceStatusLabel->setStyleSheet(statusStyle);
}
QString DeviceDialog::calculateWorkingTime(const QString &createdTime)
{
if (createdTime.isEmpty()) {
return "未知";
}
QDateTime created = QDateTime::fromString(createdTime, "yyyy-MM-dd hh:mm:ss");
if (!created.isValid()) {
return "未知";
}
QDateTime now = QDateTime::currentDateTime();
qint64 secondsElapsed = created.secsTo(now);
int days = secondsElapsed / (24 * 3600);
int hours = (secondsElapsed % (24 * 3600)) / 3600;
int minutes = (secondsElapsed % 3600) / 60;
QString result;
if (days > 0) {
result += QString("%1天").arg(days);
}
if (hours > 0) {
result += QString("%1小时").arg(hours);
}
if (minutes > 0) {
result += QString("%1分钟").arg(minutes);
}
return result.isEmpty() ? "刚刚创建" : result;
}
// 将机器人信息部件添加到布局中
layout->addWidget(widget);
void DeviceDialog::initializeOperationLogTable()
{
// 设置表格列宽
ui->operationLogTable->horizontalHeader()->setStretchLastSection(true);
ui->operationLogTable->setColumnWidth(0, 150); // 时间列
ui->operationLogTable->setColumnWidth(1, 100); // 操作列
ui->operationLogTable->setColumnWidth(2, 80); // 结果列
// 设置表格属性
ui->operationLogTable->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->operationLogTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->operationLogTable->setSortingEnabled(false);
}
void DeviceDialog::logOperation(const QString &operation, const QString &operatorName)
{
// 记录操作到数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "DeviceDialog_LogOperation");
db.setHostName("localhost");
db.setPort(3306);
db.setDatabaseName("Client");
db.setUserName("root");
db.setPassword("hzk200407140238");
if (!db.open()) {
qWarning() << "Failed to connect to database for logging operation:" << db.lastError().text();
return;
}
QSqlQuery query(db);
QString sql = "INSERT INTO device_operation_logs (device_id, device_type, operation, operation_result, operator) "
"VALUES (?, (SELECT device_type FROM devices WHERE id = ? LIMIT 1), ?, 'success', ?)";
query.prepare(sql);
query.addBindValue(m_currentDeviceId);
query.addBindValue(m_currentDeviceId);
query.addBindValue(operation);
query.addBindValue(operatorName);
if (!query.exec()) {
qWarning() << "Failed to log operation:" << query.lastError().text();
} else {
qDebug() << "Operation logged:" << operation << "for device" << m_currentDeviceId;
}
db.close();
}
void DeviceDialog::setHighContrastFonts()
{
// 创建高对比度字体
QFont boldFont = this->font();
boldFont.setPointSize(13);
boldFont.setWeight(QFont::Bold);
QFont normalFont = this->font();
normalFont.setPointSize(12);
normalFont.setWeight(QFont::Medium);
// 创建调色板确保文字是白色
QPalette palette = this->palette();
palette.setColor(QPalette::WindowText, QColor(255, 255, 255));
palette.setColor(QPalette::Text, QColor(255, 255, 255));
palette.setColor(QPalette::ButtonText, QColor(255, 255, 255));
// 应用到所有控件
this->setPalette(palette);
// 设置字体到对话框
this->setFont(normalFont);
// 递归设置所有子控件的字体和颜色
QList<QLabel*> labels = this->findChildren<QLabel*>();
for (QLabel* label : labels) {
label->setPalette(palette);
if (label->objectName().contains("Value") ||
label->objectName().contains("deviceName") ||
label->objectName().contains("deviceId") ||
label->objectName().contains("deviceType")) {
label->setFont(boldFont);
} else {
label->setFont(normalFont);
}
// 强制设置样式
label->setStyleSheet("QLabel { color: rgb(255, 255, 255); font-weight: bold; }");
}
// 设置表格字体
if (ui->operationLogTable) {
ui->operationLogTable->setFont(normalFont);
ui->operationLogTable->setPalette(palette);
ui->operationLogTable->setStyleSheet(
"QTableWidget { "
" color: rgb(255, 255, 255); "
" font-weight: 500; "
" background-color: rgba(10, 15, 25, 0.95); "
"} "
"QTableWidget::item { "
" color: rgb(255, 255, 255); "
" font-weight: 500; "
"}"
);
}
qDebug() << "High contrast fonts applied";
}

@ -8,6 +8,7 @@
#include "ui/main/MainWindow.h"
#include "build/ui_MainWindow.h"
#include "ui/dialogs/DeviceDialog.h"
// Qt GUI头文件
#include <QWebEngineView>
@ -794,10 +795,79 @@ void MainWindow::onDeviceLocationRequested(const QString &deviceId)
void MainWindow::onDeviceDetailsRequested(const QString &deviceId)
{
qDebug() << "Device details requested for:" << deviceId;
// TODO: 实现设备详情显示逻辑
// 例如:打开设备详情对话框、显示设备参数等
QMessageBox::information(this, "设备详情",
QString("设备详情功能正在开发中\n设备ID: %1").arg(deviceId));
// 连接数据库获取设备详细信息
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "MainWindow_DeviceDetails");
db.setHostName("localhost");
db.setPort(3306);
db.setDatabaseName("Client");
db.setUserName("root");
db.setPassword("hzk200407140238");
if (!db.open()) {
qWarning() << "Failed to connect to database for device details:" << db.lastError().text();
QMessageBox::warning(this, "错误", "无法连接到数据库");
return;
}
// 查询设备信息
QSqlQuery query(db);
QString sql = "SELECT name, device_type, ip, port, longitude, latitude, state, "
"signal_strength, battery_level, firmware_version, last_heartbeat, "
"created_at, updated_at "
"FROM devices WHERE id = ?";
query.prepare(sql);
query.addBindValue(deviceId);
if (!query.exec() || !query.next()) {
qWarning() << "Failed to query device details:" << query.lastError().text();
QMessageBox::warning(this, "错误",
QString("无法找到设备信息\n设备ID: %1").arg(deviceId));
db.close();
return;
}
// 获取设备信息
QString name = query.value("name").toString();
QString type = query.value("device_type").toString();
QString ip = query.value("ip").toString();
int port = query.value("port").toInt();
double longitude = query.value("longitude").toDouble();
double latitude = query.value("latitude").toDouble();
int state = query.value("state").toInt();
int signalStrength = query.value("signal_strength").toInt();
int batteryLevel = query.value("battery_level").toInt();
QString firmwareVersion = query.value("firmware_version").toString();
QString lastHeartbeat = query.value("last_heartbeat").toString();
QString createdAt = query.value("created_at").toString();
QString updatedAt = query.value("updated_at").toString();
db.close();
// 创建并显示设备详情对话框
DeviceDialog *dialog = new DeviceDialog(this);
// 设置设备信息
dialog->setDeviceInfo(deviceId, name, type, ip, port, longitude, latitude,
state, signalStrength, batteryLevel, firmwareVersion,
lastHeartbeat, createdAt, updatedAt);
// 连接设备操作信号
connect(dialog, &DeviceDialog::deviceConnectRequested,
this, &MainWindow::onDeviceControlRequested);
connect(dialog, &DeviceDialog::deviceDisconnectRequested,
this, &MainWindow::onDeviceControlRequested);
connect(dialog, &DeviceDialog::deviceLocationRequested,
this, &MainWindow::onDeviceLocationRequested);
// 显示对话框
dialog->exec();
// 清理
dialog->deleteLater();
qDebug() << "Device details dialog shown for:" << deviceId;
}
void MainWindow::onAddDeviceRequested(const QString &deviceType)

Loading…
Cancel
Save