#include "launcherpage.h" #include #include #include #include #include #include LauncherPage::LauncherPage(const PageConfig &config, QWidget *parent) : QWidget(parent), m_config(config), m_columns(4), m_rows(3), m_horizontalGap(20), m_verticalGap(18), m_horizontalPadding(30), m_verticalPadding(20) { setObjectName("launcherPage_" + config.id); setupUI(); } LauncherPage::~LauncherPage() { } void LauncherPage::setupUI() { // 设置背景透明,同时确保可以绑定paintEvent setAttribute(Qt::WA_StyledBackground, true); setStyleSheet("background: transparent;"); qDebug() << "=== LauncherPage setupUI ==="; qDebug() << "Page ID:" << m_config.id; qDebug() << "Apps count:" << m_config.apps.size(); // 创建图标(不使用布局,使用绝对定位) for (int i = 0; i < m_config.apps.size(); ++i) { const auto &appData = m_config.apps[i]; qDebug() << "Creating icon for:" << appData.name << "(" << appData.id << ")" << "group:" << appData.group; AppIcon *icon = new AppIcon(appData, this); icon->setFixedSize(190, 180); connect(icon, &AppIcon::clicked, this, &LauncherPage::appClicked); connect(icon, &AppIcon::longPressed, this, &LauncherPage::appLongPressed); m_icons.append(icon); // 收集分组信息 if (!appData.group.isEmpty()) { if (!m_groups.contains(appData.group)) { GroupInfo info; info.groupId = appData.group; m_groups[appData.group] = info; } m_groups[appData.group].iconIndices.append(i); } } qDebug() << "Total icons created:" << m_icons.size(); qDebug() << "Groups found:" << m_groups.keys(); } void LauncherPage::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); layoutIcons(); } void LauncherPage::layoutIcons() { if (m_icons.isEmpty()) { qDebug() << "layoutIcons: No icons to layout!"; return; } int w = width(); int h = height(); qDebug() << "=== layoutIcons ==="; qDebug() << "Page ID:" << m_config.id; qDebug() << "Widget size:" << w << "x" << h; qDebug() << "Icons count:" << m_icons.size(); // Android风格:图标均匀分布 int iconWidth = 190; int iconHeight = 180; // 动态计算可以容纳的行数 int minVerticalSpacing = 12; int maxPossibleRows = (h + minVerticalSpacing) / (iconHeight + minVerticalSpacing); int actualRows = qMin(maxPossibleRows, m_rows); actualRows = qMax(actualRows, 1); // 至少显示1行 qDebug() << "Max possible rows:" << maxPossibleRows << "Using rows:" << actualRows; // 计算间距,使图标均匀分布 int horizontalSpacing = (w - m_columns * iconWidth) / (m_columns + 1); int verticalSpacing = (h - actualRows * iconHeight) / (actualRows + 1); // 确保最小间距 horizontalSpacing = qMax(horizontalSpacing, 10); verticalSpacing = qMax(verticalSpacing, 12); qDebug() << "Spacing - H:" << horizontalSpacing << "V:" << verticalSpacing; // 重新计算起始位置使其居中 int startX = (w - (m_columns * iconWidth + (m_columns - 1) * horizontalSpacing)) / 2; int startY = (h - (actualRows * iconHeight + (actualRows - 1) * verticalSpacing)) / 2; qDebug() << "Start position - X:" << startX << "Y:" << startY; // 布局图标,同时记录位置用于分组框计算 QMap iconRects; int index = 0; for (AppIcon *icon : m_icons) { int row = index / m_columns; int col = index % m_columns; if (row < actualRows) { int x = startX + col * (iconWidth + horizontalSpacing); int y = startY + row * (iconHeight + verticalSpacing); qDebug() << " Icon" << index << "at" << x << "," << y; icon->move(x, y); icon->show(); // 记录计算出的位置 iconRects[index] = QRect(x, y, iconWidth, iconHeight); } else { qDebug() << " Icon" << index << "hidden (too many rows)"; icon->hide(); } index++; } qDebug() << "layoutIcons done, visible icons:" << qMin(index, m_rows * m_columns); // 更新分组矩形,使用计算出的位置 updateGroupRects(iconRects); } void LauncherPage::updateGroupRects(const QMap &iconRects) { // 为每个分组计算边界矩形 for (auto it = m_groups.begin(); it != m_groups.end(); ++it) { GroupInfo &group = it.value(); if (group.iconIndices.isEmpty()) continue; QRect boundingRect; bool first = true; for (int idx : group.iconIndices) { if (iconRects.contains(idx)) { QRect iconRect = iconRects[idx]; qDebug() << " Group icon" << idx << "rect:" << iconRect; if (first) { boundingRect = iconRect; first = false; } else { boundingRect = boundingRect.united(iconRect); } } } // 扩展边界矩形,添加内边距 int padding = 3; group.boundingRect = boundingRect.adjusted(-padding, -padding, padding, padding); qDebug() << "Group" << group.groupId << "bounding rect:" << group.boundingRect; } // 触发重绘 update(); } void LauncherPage::paintEvent(QPaintEvent *event) { QWidget::paintEvent(event); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); // 绘制分组背景框 for (const GroupInfo &group : m_groups) { qDebug() << "Drawing group:" << group.groupId << "rect:" << group.boundingRect; if (group.boundingRect.isValid() && !group.boundingRect.isEmpty()) { // 设置半透明背景 - 增加透明度使其更明显 QColor bgColor(255, 255, 255, 50); // 白色半透明 painter.setBrush(bgColor); // 设置边框 QColor borderColor(255, 255, 255, 100); // 白色半透明边框 painter.setPen(QPen(borderColor, 2.0)); // 绘制圆角矩形 QPainterPath path; path.addRoundedRect(QRectF(group.boundingRect), 20, 20); painter.drawPath(path); } } }