206 lines
6.6 KiB
C++
206 lines
6.6 KiB
C++
#include "DeviceStatusWidget.h"
|
||
#include <QLabel>
|
||
#include <QVBoxLayout>
|
||
#include <QHBoxLayout>
|
||
#include <QFrame>
|
||
#include <QPixmap>
|
||
#include <QMouseEvent>
|
||
#include <QDebug>
|
||
#include "ClickableFrame.h"
|
||
|
||
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);
|
||
|
||
// 设置控件大小策略
|
||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||
}
|
||
|
||
DeviceStatusWidget::~DeviceStatusWidget()
|
||
{
|
||
}
|
||
|
||
void DeviceStatusWidget::setDevices(const QList<DeviceInfo>& devices)
|
||
{
|
||
m_devices = devices;
|
||
|
||
// 清除现有布局
|
||
QLayoutItem* child;
|
||
while ((child = m_mainLayout->takeAt(0)) != nullptr) {
|
||
delete child->widget();
|
||
delete child;
|
||
}
|
||
m_deviceLabels.clear();
|
||
m_statusLabels.clear();
|
||
m_nameLabels.clear();
|
||
|
||
// 创建设备标签
|
||
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;
|
||
}
|
||
}
|
||
|
||
// 如果找到设备,更新其状态
|
||
if (index >= 0) {
|
||
m_devices[index].status = status;
|
||
updateDeviceLabel(index);
|
||
emit deviceStatusChanged(deviceName, status);
|
||
}
|
||
}
|
||
|
||
void DeviceStatusWidget::setDeviceCount(int count)
|
||
{
|
||
// 清除现有布局
|
||
QLayoutItem* child;
|
||
while ((child = m_mainLayout->takeAt(0)) != nullptr) {
|
||
delete child->widget();
|
||
delete child;
|
||
}
|
||
m_deviceLabels.clear();
|
||
m_statusLabels.clear();
|
||
m_nameLabels.clear();
|
||
|
||
// 调整设备列表大小
|
||
while (m_devices.size() < count) {
|
||
m_devices.append(DeviceInfo());
|
||
}
|
||
while (m_devices.size() > count) {
|
||
m_devices.removeLast();
|
||
}
|
||
|
||
// 创建设备标签
|
||
createDeviceLabels(count);
|
||
|
||
// 更新设备标签显示
|
||
for (int i = 0; i < count; ++i) {
|
||
updateDeviceLabel(i);
|
||
}
|
||
}
|
||
|
||
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; }");
|
||
deviceFrame->setFixedSize(80, 100); // 调整大小以适应新布局
|
||
|
||
// 创建垂直布局(图标在上,名字在下)
|
||
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);
|
||
|
||
// 添加到设备布局(垂直排列)
|
||
deviceLayout->addWidget(statusLabel, 0, Qt::AlignCenter);
|
||
deviceLayout->addWidget(nameLabel, 0, Qt::AlignCenter);
|
||
|
||
// 添加到行布局
|
||
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;
|
||
}
|
||
|
||
const DeviceInfo& device = m_devices[index];
|
||
|
||
// 更新状态图片
|
||
QString imagePath = getStatusImage(device.status);
|
||
m_statusLabels[index]->setPixmap(QPixmap(imagePath).scaled(40, 40, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||
|
||
// 更新设备名称
|
||
m_nameLabels[index]->setText(device.name);
|
||
|
||
// 根据设备状态设置设备名称颜色
|
||
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;");
|
||
}
|
||
}
|
||
|
||
QString DeviceStatusWidget::getStatusImage(DeviceStatus status) const
|
||
{
|
||
// 这里简化处理,实际应用中可能需要根据设备类型选择不同的图片
|
||
switch (status) {
|
||
case DeviceStatus::Online:
|
||
return ":/resource/camera_online.png";
|
||
case DeviceStatus::Offline:
|
||
return ":/resource/camera_offline.png";
|
||
case DeviceStatus::Error:
|
||
return ":/resource/camera_offline.png"; // 错误状态也使用离线图片
|
||
default:
|
||
return ":/resource/camera_offline.png";
|
||
}
|
||
} |