2025-08-24 23:24:33 +08:00
|
|
|
|
#include "DeviceStatusWidget.h"
|
|
|
|
|
|
#include <QLabel>
|
|
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
|
|
#include <QFrame>
|
|
|
|
|
|
#include <QPixmap>
|
|
|
|
|
|
#include <QMouseEvent>
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
#include "ClickableFrame.h"
|
2025-08-31 21:08:28 +08:00
|
|
|
|
#include "VrLog.h"
|
2025-08-24 23:24:33 +08:00
|
|
|
|
|
|
|
|
|
|
DeviceStatusWidget::DeviceStatusWidget(QWidget* parent)
|
|
|
|
|
|
: QWidget(parent)
|
|
|
|
|
|
, m_mainLayout(new QVBoxLayout(this))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 设置布局边距
|
|
|
|
|
|
m_mainLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
m_mainLayout->setSpacing(5);
|
|
|
|
|
|
setLayout(m_mainLayout);
|
2025-08-31 21:08:28 +08:00
|
|
|
|
|
|
|
|
|
|
m_devices.clear();
|
2025-08-24 23:24:33 +08:00
|
|
|
|
|
|
|
|
|
|
// 设置控件大小策略
|
|
|
|
|
|
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DeviceStatusWidget::~DeviceStatusWidget()
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DeviceStatusWidget::setDevices(const QList<DeviceInfo>& devices)
|
|
|
|
|
|
{
|
2025-09-06 15:07:16 +08:00
|
|
|
|
// 移除现有设备标签
|
|
|
|
|
|
removeDeviceLabels();
|
2025-08-24 23:24:33 +08:00
|
|
|
|
|
2025-09-06 15:07:16 +08:00
|
|
|
|
m_devices = devices;
|
2025-08-31 21:08:28 +08:00
|
|
|
|
|
|
|
|
|
|
if (devices.isEmpty()) {
|
2025-09-06 15:07:16 +08:00
|
|
|
|
// 无设备时显示的标签
|
|
|
|
|
|
QLabel* noDeviceLabel;
|
|
|
|
|
|
// 创建一个提示标签,当没有设备时显示
|
|
|
|
|
|
noDeviceLabel = new QLabel("未配置设备", this);
|
|
|
|
|
|
noDeviceLabel->setStyleSheet("color: gray; font-size: 14px;");
|
|
|
|
|
|
noDeviceLabel->setAlignment(Qt::AlignCenter);
|
|
|
|
|
|
|
|
|
|
|
|
// 如果没有设备,显示提示信息
|
|
|
|
|
|
m_mainLayout->addWidget(noDeviceLabel);
|
|
|
|
|
|
|
|
|
|
|
|
noDeviceLabel->show();
|
2025-08-31 21:08:28 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-08-24 23:24:33 +08:00
|
|
|
|
|
|
|
|
|
|
// 创建设备标签
|
|
|
|
|
|
createDeviceLabels(devices.size());
|
|
|
|
|
|
|
|
|
|
|
|
// 更新设备标签显示
|
|
|
|
|
|
for (int i = 0; i < devices.size(); ++i) {
|
|
|
|
|
|
updateDeviceLabel(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DeviceStatusWidget::updateDeviceStatus(const QString& deviceName, DeviceStatus status)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 查找设备索引
|
|
|
|
|
|
int index = -1;
|
|
|
|
|
|
for (int i = 0; i < m_devices.size(); ++i) {
|
|
|
|
|
|
if (m_devices[i].alias == deviceName) {
|
|
|
|
|
|
index = i;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-11-26 22:44:38 +08:00
|
|
|
|
|
2025-08-24 23:24:33 +08:00
|
|
|
|
// 如果找到设备,更新其状态
|
|
|
|
|
|
if (index >= 0) {
|
|
|
|
|
|
m_devices[index].status = status;
|
|
|
|
|
|
updateDeviceLabel(index);
|
|
|
|
|
|
emit deviceStatusChanged(deviceName, status);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-26 22:44:38 +08:00
|
|
|
|
void DeviceStatusWidget::updateDeviceTemperature(const QString& deviceName, float temperature)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 查找设备索引
|
|
|
|
|
|
int index = -1;
|
|
|
|
|
|
for (int i = 0; i < m_devices.size(); ++i) {
|
|
|
|
|
|
if (m_devices[i].alias == deviceName) {
|
|
|
|
|
|
index = i;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果找到设备,更新其温度
|
|
|
|
|
|
if (index >= 0) {
|
|
|
|
|
|
m_devices[index].temperature = temperature;
|
|
|
|
|
|
m_devices[index].hasTemperature = true;
|
|
|
|
|
|
updateDeviceLabel(index);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-24 23:24:33 +08:00
|
|
|
|
void DeviceStatusWidget::onDeviceLabelClicked()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 查找发送信号的标签
|
|
|
|
|
|
QObject* senderObj = sender();
|
|
|
|
|
|
for (int i = 0; i < m_deviceLabels.size(); ++i) {
|
|
|
|
|
|
if (m_deviceLabels[i] == senderObj) {
|
|
|
|
|
|
emit deviceClicked(m_devices[i].alias);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void DeviceStatusWidget::createDeviceLabels(int count)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 创建网格布局,每行4个设备
|
|
|
|
|
|
int devicesPerRow = 4;
|
|
|
|
|
|
int rowCount = (count + devicesPerRow - 1) / devicesPerRow; // 向上取整
|
|
|
|
|
|
|
|
|
|
|
|
for (int row = 0; row < rowCount; ++row) {
|
|
|
|
|
|
QHBoxLayout* rowLayout = new QHBoxLayout();
|
|
|
|
|
|
rowLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
rowLayout->setSpacing(10);
|
|
|
|
|
|
|
|
|
|
|
|
for (int col = 0; col < devicesPerRow; ++col) {
|
|
|
|
|
|
int index = row * devicesPerRow + col;
|
|
|
|
|
|
if (index >= count) break;
|
|
|
|
|
|
|
|
|
|
|
|
// 创建设备框架
|
|
|
|
|
|
ClickableFrame* deviceFrame = new ClickableFrame(this);
|
|
|
|
|
|
deviceFrame->setObjectName("deviceFrame");
|
|
|
|
|
|
// 增强圆角框样式,添加边框以便更好地区分
|
|
|
|
|
|
deviceFrame->setStyleSheet("QFrame#deviceFrame { background-color: rgb(37, 38, 42); border: 1px solid #555555; border-radius: 8px; }");
|
2025-11-26 22:44:38 +08:00
|
|
|
|
deviceFrame->setFixedSize(80, 120); // 调整大小以适应温度标签
|
2025-08-24 23:24:33 +08:00
|
|
|
|
|
|
|
|
|
|
// 创建垂直布局(图标在上,名字在下)
|
|
|
|
|
|
QVBoxLayout* deviceLayout = new QVBoxLayout(deviceFrame);
|
|
|
|
|
|
deviceLayout->setContentsMargins(5, 5, 5, 5);
|
|
|
|
|
|
deviceLayout->setSpacing(5);
|
|
|
|
|
|
|
|
|
|
|
|
// 创建状态图片标签
|
|
|
|
|
|
QLabel* statusLabel = new QLabel(deviceFrame);
|
|
|
|
|
|
statusLabel->setFixedSize(40, 40);
|
|
|
|
|
|
statusLabel->setAlignment(Qt::AlignCenter);
|
|
|
|
|
|
m_statusLabels.append(statusLabel);
|
|
|
|
|
|
|
|
|
|
|
|
// 创建设备名称标签
|
|
|
|
|
|
QLabel* nameLabel = new QLabel(deviceFrame);
|
|
|
|
|
|
nameLabel->setStyleSheet("color: green; font-size: 12px;");
|
|
|
|
|
|
nameLabel->setAlignment(Qt::AlignCenter); // 居中对齐
|
|
|
|
|
|
m_nameLabels.append(nameLabel);
|
2025-11-26 22:44:38 +08:00
|
|
|
|
|
|
|
|
|
|
// 创建温度标签
|
|
|
|
|
|
QLabel* temperatureLabel = new QLabel(deviceFrame);
|
|
|
|
|
|
temperatureLabel->setStyleSheet("color: rgb(100, 200, 255); font-size: 11px;");
|
|
|
|
|
|
temperatureLabel->setAlignment(Qt::AlignCenter);
|
|
|
|
|
|
temperatureLabel->setText("--°C"); // 默认显示
|
|
|
|
|
|
m_temperatureLabels.append(temperatureLabel);
|
|
|
|
|
|
|
2025-08-24 23:24:33 +08:00
|
|
|
|
// 添加到设备布局(垂直排列)
|
|
|
|
|
|
deviceLayout->addWidget(statusLabel, 0, Qt::AlignCenter);
|
|
|
|
|
|
deviceLayout->addWidget(nameLabel, 0, Qt::AlignCenter);
|
2025-11-26 22:44:38 +08:00
|
|
|
|
deviceLayout->addWidget(temperatureLabel, 0, Qt::AlignCenter);
|
2025-08-24 23:24:33 +08:00
|
|
|
|
|
|
|
|
|
|
// 添加到行布局
|
|
|
|
|
|
rowLayout->addWidget(deviceFrame);
|
|
|
|
|
|
|
|
|
|
|
|
// 保存设备标签引用
|
|
|
|
|
|
m_deviceLabels.append(deviceFrame);
|
|
|
|
|
|
|
|
|
|
|
|
// 连接点击信号
|
|
|
|
|
|
connect(deviceFrame, &ClickableFrame::clicked, this, &DeviceStatusWidget::onDeviceLabelClicked);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加行布局到主布局
|
|
|
|
|
|
m_mainLayout->addLayout(rowLayout);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DeviceStatusWidget::updateDeviceLabel(int index)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (index < 0 || index >= m_devices.size() || index >= m_statusLabels.size() || index >= m_nameLabels.size()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-11-26 22:44:38 +08:00
|
|
|
|
|
2025-08-24 23:24:33 +08:00
|
|
|
|
const DeviceInfo& device = m_devices[index];
|
2025-11-26 22:44:38 +08:00
|
|
|
|
|
2025-08-24 23:24:33 +08:00
|
|
|
|
// 更新状态图片
|
|
|
|
|
|
QString imagePath = getStatusImage(device.status);
|
|
|
|
|
|
m_statusLabels[index]->setPixmap(QPixmap(imagePath).scaled(40, 40, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
2025-11-26 22:44:38 +08:00
|
|
|
|
|
2025-08-24 23:24:33 +08:00
|
|
|
|
// 更新设备名称
|
|
|
|
|
|
m_nameLabels[index]->setText(device.name);
|
2025-11-26 22:44:38 +08:00
|
|
|
|
|
2025-08-24 23:24:33 +08:00
|
|
|
|
// 根据设备状态设置设备名称颜色
|
|
|
|
|
|
if (device.status == DeviceStatus::Online) {
|
|
|
|
|
|
m_nameLabels[index]->setStyleSheet("color: green; font-size: 12px;");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
m_nameLabels[index]->setStyleSheet("color: rgb(220, 60, 60); font-size: 12px;");
|
|
|
|
|
|
}
|
2025-11-26 22:44:38 +08:00
|
|
|
|
|
|
|
|
|
|
// 更新温度显示
|
|
|
|
|
|
if (index < m_temperatureLabels.size()) {
|
|
|
|
|
|
if (device.hasTemperature) {
|
|
|
|
|
|
m_temperatureLabels[index]->setText(QString("%1°C").arg(device.temperature, 0, 'f', 1));
|
|
|
|
|
|
m_temperatureLabels[index]->setStyleSheet("color: rgb(100, 200, 255); font-size: 11px;");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
m_temperatureLabels[index]->setText("--°C");
|
|
|
|
|
|
m_temperatureLabels[index]->setStyleSheet("color: gray; font-size: 11px;");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-24 23:24:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString DeviceStatusWidget::getStatusImage(DeviceStatus status) const
|
|
|
|
|
|
{
|
|
|
|
|
|
// 这里简化处理,实际应用中可能需要根据设备类型选择不同的图片
|
|
|
|
|
|
switch (status) {
|
|
|
|
|
|
case DeviceStatus::Online:
|
2025-11-19 00:23:09 +08:00
|
|
|
|
return ":/common/resource/camera_online.png";
|
2025-08-24 23:24:33 +08:00
|
|
|
|
case DeviceStatus::Offline:
|
2025-11-19 00:23:09 +08:00
|
|
|
|
return ":/common/resource/camera_offline.png";
|
2025-08-24 23:24:33 +08:00
|
|
|
|
case DeviceStatus::Error:
|
2025-11-19 00:23:09 +08:00
|
|
|
|
return ":/common/resource/camera_offline.png"; // 错误状态也使用离线图片
|
2025-08-24 23:24:33 +08:00
|
|
|
|
default:
|
2025-11-19 00:23:09 +08:00
|
|
|
|
return ":/common/resource/camera_offline.png";
|
2025-08-24 23:24:33 +08:00
|
|
|
|
}
|
2025-08-31 21:08:28 +08:00
|
|
|
|
}
|
2025-09-06 15:07:16 +08:00
|
|
|
|
|
|
|
|
|
|
void DeviceStatusWidget::removeDeviceLabels()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 清空所有设备相关的标签列表
|
|
|
|
|
|
m_deviceLabels.clear();
|
|
|
|
|
|
m_statusLabels.clear();
|
|
|
|
|
|
m_nameLabels.clear();
|
2025-11-26 22:44:38 +08:00
|
|
|
|
m_temperatureLabels.clear();
|
|
|
|
|
|
|
2025-09-06 15:07:16 +08:00
|
|
|
|
// 递归删除所有子widget
|
|
|
|
|
|
QList<QWidget*> allWidgets = this->findChildren<QWidget*>();
|
|
|
|
|
|
for (QWidget* widget : allWidgets) {
|
|
|
|
|
|
if (widget != this) { // 不要删除自己
|
|
|
|
|
|
widget->deleteLater();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-11-26 22:44:38 +08:00
|
|
|
|
|
2025-09-06 15:07:16 +08:00
|
|
|
|
// 清理布局项目
|
|
|
|
|
|
while (m_mainLayout->count()) {
|
|
|
|
|
|
QLayoutItem* child = m_mainLayout->takeAt(0);
|
|
|
|
|
|
if (child) {
|
|
|
|
|
|
delete child;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|