Skip to content

Feat: improve PageMultiInfo CPU header info display and device genera…#653

Merged
deepin-bot[bot] merged 1 commit intolinuxdeepin:develop/eaglefrom
GongHeng2017:202605071454-dev-eagle-feat
May 7, 2026
Merged

Feat: improve PageMultiInfo CPU header info display and device genera…#653
deepin-bot[bot] merged 1 commit intolinuxdeepin:develop/eaglefrom
GongHeng2017:202605071454-dev-eagle-feat

Conversation

@GongHeng2017
Copy link
Copy Markdown
Contributor

@GongHeng2017 GongHeng2017 commented May 7, 2026

…tion

  • Update PageMultiInfo to use scroll area container layout for CPU header detail widgets
  • Add/adjust accessor usage for header info in CPU page
  • Refactor scroll area content resizing and visibility behavior
  • Update DeviceGenerator logic and declarations (internal feature updates)
  • Keep UI behavior consistent with latest header info widget layout

Log: add feature for cpu info show.
Task: https://pms.uniontech.com/task-view-387697.html

Summary by Sourcery

Add scrollable CPU header info display to the multi-info page and generate corresponding header data during CPU device creation.

New Features:

  • Display CPU header information in the CPU device page using a scrollable header info widget populated from DeviceManager data
  • Compute and expose aggregate CPU header information (model, vendor, architecture, cores/threads, cache totals) during CPU device generation

Enhancements:

  • Refine PageMultiInfo layout to integrate a scroll area for header information and keep table/detail sections responsive to resizing

…tion

- Update PageMultiInfo to use scroll area container layout for CPU header detail widgets
- Add/adjust accessor usage for header info in CPU page
- Refactor scroll area content resizing and visibility behavior
- Update DeviceGenerator logic and declarations (internal feature updates)
- Keep UI behavior consistent with latest header info widget layout

Log: add feature for cpu info show.
Task: https://pms.uniontech.com/task-view-387697.html
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 7, 2026

Reviewer's Guide

Implements a scrollable CPU header info section in PageMultiInfo and wires it to new CPU header metadata generated in DeviceGenerator, including layout, visibility, and data calculation logic.

Sequence diagram for CPU header info generation and display

sequenceDiagram
    actor User
    participant DeviceGenerator
    participant DeviceManager
    participant PageMultiInfo
    participant HeaderInfoTableWidget

    User->>DeviceGenerator: generatorCpuDevice()
    DeviceGenerator->>DeviceGenerator: iterate lsCpu
    DeviceGenerator->>DeviceManager: addCpuDevice(device)
    DeviceGenerator->>DeviceGenerator: calAndSetCpuHeaderInfo(firstProcessorInfo, coreNum, logicalNum)
    DeviceGenerator->>DeviceManager: setCpuHeaderInfo(cpuHeaderInfo)

    User->>PageMultiInfo: updateInfo(lst)
    PageMultiInfo->>PageMultiInfo: dynamic_cast to DeviceCpu
    alt lst contains DeviceCpu
        PageMultiInfo->>DeviceManager: getCpuHeaderInfo(headerInfo)
        PageMultiInfo->>PageMultiInfo: clearLayout(mp_HeaderInfoWidgetLay)
        loop for each headerInfoGroup
            PageMultiInfo->>HeaderInfoTableWidget: new HeaderInfoTableWidget(mp_HeaderInfoWidget)
            PageMultiInfo->>HeaderInfoTableWidget: updateData(group)
            PageMultiInfo->>PageMultiInfo: mp_HeaderInfoWidgetLay->addWidget(widget)
        end
        PageMultiInfo->>PageMultiInfo: configure mp_HeaderInfoWidget
        PageMultiInfo->>PageMultiInfo: mp_HeaderInfoWidget->setVisible(true)
    else lst does not contain DeviceCpu
        PageMultiInfo->>PageMultiInfo: mp_HeaderInfoWidget->setVisible(false)
        PageMultiInfo->>PageMultiInfo: mp_HeaderInfoWidget->setMaximumHeight(0)
    end
Loading

Class diagram for updated CPU header info flow

classDiagram
    class PageMultiInfo {
        +PageMultiInfo(QWidget *parent)
        +~PageMultiInfo()
        +void updateInfo(QList~DeviceBaseInfo *~ lst)
        -void initWidgets()
        -void getTableListInfo(QList~DeviceBaseInfo *~ lst, QList~QStringList~ &deviceList, QList~QStringList~ &menuList)
        -void clearLayout(QLayout *layout)
        -DLabel *mp_Label
        -DScrollArea *mp_HeaderInfoWidget
        -DWidget *mp_HeaderInfoContainer
        -QVBoxLayout *mp_HeaderInfoWidgetLay
        -PageTableHeader *mp_Table
        -PageDetail *mp_Detail
        -QList~DeviceBaseInfo *~ m_lstDevice
        -QList~QStringList~ m_deviceList
        -QList~QStringList~ m_menuControlList
    }

    class DeviceGenerator {
        +DeviceGenerator(QObject *parent)
        +void generatorCpuDevice()
        -void calAndSetCpuHeaderInfo(QMap~QString, QString~ firstProcessorInfo, int coreNum, int logicalNum)
        #QStringList m_ListBusID
    }

    class DeviceManager {
        +static DeviceManager *instance()
        +void addCpuDevice(DeviceBaseInfo *device)
        +void setCpuHeaderInfo(QList~QList~QPair~QString, QString~~~ cpuHeaderInfo)
        +void getCpuHeaderInfo(QList~QList~QPair~QString, QString~~~ &cpuHeaderInfo)
    }

    class DeviceBaseInfo {
    }

    class DeviceCpu {
    }

    class HeaderInfoTableWidget {
        +HeaderInfoTableWidget(QWidget *parent)
        +void updateData(QList~QPair~QString, QString~~ headerInfo)
    }

    class PageTableHeader {
    }

    class PageDetail {
    }

    class QWidget {
    }

    PageMultiInfo --|> QWidget
    DeviceCpu --|> DeviceBaseInfo

    PageMultiInfo o--> PageTableHeader : mp_Table
    PageMultiInfo o--> PageDetail : mp_Detail
    PageMultiInfo o--> DLabel : mp_Label
    PageMultiInfo o--> DScrollArea : mp_HeaderInfoWidget
    PageMultiInfo o--> DWidget : mp_HeaderInfoContainer
    PageMultiInfo o--> QVBoxLayout : mp_HeaderInfoWidgetLay
    PageMultiInfo ..> DeviceCpu : uses dynamic_cast
    PageMultiInfo ..> HeaderInfoTableWidget : creates
    PageMultiInfo ..> DeviceManager : calls getCpuHeaderInfo

    DeviceGenerator ..> DeviceManager : addCpuDevice
    DeviceGenerator ..> DeviceManager : setCpuHeaderInfo
    DeviceGenerator ..> Common : formatTotalCache

    DeviceManager ..> DeviceCpu : manages
Loading

File-Level Changes

Change Details Files
Add scrollable CPU header info section to PageMultiInfo and manage its lifecycle
  • Introduce DScrollArea-based header info widget, container, and vertical layout managed alongside existing label/table/detail widgets
  • Initialize header scroll area with no frame, vertical-only scrolling, expanding size policy, and default maximum height to integrate into the main page layout
  • Implement clearLayout helper to safely remove dynamic header widgets and use it before repopulating header info
  • Ensure header scroll area is constructed in the constructor and deleted in the destructor, avoiding dangling container/layout pointers
deepin-devicemanager/src/Page/PageMultiInfo.cpp
deepin-devicemanager/src/Page/PageMultiInfo.h
Populate CPU header info view based on detected CPU devices
  • Detect when the current page represents a CPU device via dynamic_cast and retrieve precomputed CPU header info from DeviceManager
  • Dynamically create HeaderInfoTableWidget instances per header-info group, bind data via updateData, and add them to the header layout
  • Control visibility, maximum height, and size of the header scroll area when CPU info is present, and hide/collapse it for non-CPU devices
deepin-devicemanager/src/Page/PageMultiInfo.cpp
Compute and store CPU header metadata in DeviceGenerator for use by the UI
  • Call a new helper after CPU devices are generated to compute header info from the first processor’s lsCpu map along with core/logical counts
  • Implement calAndSetCpuHeaderInfo to extract model name, vendor ID, architecture, core and thread counts, and cache sizes (L1d/L1i/L2/L3) into a structured QList of key-value pairs
  • Use Common::formatTotalCache to convert per-core cache values into total caches and push final header info into DeviceManager via setCpuHeaderInfo
deepin-devicemanager/src/GenerateDevice/DeviceGenerator.cpp
deepin-devicemanager/src/GenerateDevice/DeviceGenerator.h
Minor structural and metadata updates
  • Add necessary includes for headerinfotablewidget and DeviceCpu to support new functionality
  • Adjust main layout naming from hLayout to vLayout and ensure label/table/detail stacking includes the new header scroll area
  • Update SPDX-FileCopyrightText year ranges in modified files to 2019–2026 or 2022–2026
deepin-devicemanager/src/Page/PageMultiInfo.cpp
deepin-devicemanager/src/Page/PageMultiInfo.h
deepin-devicemanager/src/GenerateDevice/DeviceGenerator.cpp
deepin-devicemanager/src/GenerateDevice/DeviceGenerator.h

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

这份代码 diff 主要是为了在设备管理器中为 CPU 设备添加一个新的头部信息展示区域(HeaderInfo),包括型号、架构、缓存等信息。我将从语法逻辑、代码质量、性能和安全四个方面进行审查。

1. 语法逻辑

优点:

  • 版权更新:更新了文件头部的版权年份(SPDX-FileCopyrightText),符合合规性要求。
  • 逻辑清晰calAndSetCpuHeaderInfo 函数逻辑分段明确,依次检查并添加型号、厂商、架构、核心/线程数以及各级缓存信息。
  • 类型转换:在 PageMultiInfo::updateInfo 中使用了 dynamic_cast<DeviceCpu *> 来判断是否为 CPU 设备,这是处理多态的正确方式。

问题与建议:

  • 除零风险:在 DeviceGenerator.cppcalAndSetCpuHeaderInfo 函数中:
    QPair<QString, QString> threadPerCore(tr("Thread(s)"), QString::number(logicalNum / coreNum));
    虽然前面有 if (coreNum > 0) 的判断,但在极端或异常情况下(例如 coreNum 被意外修改或数据源错误),确保除数安全是好的,但这里逻辑已经防御了。
  • L3 缓存计算参数不一致
    // L1, L2 传入 coreNum
    QString strTotalL1dCache = Common::formatTotalCache(strL1dCache, coreNum);
    // ...
    // L3 却传入了 1
    QString strTotalL3Cache = Common::formatTotalCache(strL3Cache, 1);
    建议:请确认 formatTotalCache 的逻辑。通常 L3 缓存是所有核心共享的,如果 formatTotalCache 是用来计算"总缓存=单核缓存*核心数",那么 L3 传入 1 是正确的(因为它是共享的,不需要乘以核心数)。但如果该函数含义不同,这里可能存在逻辑错误。建议添加注释解释为什么 L3 传入 1 而其他传入 coreNum

2. 代码质量

问题与建议:

  • 代码重复calAndSetCpuHeaderInfo 中处理 L1d, L1i, L2, L3 缓存的代码结构高度重复。
    if (firstProcessorInfo.contains("L1d cache")) {
        QString strL1dCache = firstProcessorInfo.value("L1d cache");
        QString strTotalL1dCache = Common::formatTotalCache(strL1dCache, coreNum);
        if (!strTotalL1dCache.isEmpty()) {
            // ...
        }
    }
    // ... 重复了 3 次
    建议:可以提取一个私有辅助函数,例如 addCacheInfo,传入缓存名称(如 "L1d cache")、显示名称(tr("L1d cache"))和倍率因子(coreNum 或 1),以减少重复代码,提高可读性和可维护性。
  • 命名规范
    • 变量名 lsCpu 在 diff 中未定义但被使用 (lsCpu.at(0)),推测是类成员变量。建议使用更具描述性的名称,如 m_cpuInfoListm_processorList
    • calAndSetCpuHeaderInfo 中的 calcalculate 的缩写。在 Qt/Deepin 代码风格中,通常倾向于完整单词或遵循项目既定规范。如果项目允许缩写,则无问题,否则建议改为 calculateAndSetCpuHeaderInfo
  • 内存管理:在 PageMultiInfo 析构函数中:
    if (mp_HeaderInfoWidget) {
        delete mp_HeaderInfoWidget;
        mp_HeaderInfoWidget = nullptr;
        mp_HeaderInfoContainer = nullptr; // <--- 问题点
    }
    建议mp_HeaderInfoContainermp_HeaderInfoWidget 的子控件(在构造函数中 new DWidget(mp_HeaderInfoWidget)),当父控件 mp_HeaderInfoWidget 被删除时,Qt 的对象树机制会自动删除子控件。将其手动置空是可以的,但逻辑上显得有些多余。更重要的是,如果 mp_HeaderInfoWidget 不为空,mp_HeaderInfoContainer 必然存在,这种写法没问题,但可以更简洁。
  • 布局清理clearLayout 函数实现是正确的,使用了 deleteLater(),这是处理动态删除 UI 控件的安全做法。

3. 代码性能

问题与建议:

  • 频繁的 UI 重建:在 PageMultiInfo::updateInfo 中,每次更新信息时:
    clearLayout(mp_HeaderInfoWidgetLay);
    for (int i = 0; i < headerInfo.size(); ++i) {
        HeaderInfoTableWidget *headerWidget = new HeaderInfoTableWidget(mp_HeaderInfoWidget);
        headerWidget->updateData(headerInfo.at(i));
        mp_HeaderInfoWidgetLay->addWidget(headerWidget);
    }
    这里会销毁并重新创建所有的 HeaderInfoTableWidget。如果 CPU 信息不经常变化,或者 updateInfo 调用频率很高,这会造成不必要的 CPU 和内存开销。
    建议:考虑实现 HeaderInfoTableWidget 的更新接口,如果 Widget 已经存在,只调用 updateData 更新内容,而不是销毁重建。不过,考虑到这是设备管理器,通常只有在用户切换设备页面或刷新时才调用,目前的实现可能也是可以接受的。

4. 代码安全

问题与建议:

  • 空指针解引用风险:在 DeviceGenerator::generatorCpuDevice 中:
    if (lsCpu.size() > 0)
        calAndSetCpuHeaderInfo(lsCpu.at(0), coreNum, logicalNum);
    这里检查了 size() > 0,访问 at(0) 是安全的。但在 calAndSetCpuHeaderInfo 内部,直接使用 firstProcessorInfo.value("...")。如果 firstProcessorInfo 中的键对应的值格式异常(例如不是预期的数字或字符串),可能会影响后续显示。虽然 QMap::value 在键不存在时返回默认构造的值(空字符串),这是安全的。
  • 动态类型转换
    DeviceCpu *cpuInfo = dynamic_cast<DeviceCpu *>(lst.at(0));
    if (cpuInfo) { ... }
    使用 dynamic_cast 是安全的,如果转换失败会返回 nullptr,且代码中进行了判空检查。这是良好的实践。
  • 布局清理的安全性clearLayout 函数中使用了 widget->deleteLater() 而不是 delete widget。这是非常好的做法,因为 deleteLater 会确保在当前事件循环结束后删除对象,避免了在布局事件处理过程中直接删除对象可能导致的崩溃。

总结

这段代码整体质量不错,逻辑清晰,且在内存管理(如 deleteLater)上表现出了较好的安全意识。

主要改进建议:

  1. 重构缓存处理逻辑:将 L1/L2/L3 的处理逻辑提取为公共函数,消除重复代码。
  2. 添加注释:为 Common::formatTotalCache(strL3Cache, 1) 中参数 1 的特殊性添加注释,说明原因。
  3. 版权年份一致性:确保所有相关文件的版权年份更新逻辑一致(目前看起来是统一的)。
  4. UI 优化:如果未来发现性能瓶颈,可考虑优化 updateInfo 中 Widget 的重建逻辑。

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In PageMultiInfo::updateInfo, consider removing the explicit mp_HeaderInfoWidget->resize() call and let the layout manage the scroll area's size, as manual resizing inside a managed layout can lead to unexpected layout behavior on different window sizes or DPI settings.
  • clearLayout() currently assumes the QLayout pointer is non-null and only handles direct widgets; it would be safer to guard against a nullptr and optionally handle nested layouts to avoid potential leaks if the layout ever contains sublayouts in the future.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In PageMultiInfo::updateInfo, consider removing the explicit mp_HeaderInfoWidget->resize() call and let the layout manage the scroll area's size, as manual resizing inside a managed layout can lead to unexpected layout behavior on different window sizes or DPI settings.
- clearLayout() currently assumes the QLayout pointer is non-null and only handles direct widgets; it would be safer to guard against a nullptr and optionally handle nested layouts to avoid potential leaks if the layout ever contains sublayouts in the future.

## Individual Comments

### Comment 1
<location path="deepin-devicemanager/src/GenerateDevice/DeviceGenerator.cpp" line_range="1286-1295" />
<code_context>
+    if (firstProcessorInfo.contains("L1d cache")) {
</code_context>
<issue_to_address>
**issue (bug_risk):** Cache total calculations should guard against coreNum being zero to avoid invalid computations inside formatTotalCache.

In `calAndSetCpuHeaderInfo`, `Common::formatTotalCache` is called for L1/L2 caches with `coreNum` even when it may be zero, unlike the guarded core/thread section. If `formatTotalCache` divides or scales by `coreNum`, this can yield invalid results. Please either guard these calls with `coreNum > 0` or return early when `coreNum <= 0` before computing cache totals.
</issue_to_address>

### Comment 2
<location path="deepin-devicemanager/src/Page/PageMultiInfo.cpp" line_range="68" />
<code_context>
 PageMultiInfo::~PageMultiInfo()
 {
     // 清空指针
</code_context>
<issue_to_address>
**issue (complexity):** Consider simplifying the new CPU header UI integration by relying on Qt parent ownership, extracting CPU-specific helpers, and reducing member state and layout utilities to keep PageMultiInfo easier to read and maintain.

You can keep the feature as-is but reduce complexity and surface area with a few targeted changes.

### 1. Drop manual deletion of `mp_HeaderInfoWidget` / `mp_HeaderInfoContainer`

Qt’s parent ownership already handles these. The explicit `delete` + `nullptr` adds noise and potential for double-delete if parents change.

**Current:**
```cpp
PageMultiInfo::~PageMultiInfo()
{
    // 清空指针
    if (mp_HeaderInfoWidget) {
        delete mp_HeaderInfoWidget;
        mp_HeaderInfoWidget = nullptr;
        mp_HeaderInfoContainer = nullptr;
    }
    if (mp_Table) {
        delete mp_Table;
        mp_Table = nullptr;
    }
    if (mp_Detail) {
        delete mp_Detail;
        mp_Detail = nullptr;
    }
    m_deviceList.clear();
    m_menuControlList.clear();
}
```

**Suggestion:**
Let parents clean up, only delete when no parent:

```cpp
PageMultiInfo::~PageMultiInfo()
{
    // mp_HeaderInfoWidget / mp_HeaderInfoContainer rely on QObject parent deletion

    if (!mp_Table->parent()) {
        delete mp_Table;
    }
    if (!mp_Detail->parent()) {
        delete mp_Detail;
    }

    m_deviceList.clear();
    m_menuControlList.clear();
}
```

If `mp_Table` and `mp_Detail` also always have `this` as parent, you can remove their manual deletes too.

---

### 2. Simplify show/hide & size logic for the scroll area

You already set size policy, min/max and visibility in `initWidgets`. Updating height and resizing on every `updateInfo` call is redundant.

**Current in `updateInfo`:**
```cpp
if (cpuInfo) {
    ...
    mp_HeaderInfoWidget->setMaximumHeight(kHeaderInfoDefaultHeight);
    mp_HeaderInfoWidget->resize(this->width(), kHeaderInfoDefaultHeight);
    mp_HeaderInfoWidget->setVisible(true);
} else {
    mp_HeaderInfoWidget->setVisible(false);
    mp_HeaderInfoWidget->setMaximumHeight(0);
}
```

**Suggestion:** configure once in `initWidgets`, then just toggle visibility:

```cpp
// initWidgets()
mp_HeaderInfoWidget->setMaximumHeight(kHeaderInfoDefaultHeight);
mp_HeaderInfoWidget->setMinimumHeight(0);
mp_HeaderInfoWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
mp_HeaderInfoWidget->setVisible(false);
```

```cpp
// updateInfo()
if (cpuInfo) {
    updateCpuHeaderInfo(headerInfo);
    mp_HeaderInfoWidget->setVisible(true);
} else {
    clearCpuHeaderInfo();
    mp_HeaderInfoWidget->setVisible(false);
}
```

This removes the height juggling and the explicit `resize`.

---

### 3. Extract CPU-specific logic out of `updateInfo`

Right now `updateInfo` handles:

- CPU type detection
- Data retrieval
- Layout management
- Scroll area visibility/size

Splitting that into focused helpers will make `updateInfo` easier to read, without changing behavior.

**Suggestion:**

```cpp
void PageMultiInfo::updateInfo(const QList<DeviceBaseInfo *> &lst)
{
    m_lstDevice = lst;
    if (lst.isEmpty() || !lst.at(0))
        return;

    updateCpuHeaderSection(lst.at(0));  // CPU-specific logic extracted

    m_deviceList.clear();
    m_menuControlList.clear();

    getTableListInfo(lst, m_deviceList, m_menuControlList);
    mp_Table->setVisible(true);
    mp_Table->setFixedHeight(TABLE_HEIGHT);
    mp_Table->updateTable(m_deviceList, m_menuControlList);
    mp_Detail->updateDetail(lst);
}
```

```cpp
void PageMultiInfo::updateCpuHeaderSection(DeviceBaseInfo *device)
{
    auto *cpuInfo = dynamic_cast<DeviceCpu *>(device);
    if (!cpuInfo) {
        clearCpuHeaderInfo();
        mp_HeaderInfoWidget->setVisible(false);
        return;
    }

    QList<QList<QPair<QString, QString>>> headerInfo;
    DeviceManager::instance()->getCpuHeaderInfo(headerInfo);

    auto *layout = cpuHeaderLayout();
    clearLayout(layout);

    for (const auto &group : headerInfo) {
        auto *headerWidget = new HeaderInfoTableWidget(mp_HeaderInfoWidget);
        headerWidget->updateData(group);
        layout->addWidget(headerWidget);
    }

    mp_HeaderInfoWidget->setVisible(true);
}

void PageMultiInfo::clearCpuHeaderInfo()
{
    auto *layout = cpuHeaderLayout();
    clearLayout(layout);
}
```

This keeps `updateInfo` focused on orchestration and isolates CPU-specific UI behavior.

---

### 4. Avoid `mp_HeaderInfoWidgetLay` as a member if not necessary

You only need the layout when populating/clearing CPU header info. It doesn’t have to be a long-lived member; reducing member state lowers cognitive load.

**Current constructor:**
```cpp
, mp_HeaderInfoWidget(new DScrollArea(this))
, mp_HeaderInfoContainer(new DWidget(mp_HeaderInfoWidget))
, mp_HeaderInfoWidgetLay(new QVBoxLayout(mp_HeaderInfoContainer))
```

**Suggestion:** keep only the widget/container members; get the layout on demand:

```cpp
// header
QVBoxLayout *cpuHeaderLayout() const;

// cpp
QVBoxLayout *PageMultiInfo::cpuHeaderLayout() const
{
    return qobject_cast<QVBoxLayout *>(mp_HeaderInfoContainer->layout());
}
```

Then in `updateCpuHeaderSection` / `clearCpuHeaderInfo` use `cpuHeaderLayout()` instead of `mp_HeaderInfoWidgetLay`. You can drop `mp_HeaderInfoWidgetLay` from the class members and constructor initializer list.

---

### 5. Make `clearLayout` clearly scoped and/or truly generic

Right now `clearLayout` is:

- A member method
- Only used for the CPU header layout
- Written as if it were a generic utility, but not recursive

Two options:

**a) Make it clearly local to CPU header**

Rename and keep behaviour explicit:

```cpp
void PageMultiInfo::clearCpuHeaderLayout(QLayout *layout)
{
    QLayoutItem *item;
    while ((item = layout->takeAt(0)) != nullptr) {
        if (QWidget *widget = item->widget()) {
            widget->deleteLater();
        }
        delete item;
    }
}
```

Call it only from CPU-specific helpers to avoid suggesting it’s a generic utility.

**b) Or make it generic and recursive if you intend broader reuse:**

```cpp
void clearLayoutRecursive(QLayout *layout)
{
    QLayoutItem *item;
    while ((item = layout->takeAt(0)) != nullptr) {
        if (QWidget *widget = item->widget()) {
            widget->deleteLater();
        } else if (QLayout *childLayout = item->layout()) {
            clearLayoutRecursive(childLayout);
            delete childLayout;
        }
        delete item;
    }
}
```

And either keep it `static` in the `.cpp` or in an anonymous namespace if it’s not meant to be part of the class API.

---

These changes keep all behavior but reduce manual lifetime management, member state, and responsibility mixing, which should address most of the “too complex” concerns without undoing the feature.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread deepin-devicemanager/src/GenerateDevice/DeviceGenerator.cpp
Comment thread deepin-devicemanager/src/Page/PageMultiInfo.cpp
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: GongHeng2017, max-lvs

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@GongHeng2017
Copy link
Copy Markdown
Contributor Author

/forcemerge

@deepin-bot
Copy link
Copy Markdown
Contributor

deepin-bot Bot commented May 7, 2026

This pr force merged! (status: unstable)

@deepin-bot deepin-bot Bot merged commit 674a9cf into linuxdeepin:develop/eagle May 7, 2026
20 of 22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants