#include "appicon.h" #include #include #include #include #include #include AppIcon::AppIcon(const AppIconData &data, QWidget *parent) : QWidget(parent), m_data(data), m_scale(1.0), m_isPressed(false), m_longPressTimerId(0) { qDebug() << "AppIcon constructor:" << data.name << "(" << data.id << ")"; setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); setCursor(Qt::PointingHandCursor); setAttribute(Qt::WA_Hover); setupUI(); qDebug() << "AppIcon created successfully:" << data.name; } AppIcon::~AppIcon() { if (m_longPressTimerId) { killTimer(m_longPressTimerId); } } void AppIcon::setupUI() { QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(3, 3, 3, 3); layout->setSpacing(5); layout->setAlignment(Qt::AlignCenter); // Android风格图标尺寸 - 10英寸屏幕优化 int iconSize = 80; int borderRadius = 16; QWidget *iconContainer = new QWidget(this); iconContainer->setFixedSize(iconSize, iconSize); iconContainer->setObjectName("iconContainer"); // 设置阴影效果 - 更明显的阴影 m_shadowEffect = new QGraphicsDropShadowEffect(this); m_shadowEffect->setBlurRadius(16); m_shadowEffect->setColor(QColor(0, 0, 0, 60)); m_shadowEffect->setOffset(0, 4); iconContainer->setGraphicsEffect(m_shadowEffect); // 图标标签 m_iconLabel = new QLabel(iconContainer); m_iconLabel->setAlignment(Qt::AlignCenter); m_iconLabel->setFixedSize(iconSize, iconSize); m_iconLabel->move(0, 0); // 设置图标样式 QString gradientStart = m_data.gradient.size() > 0 ? m_data.gradient[0] : m_data.color; QString gradientEnd = m_data.gradient.size() > 1 ? m_data.gradient[1] : m_data.color; QString iconStyle = QString(R"( QLabel { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 %1, stop:1 %2); border-radius: %3px; font-size: 36px; color: white; } )") .arg(gradientStart, gradientEnd) .arg(borderRadius); m_iconLabel->setStyleSheet(iconStyle); // 设置 SVG 图标 QString iconPath = getIconSymbol(m_data.id); if (!iconPath.isEmpty()) { QPixmap pixmap(iconPath); if (!pixmap.isNull()) { // 缩放图标到合适大小 int svgSize = iconSize - 24; // 留出边距 pixmap = pixmap.scaled(svgSize, svgSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); m_iconLabel->setPixmap(pixmap); } } // 徽章标签 - 过滤掉emoji,只显示纯文字badge if (!m_data.badge.isEmpty()) { QString badgeText = m_data.badge; // 过滤掉emoji字符(保留ASCII和常见中文字符) QString filteredBadge; for (const QChar &ch : badgeText) { ushort unicode = ch.unicode(); // 保留基本ASCII(32-126)、中文字符(0x4E00-0x9FFF)、以及一些常用符号 if ((unicode >= 32 && unicode <= 126) || (unicode >= 0x4E00 && unicode <= 0x9FFF) || ch == QChar(0xB1) || // ± ch == QChar(0x394) || // Δ ch == QChar(0x3A9)) { // Ω filteredBadge += ch; } } if (!filteredBadge.isEmpty()) { m_badgeLabel = new QLabel(iconContainer); m_badgeLabel->setText(filteredBadge); m_badgeLabel->setFixedSize(26, 16); m_badgeLabel->setAlignment(Qt::AlignCenter); m_badgeLabel->move(iconSize - 28, iconSize - 18); m_badgeLabel->setStyleSheet(R"( QLabel { background-color: rgba(255, 255, 255, 0.95); color: #333; border-radius: 4px; font-size: 9px; font-weight: bold; } )"); } } layout->addWidget(iconContainer, 0, Qt::AlignCenter); // 名称标签 - Android风格白色文字带阴影 m_nameLabel = new QLabel(m_data.name, this); m_nameLabel->setAlignment(Qt::AlignCenter); m_nameLabel->setFixedWidth(150); m_nameLabel->setWordWrap(false); m_nameLabel->setStyleSheet(R"( QLabel { color: white; font-size: 13px; font-weight: 500; background: transparent; } )"); layout->addWidget(m_nameLabel, 0, Qt::AlignCenter); } QString AppIcon::getIconSymbol(const QString &id) const { // 返回对应的SVG图标路径 static QMap iconMap = { {"rtd", ":/icons/ic_rtd.svg"}, {"rtd_measure", ":/icons/ic_rtd.svg"}, {"rtd_output", ":/icons/ic_rtd_output.svg"}, {"thermocouple", ":/icons/ic_thermocouple.svg"}, {"insulation", ":/icons/ic_insulation.svg"}, {"dc_current", ":/icons/ic_dc_current.svg"}, {"dc_voltage", ":/icons/ic_dc_voltage.svg"}, {"frequency", ":/icons/ic_frequency.svg"}, {"ac_voltage", ":/icons/ic_ac_voltage.svg"}, {"switch_detect", ":/icons/ic_switch.svg"}, {"ripple", ":/icons/ic_ripple.svg"}, {"ramp", ":/icons/ic_ramp.svg"}, {"waveform", ":/icons/ic_waveform.svg"}, {"dual_channel", ":/icons/ic_dual_channel.svg"}, {"trim", ":/icons/ic_trim.svg"}, {"data_management", ":/icons/ic_data.svg"}, {"wireless", ":/icons/ic_wireless.svg"}, {"sop", ":/icons/ic_sop.svg"}, {"rcp63", ":/icons/ic_rcp63.svg"}, {"settings", ":/icons/ic_settings.svg"}, {"network_test", ":/icons/ic_network_test.svg"}, {"dock_sop", ":/icons/ic_sop.svg"}, {"dock_rcp63", ":/icons/ic_rcp63.svg"}, {"dock_network", ":/icons/ic_network_test.svg"}, {"dock_settings", ":/icons/ic_settings.svg"}}; return iconMap.value(id, ""); } void AppIcon::setScale(qreal scale) { if (qFuzzyCompare(m_scale, scale)) return; m_scale = scale; update(); } void AppIcon::paintEvent(QPaintEvent *event) { Q_UNUSED(event) if (!qFuzzyCompare(m_scale, 1.0)) { // 应用缩放变换 QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); QTransform transform; transform.translate(width() / 2, height() / 2); transform.scale(m_scale, m_scale); transform.translate(-width() / 2, -height() / 2); painter.setTransform(transform); } QWidget::paintEvent(event); } #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) void AppIcon::enterEvent(QEnterEvent *event) #else void AppIcon::enterEvent(QEvent *event) #endif { Q_UNUSED(event) m_shadowEffect->setBlurRadius(20); m_shadowEffect->setColor(QColor(0, 0, 0, 60)); } void AppIcon::leaveEvent(QEvent *event) { Q_UNUSED(event) m_shadowEffect->setBlurRadius(16); m_shadowEffect->setColor(QColor(0, 0, 0, 40)); } void AppIcon::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_isPressed = true; animateScale(0.95); // 启动长按计时器 m_longPressTimerId = startTimer(LONG_PRESS_DELAY); } QWidget::mousePressEvent(event); } void AppIcon::mouseReleaseEvent(QMouseEvent *event) { if (m_longPressTimerId) { killTimer(m_longPressTimerId); m_longPressTimerId = 0; } if (m_isPressed && event->button() == Qt::LeftButton) { m_isPressed = false; animateScale(1.0); if (rect().contains(event->pos())) { emit clicked(m_data.id); } } QWidget::mouseReleaseEvent(event); } void AppIcon::timerEvent(QTimerEvent *event) { if (event->timerId() == m_longPressTimerId) { killTimer(m_longPressTimerId); m_longPressTimerId = 0; if (m_isPressed) { emit longPressed(m_data.id); } } QWidget::timerEvent(event); } void AppIcon::animateScale(qreal targetScale, int duration) { QPropertyAnimation *anim = new QPropertyAnimation(this, "scale", this); anim->setDuration(duration); anim->setStartValue(m_scale); anim->setEndValue(targetScale); anim->setEasingCurve(QEasingCurve::OutCubic); anim->start(QAbstractAnimation::DeleteWhenStopped); }