Skip to content

Feat: add HeaderInfoTableWidget for displaying device information#650

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

Feat: add HeaderInfoTableWidget for displaying device information#650
deepin-bot[bot] merged 1 commit intolinuxdeepin:develop/eaglefrom
GongHeng2017:202605071004-dev-eagle-feat

Conversation

@GongHeng2017
Copy link
Copy Markdown
Contributor

@GongHeng2017 GongHeng2017 commented May 7, 2026

Add a custom table widget with rounded border and alternating row colors for displaying device information as key-value pairs.

  • Add HeaderInfoDelegate for custom text color handling in selection
  • Add HeaderInfoTableWidget with rounded border painting and vertical divider
  • Support dynamic height adjustment based on content
  • Use DPalette for consistent theming with active/inactive states

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

Summary by Sourcery

Introduce a styled table widget and delegate for displaying header/device information with theming support.

New Features:

  • Add HeaderInfoTableWidget for displaying key-value device information with rounded borders, alternating row colors, and dynamic height based on content.
  • Add HeaderInfoDelegate to control text coloring based on selection state using DPalette theming.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 7, 2026

Reviewer's Guide

Introduces a new HeaderInfoTableWidget and its custom delegate to display device key-value information in a rounded, themable table with alternating row colors and dynamic height, using DTK palettes for active/inactive states and a custom frame border and divider line.

Sequence diagram for updating and painting HeaderInfoTableWidget

sequenceDiagram
    actor User
    participant DeviceDetailsView
    participant HeaderInfoTableWidget
    participant HeaderInfoDelegate
    participant DApplication
    participant DPaletteHelper

    User->>DeviceDetailsView: selectDevice(device)
    DeviceDetailsView->>DeviceDetailsView: buildKeyValuePairs(device)
    DeviceDetailsView->>HeaderInfoTableWidget: updateData(data)
    HeaderInfoTableWidget->>HeaderInfoTableWidget: resetTableContents()
    HeaderInfoTableWidget->>HeaderInfoTableWidget: setRowCount(nRow)
    loop for each row
        HeaderInfoTableWidget->>DApplication: activeWindow()
        DApplication-->>HeaderInfoTableWidget: window
        HeaderInfoTableWidget->>DPaletteHelper: palette(widget)
        DPaletteHelper-->>HeaderInfoTableWidget: palette
        HeaderInfoTableWidget->>HeaderInfoTableWidget: createItemsAndSetBackground()
    end
    HeaderInfoTableWidget->>HeaderInfoTableWidget: adjustFixedHeight()

    Note over HeaderInfoTableWidget: Qt triggers paintEvent and delegate paint during rendering

    HeaderInfoTableWidget->>HeaderInfoTableWidget: paintEvent(event)
    HeaderInfoTableWidget->>DApplication: activeWindow()
    DApplication-->>HeaderInfoTableWidget: window
    HeaderInfoTableWidget->>DPaletteHelper: palette(widget)
    DPaletteHelper-->>HeaderInfoTableWidget: palette
    HeaderInfoTableWidget->>HeaderInfoTableWidget: drawRoundedBorderAndDivider()

    HeaderInfoTableWidget->>HeaderInfoDelegate: paint(painter, option, index)
    HeaderInfoDelegate->>DApplication: activeWindow()
    DApplication-->>HeaderInfoDelegate: window
    HeaderInfoDelegate->>DPaletteHelper: palette(widget)
    DPaletteHelper-->>HeaderInfoDelegate: palette
    alt itemSelected
        HeaderInfoDelegate->>HeaderInfoDelegate: setHighlightedTextColor()
    else itemNotSelected
        HeaderInfoDelegate->>HeaderInfoDelegate: setNormalTextColor()
    end
    HeaderInfoDelegate->>HeaderInfoDelegate: QStyledItemDelegate::paint()
Loading

Class diagram for the new HeaderInfoTableWidget and HeaderInfoDelegate

classDiagram
    class DWidget
    class DTableWidget
    DTableWidget --|> DWidget

    class HeaderInfoDelegate {
        +HeaderInfoDelegate(QObject *parent)
        +void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    }

    class HeaderInfoTableWidget {
        +HeaderInfoTableWidget(DWidget *parent)
        +void updateData(QList~QPair~QString,QString~~ data)
        +void paintEvent(QPaintEvent *event)
        -void initUI()
        -void resetTableContents()
        -HeaderInfoDelegate *m_delegate
    }

    HeaderInfoTableWidget --|> DTableWidget
    HeaderInfoTableWidget *-- HeaderInfoDelegate

    class DApplication
    class DPaletteHelper
    class DPalette

    HeaderInfoTableWidget ..> DApplication : uses
    HeaderInfoTableWidget ..> DPaletteHelper : uses
    HeaderInfoTableWidget ..> DPalette : uses
    HeaderInfoDelegate ..> DApplication : uses
    HeaderInfoDelegate ..> DPaletteHelper : uses
    HeaderInfoDelegate ..> DPalette : uses
Loading

File-Level Changes

Change Details Files
Add HeaderInfoTableWidget for displaying key-value device information with themable rounded table UI and dynamic sizing.
  • Create HeaderInfoTableWidget subclass of DTableWidget with two fixed columns and non-editable, non-selectable cells for key-value pairs.
  • Implement updateData to clear existing contents, populate rows with alternating background colors from DPalette, and adjust fixed height based on row count using ROW_HEIGHT.
  • Configure table appearance in initUI, including no frame/grid, hidden headers, alternating row colors, custom delegate, default section sizes, and translucent, frameless window attributes.
  • Override paintEvent to draw a rounded border and frame using DPalette FrameBorder color and add a vertical divider between the two columns.
deepin-devicemanager/src/Widget/headerinfotablewidget.cpp
deepin-devicemanager/src/Widget/headerinfotablewidget.h
Add HeaderInfoDelegate to control text color for selected and normal states using DTK palette.
  • Create HeaderInfoDelegate subclass of QStyledItemDelegate and override paint to adjust palette text colors based on selection state.
  • Use DApplication::activeWindow and DPaletteHelper to select appropriate color group (Active/Inactive) and apply HighlightedText or Text colors to QPalette::Text and QPalette::WindowText before delegating to base paint.
deepin-devicemanager/src/Widget/headerinfotableDelegate.cpp
deepin-devicemanager/src/Widget/headerinfotableDelegate.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

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 3 issues, and left some high level feedback:

  • The vertical divider position is currently hard-coded to 179 while the column width is set to 180; consider deriving the divider x-position from the actual first-column width (e.g., columnWidth(0)) to keep layout consistent if column sizing changes.
  • In updateData, setFixedHeight(0) for the empty case may cause layout glitches; it can be safer to use a minimal height or rely on sizeHint to avoid the widget effectively disappearing in some layouts.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The vertical divider position is currently hard-coded to 179 while the column width is set to 180; consider deriving the divider x-position from the actual first-column width (e.g., `columnWidth(0)`) to keep layout consistent if column sizing changes.
- In `updateData`, `setFixedHeight(0)` for the empty case may cause layout glitches; it can be safer to use a minimal height or rely on sizeHint to avoid the widget effectively disappearing in some layouts.

## Individual Comments

### Comment 1
<location path="deepin-devicemanager/src/Widget/headerinfotablewidget.cpp" line_range="49-55" />
<code_context>
+    }
+
+    // 调整控件高度,使内容刚好完全显示,不出现垂直滚动条
+    if (nRow > 0) {
+        // 为了保持底部圆角,给表格高度留出 2px 余量;避免内容铺满viewport导致圆角被覆盖
+        setFixedHeight(ROW_HEIGHT * nRow + 2);
+    } else {
+        setFixedHeight(0);
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Avoid assuming row height equals ROW_HEIGHT when setting the table height.

`ROW_HEIGHT * nRow` only works if every row is exactly `ROW_HEIGHT`, but actual row heights can vary with styles, fonts, or DPI, leading to gaps or unexpected scrollbars. Instead, derive the height from the table itself, e.g.:

```cpp
int totalHeight = verticalHeader()->length();
setFixedHeight(totalHeight + 2);
```

This preserves the 2px margin while matching the real row heights.

```suggestion
    // 调整控件高度,使内容刚好完全显示,不出现垂直滚动条
    if (nRow > 0) {
        // 为了保持底部圆角,给表格高度留出 2px 余量;避免内容铺满 viewport 导致圆角被覆盖
        // 不再假设每行高度等于 ROW_HEIGHT,而是从 verticalHeader() 实际计算所有行的总高度
        int totalHeight = 0;
        if (auto *vh = verticalHeader()) {
            totalHeight = vh->length();
        } else {
            // 兜底:如果 verticalHeader 不可用,则退回到原有的按行数估算高度逻辑
            totalHeight = ROW_HEIGHT * nRow;
        }
        setFixedHeight(totalHeight + 2);
    } else {
        setFixedHeight(0);
    }
```
</issue_to_address>

### Comment 2
<location path="deepin-devicemanager/src/Widget/headerinfotablewidget.cpp" line_range="114-119" />
<code_context>
+    painter.drawRoundedRect(rectIn, radius, radius);
+
+    // Draw vertical divider between first and second columns (same as DetailTreeView)
+    QLine vline(rect.topLeft().x() + 179, rect.topLeft().y(), rect.bottomLeft().x() + 179, rect.bottomLeft().y());
+    painter.drawLine(vline);
+}
+
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Avoid hardcoding the vertical divider position; derive it from the column geometry instead.

The `179` offset assumes a fixed first-column width of 180, so the divider will misalign if that width changes (e.g. user resize or style/layout updates). Instead, compute the divider position from the actual column geometry, e.g.:

```cpp
int dividerX = columnViewportPosition(1); // or columnWidth(0)
QLine vline(rect.topLeft().x() + dividerX - 1,
            rect.topLeft().y(),
            rect.bottomLeft().x() + dividerX - 1,
            rect.bottomLeft().y());
```

This keeps the divider aligned with runtime column width changes.

```suggestion
    painter.drawRoundedRect(rectIn, radius, radius);

    // Draw vertical divider between first and second columns (same as DetailTreeView)
    const int dividerX = columnViewportPosition(1);
    if (dividerX > 0) {
        QLine vline(rect.topLeft().x() + dividerX - 1,
                    rect.topLeft().y(),
                    rect.bottomLeft().x() + dividerX - 1,
                    rect.bottomLeft().y());
        painter.drawLine(vline);
    }
}
```
</issue_to_address>

### Comment 3
<location path="deepin-devicemanager/src/Widget/headerinfotablewidget.cpp" line_range="26" />
<code_context>
+    initUI();
+}
+
+void HeaderInfoTableWidget::updateData(const QList<QPair<QString, QString>> &data)
+{
+    resetTableContents();
</code_context>
<issue_to_address>
**issue (complexity):** Consider extracting shared palette logic, cell creation, border drawing, and height calculation into small helpers with named constants to remove duplication and magic numbers while preserving behavior.

You can keep the current behavior while trimming quite a bit of complexity with a few small, local helpers and constants.

### 1. Remove duplicated palette / color-group logic

`updateData` and `paintEvent` both compute `wnd`, `cg`, and `palette`. Centralize this:

```cpp
namespace {
constexpr int kBorderRadius = 8;
constexpr int kBorderWidth  = 1;
constexpr int kDividerSectionIndex = 0; // divider after column 0
constexpr int kHeightPadding = 2;

inline DPalette::ColorGroup currentColorGroup() {
    return DApplication::activeWindow() ? DPalette::Active : DPalette::Inactive;
}

inline DPalette currentPalette(const QWidget *w) {
    return DPaletteHelper::instance()->palette(w);
}
} // namespace
```

Then in `updateData` and `paintEvent`:

```cpp
void HeaderInfoTableWidget::updateData(const QList<QPair<QString, QString>> &data)
{
    resetTableContents();
    const int nRow = data.size();
    setRowCount(nRow);

    const auto cg      = currentColorGroup();
    const auto palette = currentPalette(this);
    const QColor colorEven = palette.color(cg, DPalette::Base);
    const QColor colorOdd  = palette.color(cg, DPalette::ItemBackground);
    ...
}
```

```cpp
void HeaderInfoTableWidget::paintEvent(QPaintEvent *event)
{
    DTableWidget::paintEvent(event);

    const auto cg      = currentColorGroup();
    const auto palette = currentPalette(this);
    ...
}
```

### 2. Factor out cell creation to avoid duplicated item setup

The first/second column logic is copy-pasted. A tiny helper keeps flags/background logic in one place:

```cpp
QTableWidgetItem *HeaderInfoTableWidget::createCell(const QString &text,
                                                    int row,
                                                    int column,
                                                    const QColor &bg)
{
    auto *item = new QTableWidgetItem(text);
    item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
    item->setBackground(bg);
    setItem(row, column, item);
    return item;
}
```

Use it in the loop:

```cpp
for (int i = 0; i < nRow; ++i) {
    const QColor bg = (i % 2 == 0) ? colorEven : colorOdd;
    createCell(data[i].first,  i, 0, bg);
    createCell(data[i].second, i, 1, bg);
}
```

Now any change to flags/background is made once.

### 3. Extract border/drawer logic from `paintEvent` and remove magic numbers

Right now `paintEvent` mixes: base painting, geometry, rounded border, and divider. You can still call it from `paintEvent`, but move the details out and replace magic numbers with named constants:

```cpp
void HeaderInfoTableWidget::drawBorder(QPainter &painter,
                                       const QRect &rect,
                                       const DPalette &palette,
                                       DPalette::ColorGroup cg) const
{
    const QRect outerRect = rect.adjusted(0, 0, -1, -1);
    const QRect innerRect(
        outerRect.x() + kBorderWidth,
        outerRect.y() + kBorderWidth,
        outerRect.width()  - 2 * kBorderWidth,
        outerRect.height() - 2 * kBorderWidth
    );

    QPainterPath outerPath;
    outerPath.addRoundedRect(outerRect, kBorderRadius, kBorderRadius);

    QPainterPath innerPath;
    innerPath.addRoundedRect(innerRect, kBorderRadius, kBorderRadius);

    const QPainterPath framePath = outerPath.subtracted(innerPath);
    const QBrush frameBrush(palette.color(cg, DPalette::FrameBorder));

    painter.fillPath(framePath, frameBrush);

    QPen pen = painter.pen();
    pen.setWidth(kBorderWidth);
    pen.setColor(palette.color(cg, DPalette::FrameBorder));
    painter.setPen(pen);
    painter.drawRoundedRect(innerRect, kBorderRadius, kBorderRadius);
}
```

For the divider, derive it from the header instead of using `179`:

```cpp
void HeaderInfoTableWidget::drawColumnDivider(QPainter &painter, const QRect &rect) const
{
    const auto *header = horizontalHeader();
    if (!header || header->count() <= kDividerSectionIndex)
        return;

    // Divider at the end of the first section
    const int dividerX = header->sectionPosition(kDividerSectionIndex) +
                         header->sectionSize(kDividerSectionIndex);

    const QLine vline(dividerX, rect.top(), dividerX, rect.bottom());
    painter.drawLine(vline);
}
```

Then `paintEvent` becomes shorter and easier to follow:

```cpp
void HeaderInfoTableWidget::paintEvent(QPaintEvent *event)
{
    DTableWidget::paintEvent(event);

    const auto cg      = currentColorGroup();
    const auto palette = currentPalette(this);

    QPainter painter(viewport());
    painter.setRenderHint(QPainter::Antialiasing, true);

    const QRect rect = viewport()->rect();
    drawBorder(painter, rect, palette, cg);
    drawColumnDivider(painter, rect);
}
```

### 4. Isolate height logic and remove `+ 2` magic number

`ROW_HEIGHT * nRow + 2` is non-obvious. Use a constant and a helper:

```cpp
void HeaderInfoTableWidget::updateFixedHeight(int rowCount)
{
    if (rowCount > 0) {
        setFixedHeight(ROW_HEIGHT * rowCount + kHeightPadding);
    } else {
        setFixedHeight(0);
    }
}
```

Call it from `updateData`:

```cpp
void HeaderInfoTableWidget::updateData(const QList<QPair<QString, QString>> &data)
{
    ...
    updateFixedHeight(nRow);
}
```

This keeps all behavior (rounded corners, colors, height behavior) intact but reduces duplication, centralizes layout-related numbers, and makes future tweaks safer and cheaper.
</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/Widget/headerinfotablewidget.cpp
Comment thread deepin-devicemanager/src/Widget/headerinfotablewidget.cpp
Comment thread deepin-devicemanager/src/Widget/headerinfotablewidget.cpp
@GongHeng2017
Copy link
Copy Markdown
Contributor Author

/forcemerge

1 similar comment
@GongHeng2017
Copy link
Copy Markdown
Contributor Author

/forcemerge

@GongHeng2017 GongHeng2017 requested a review from max-lvs May 7, 2026 05:37
@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

1 similar comment
@GongHeng2017
Copy link
Copy Markdown
Contributor Author

/forcemerge

@GongHeng2017
Copy link
Copy Markdown
Contributor Author

/merge

@GongHeng2017 GongHeng2017 force-pushed the 202605071004-dev-eagle-feat branch from eba0fa4 to cffa1c9 Compare May 7, 2026 05:50
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

  • 敏感词检查失败, 检测到1个文件存在敏感词
详情
{
    "deepin-devicemanager/src/Tool/commontools.cpp": [
        {
            "line": "        return \"https://driver.uniontech.com/api/v1/drive/search\";",
            "line_number": 167,
            "rule": "S35",
            "reason": "Url link | 162cef9d4a"
        },
        {
            "line": "        return \"https://driver.uniontech.com/api/v1/drive/search\";",
            "line_number": 171,
            "rule": "S35",
            "reason": "Url link | 162cef9d4a"
        },
        {
            "line": "        return \"https://drive-pre.uniontech.com/api/v1/drive/search\";",
            "line_number": 173,
            "rule": "S35",
            "reason": "Url link | 0e010283c1"
        }
    ]
}

Add a custom table widget with rounded border and alternating row colors
for displaying device information as key-value pairs.

- Add HeaderInfoDelegate for custom text color handling in selection
- Add HeaderInfoTableWidget with rounded border painting and vertical divider
- Support dynamic height adjustment based on content
- Use DPalette for consistent theming with active/inactive states

Log: add feature for cpu info show.
Task: https://pms.uniontech.com/task-view-387697.html
@GongHeng2017 GongHeng2017 force-pushed the 202605071004-dev-eagle-feat branch from cffa1c9 to b8f46c8 Compare May 7, 2026 05:53
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

  • 敏感词检查失败, 检测到1个文件存在敏感词
详情
{
    "deepin-devicemanager/src/Tool/commontools.cpp": [
        {
            "line": "        return \"https://driver.uniontech.com/api/v1/drive/search\";",
            "line_number": 167,
            "rule": "S35",
            "reason": "Url link | 162cef9d4a"
        },
        {
            "line": "        return \"https://driver.uniontech.com/api/v1/drive/search\";",
            "line_number": 171,
            "rule": "S35",
            "reason": "Url link | 162cef9d4a"
        },
        {
            "line": "        return \"https://drive-pre.uniontech.com/api/v1/drive/search\";",
            "line_number": 173,
            "rule": "S35",
            "reason": "Url link | 0e010283c1"
        }
    ]
}

@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

Git Diff 代码审查报告

1. 语法逻辑审查

1.1 头文件包含

  • commontools.cpp 中新增了 QRegularExpressionQRegularExpressionMatch 的包含,但在当前 diff 中没有看到使用,可能是为后续功能预留的。

1.2 HeaderInfoDelegate 类

  • paint 方法中正确处理了选中状态和普通状态下的文本颜色
  • 使用了 DTK 的 DPaletteHelper 获取调色板,符合 DTK 应用开发规范

1.3 HeaderInfoTableWidget 类

  • updateData 方法中正确处理了表格数据的更新
  • initUI 方法中设置了表格的基本属性
  • paintEvent 中实现了自定义绘制逻辑,包括圆角边框和列分隔线

2. 代码质量审查

2.1 命名规范

  • 类名、方法名和变量名遵循驼峰命名法,符合 Qt 命名规范
  • 常量使用 k 前缀,如 kColumnCount,符合常见命名习惯

2.2 代码结构

  • 新增的类结构清晰,职责单一
  • 头文件和实现文件分离良好
  • 使用了 explicit 关键字防止隐式类型转换

2.3 代码注释

  • 文件头有正确的 SPDX 版权声明
  • 缺少类和方法的功能注释,建议添加

3. 代码性能审查

3.1 内存管理

  • updateData 方法中每次调用都会创建新的 QTableWidgetItem 对象,没有看到旧对象的删除逻辑
    • 建议:在 resetTableContents 中确保正确清理旧对象,或使用 clearContents 代替 clear

3.2 绘制性能

  • paintEvent 中每次都创建新的 QPainterPathQPainter 对象
    • 建议:考虑缓存这些对象,如果可能的话

3.3 颜色获取

  • 在多个方法中重复获取 DPalette 和活动窗口状态
    • 建议:可以考虑在类中缓存这些值,并在窗口状态改变时更新

4. 代码安全审查

4.1 空指针检查

  • HeaderInfoDelegate::paint 中对 DApplication::activeWindow() 的返回值进行了检查
  • HeaderInfoTableWidget::updateData 中没有对 this 进行空指针检查,虽然作为成员函数不太可能为空,但作为良好实践可以添加

4.2 边界检查

  • updateData 中对 data 列表进行了遍历,但没有检查 data 中的字符串是否为空
  • paintEvent 中的 vline 绘制使用了硬编码的偏移量 179,可能与 initUI 中设置的默认列宽 180 不一致

4.3 资源管理

  • m_delegate 作为成员变量,在析构时没有显式删除
    • 建议:由于使用了 new HeaderInfoDelegate(this),Qt 的父子对象机制会自动管理内存,但显式声明析构函数会更清晰

5. 改进建议

  1. 添加文档注释

    /**
     * @brief 自定义表格委托,用于处理表格项的绘制
     */
    class HeaderInfoDelegate : public QStyledItemDelegate
  2. 修复列分隔线位置

    // 替换硬编码的 179,使用实际列宽
    int firstColumnWidth = columnWidth(0);
    QLine vline(rect.topLeft().x() + firstColumnWidth - 1, rect.topLeft().y(), 
                rect.bottomLeft().x() + firstColumnWidth - 1, rect.bottomLeft().y());
  3. 优化内存管理

    void HeaderInfoTableWidget::resetTableContents()
    {
        // 使用 clearContents 而不是 clear,保留表头
        clearContents();
        setRowCount(0);
    }
  4. 添加颜色缓存

    // 在类中添加成员变量
    private:
        QColor m_colorEven;
        QColor m_colorOdd;
        QColor m_borderColor;
        bool m_colorsCached = false;
    
    // 添加方法更新缓存的颜色
    void HeaderInfoTableWidget::updateColorCache()
    {
        QWidget *wnd = DApplication::activeWindow();
        DPalette::ColorGroup cg = wnd ? DPalette::Active : DPalette::Inactive;
        auto palette = DPaletteHelper::instance()->palette(this);
        m_colorEven = palette.color(cg, DPalette::Base);
        m_colorOdd = palette.color(cg, DPalette::ItemBackground);
        m_borderColor = palette.color(cg, DPalette::FrameBorder);
        m_colorsCached = true;
    }
  5. 添加析构函数

    HeaderInfoTableWidget::~HeaderInfoTableWidget()
    {
        // 显式声明析构函数,即使为空,也有助于代码维护
    }
  6. 考虑使用信号槽机制

    // 在类中添加信号,当数据更新时通知
    signals:
        void dataUpdated();
    
    // 在 updateData 方法末尾发出信号
    emit dataUpdated();

6. 总体评价

这段代码实现了自定义表格控件,用于显示带有圆角边框和交替行颜色的信息表格。代码结构清晰,遵循了 Qt 和 DTK 的开发规范。主要改进点在于性能优化、资源管理和一些细节处理,如硬编码值的替换和文档注释的添加。

@GongHeng2017
Copy link
Copy Markdown
Contributor Author

/merge

@deepin-bot deepin-bot Bot merged commit 435c9ed into linuxdeepin:develop/eagle May 7, 2026
22 checks passed
@deepin-bot
Copy link
Copy Markdown
Contributor

deepin-bot Bot commented May 7, 2026

This pr force merged! (status: unknown)

3 similar comments
@deepin-bot
Copy link
Copy Markdown
Contributor

deepin-bot Bot commented May 7, 2026

This pr force merged! (status: unknown)

@deepin-bot
Copy link
Copy Markdown
Contributor

deepin-bot Bot commented May 7, 2026

This pr force merged! (status: unknown)

@deepin-bot
Copy link
Copy Markdown
Contributor

deepin-bot Bot commented May 7, 2026

This pr force merged! (status: unknown)

@deepin-bot
Copy link
Copy Markdown
Contributor

deepin-bot Bot commented May 7, 2026

This pr cannot be merged! (status: unknown)

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