Skip to content

fix(export): align table header and content in exported TXT file#657

Merged
deepin-bot[bot] merged 1 commit intolinuxdeepin:masterfrom
GongHeng2017:202605081641-master-fix
May 9, 2026
Merged

fix(export): align table header and content in exported TXT file#657
deepin-bot[bot] merged 1 commit intolinuxdeepin:masterfrom
GongHeng2017:202605081641-master-fix

Conversation

@GongHeng2017
Copy link
Copy Markdown
Contributor

Replace fixed QTextStream::setFieldWidth with display-width-aware padding. Add displayWidth() to calculate CJK characters as 1.5 columns, and use two-pass scanning in EXPORT_TO_TXT to compute per-column max width for accurate alignment.

修复导出TXT文件中表头与内容列不对齐的问题。
用基于显示宽度的空格填充替换固定setFieldWidth方式,
新增displayWidth计算CJK字符为1.5列宽度,
通过两遍扫描计算每列最大宽度实现精确对齐。

Log: 修复导出TXT文件表头与内容列不对齐
Bug: https://pms.uniontech.com/bug-view-360187.html
Influence: 导出TXT文件时,表头和内容的列能正确对齐,中英文混排场景下不再错位。

Replace fixed QTextStream::setFieldWidth with display-width-aware
padding. Add displayWidth() to calculate CJK characters as 1.5 columns,
and use two-pass scanning in EXPORT_TO_TXT to compute per-column max
width for accurate alignment.

修复导出TXT文件中表头与内容列不对齐的问题。
用基于显示宽度的空格填充替换固定setFieldWidth方式,
新增displayWidth计算CJK字符为1.5列宽度,
通过两遍扫描计算每列最大宽度实现精确对齐。

Log: 修复导出TXT文件表头与内容列不对齐
Bug: https://pms.uniontech.com/bug-view-360187.html
Influence: 导出TXT文件时,表头和内容的列能正确对齐,中英文混排场景下不再错位。
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.

Sorry @GongHeng2017, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

Git Diff 代码审查报告

整体评价

这段代码主要改进了设备信息输出到文本文件时的表格格式化功能。主要变更包括:

  1. 新增了displayWidth函数来计算字符串的显示宽度(区分CJK字符和其他字符)
  2. 修改了tableInfoToTxttableHeaderToTxt函数,使其接受列宽参数
  3. 在宏定义中增加了计算每列最大宽度的逻辑,使表格对齐更精确

语法逻辑分析

优点

  1. 新增的displayWidth函数逻辑清晰,正确处理了CJK字符和其他字符的宽度差异
  2. 表格输出逻辑改进后,能够根据实际内容动态调整列宽,使输出更美观
  3. 使用qMax确保填充宽度不为负数,提高了代码健壮性

潜在问题

  1. displayWidth函数中,CJK字符的判断条件可能不够全面:

    if (code > 0x7E || (code >= 0xA1 && code <= 0xFF))

    这个条件可能无法覆盖所有CJK字符范围,建议使用Qt内置的字符分类函数。

  2. tableHeaderToTxt函数中,循环条件是m_TableHeaderTr.size() - 1,而tableInfoToTxt函数中没有减1:

    for (int col = 0; col < m_TableHeaderTr.size() - 1; ++col)
    for (int col = 0; col < m_TableDataTr.size(); ++col)

    这可能导致表头和数据的列数不一致,需要确认这是否是预期行为。

代码质量建议

  1. 字符宽度计算优化

    double DeviceBaseInfo::displayWidth(const QString &str)
    {
        double width = 0;
        for (const QChar &ch : str) {
            // 使用Qt内置函数判断字符是否为CJK字符
            if (ch.script() == QChar::Script_Han || 
                ch.script() == QChar::Script_Hiragana || 
                ch.script() == QChar::Script_Katakana ||
                ch.script() == QChar::Script_Hangul) {
                width += 1.5;
            } else {
                width += 1;
            }
        }
        return width;
    }
  2. 列数一致性检查

    void DeviceBaseInfo::tableInfoToTxt(QTextStream &out, const QList<double> &colWidths)
    {
        // ... 前面的代码不变 ...
        
        // 确保列数一致
        int colCount = qMin(m_TableDataTr.size(), colWidths.size());
        for (int col = 0; col < colCount; ++col) {
            double w = colWidths[col];
            int pad = qMax(0, int(w - displayWidth(m_TableDataTr[col])));
            out << m_TableDataTr[col] << QString(pad, ' ');
        }
        
        // ... 后面的代码不变 ...
    }
  3. 添加边界检查
    在宏定义中,应该检查_colWidths的大小是否足够:

    if (_w > _colWidths[_c]) _colWidths[_c] = _w;

    改为:

    if (_c < _colWidths.size() && _w > _colWidths[_c]) _colWidths[_c] = _w;

性能优化建议

  1. 缓存计算结果
    如果displayWidth会被频繁调用,可以考虑缓存结果:

    double DeviceBaseInfo::displayWidth(const QString &str)
    {
        static QHash<QString, double> cache;
        if (cache.contains(str)) {
            return cache.value(str);
        }
        
        double width = 0;
        for (const QChar &ch : str) {
            // ... 计算逻辑 ...
        }
        
        cache.insert(str, width);
        return width;
    }
  2. 优化宏定义中的列宽计算
    当前实现需要遍历所有数据两次(一次计算宽度,一次输出),可以考虑合并这两次操作:

    // 先计算列宽
    QList<double> _colWidths;
    const QStringList &_hdr = deviceLst[0]->getTableHeader();
    int _colCount = _hdr.size() - 1;
    for (int _c = 0; _c < _colCount; ++_c)
        _colWidths.append(DeviceBaseInfo::displayWidth(_hdr[_c]) + 4);
    
    // 输出表头
    deviceLst[0]->tableHeaderToTxt(out, _colWidths);
    
    // 输出数据行,同时更新列宽(如果需要)
    foreach (auto _dev, deviceLst) {
        const QStringList &_dat = _dev->getTableData();
        for (int _c = 0; _c < qMin(_dat.size(), _colCount); ++_c) {
            double _w = DeviceBaseInfo::displayWidth(_dat[_c]) + 4;
            if (_w > _colWidths[_c]) _colWidths[_c] = _w;
        }
        _dev->tableInfoToTxt(out, _colWidths);
    }

安全性建议

  1. 输入验证
    displayWidth函数中,可以添加输入验证:

    double DeviceBaseInfo::displayWidth(const QString &str)
    {
        if (str.isEmpty()) {
            return 0.0;
        }
        
        // ... 其余代码 ...
    }
  2. 防止整数溢出
    在计算填充宽度时,确保不会发生整数溢出:

    int pad = qMax(0, qMin(int(w - displayWidth(m_TableDataTr[col])), INT_MAX));
  3. 空指针检查
    在宏定义中,添加对deviceLstdeviceLst[0]的空指针检查:

    if (deviceLst.size() > 1 && deviceLst[0] != nullptr) {
        // ... 其余代码 ...
    }

总结

这段代码改进了设备信息输出到文本文件时的表格格式化功能,整体逻辑清晰,但在字符宽度判断、列数一致性和边界检查方面还有改进空间。建议按照上述建议进行优化,以提高代码的健壮性、可维护性和性能。

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: GongHeng2017, lzwind

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

/merge

@deepin-bot deepin-bot Bot merged commit 1ebfff9 into linuxdeepin:master May 9, 2026
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