You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现QTableWidget/QListWidget圆角显示(裁剪边角单元格)

QTableWidget 圆角效果实现方案

针对你遇到的表格圆角需求,结合已实现的选中色、自定义单元格背景色,提供两种可行方案:

方案一:QFrame 裁剪(推荐)

利用QFrame的裁剪特性,将表格放入frame中,自动切掉超出圆角的部分,不影响现有样式:

  1. UI布局调整:
    将QTableWidget作为QFrame的子控件,通过布局让表格自适应frame大小。

  2. 设置Frame样式与裁剪:

    // 代码配置Frame
    ui->tableFrame->setStyleSheet(R"(
        QFrame {
            border: 1px solid #000;
            border-radius: 5px;
            background: transparent;
        }
    )");
    ui->tableFrame->setAttribute(Qt::WA_TranslucentBackground);
    // 启用圆角裁剪
    ui->tableFrame->setMask(ui->tableFrame->rect().toRoundedRect(5, 5));
    
  3. 配置表格透明背景:
    保留已实现的选中样式,同时将表格背景设为透明,避免覆盖frame的圆角:

    ui->tableWidget->setStyleSheet(R"(
        QTableWidget {
            background: transparent;
            border: none;
        }
        QTableWidget::item:selected {
            background-color: #FF0000;
        }
    )");
    

方案二:自定义Delegate 精确控制边角单元格

针对边角单元格单独绘制圆角背景,保留其他单元格的正常样式:

  1. 实现自定义Delegate:

    class RoundedCornerDelegate : public QStyledItemDelegate
    {
        Q_OBJECT
    public:
        explicit RoundedCornerDelegate(int radius, QWidget *parent = nullptr) 
            : QStyledItemDelegate(parent), m_radius(radius) {}
    
        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
        {
            QStyleOptionViewItem opt = option;
            initStyleOption(&opt, index);
            painter->setRenderHint(QPainter::Antialiasing);
    
            QAbstractItemView *view = qobject_cast<QAbstractItemView*>(parent());
            if (!view) {
                QStyledItemDelegate::paint(painter, opt, index);
                return;
            }
    
            // 判断是否为边角单元格
            bool isTopLeft = (index.row() == 0 && index.column() == 0);
            bool isTopRight = (index.row() == 0 && index.column() == view->model()->columnCount() - 1);
            bool isBottomLeft = (index.row() == view->model()->rowCount() - 1 && index.column() == 0);
            bool isBottomRight = (index.row() == view->model()->rowCount() - 1 && index.column() == view->model()->columnCount() - 1);
    
            if (isTopLeft || isTopRight || isBottomLeft || isBottomRight) {
                QPainterPath path;
                // 针对不同边角设置对应圆角
                if (isTopLeft) {
                    path.addRoundedRect(opt.rect, m_radius, m_radius, Qt::TopLeftCorner);
                } else if (isTopRight) {
                    path.addRoundedRect(opt.rect, m_radius, m_radius, Qt::TopRightCorner);
                } else if (isBottomLeft) {
                    path.addRoundedRect(opt.rect, m_radius, m_radius, Qt::BottomLeftCorner);
                } else if (isBottomRight) {
                    path.addRoundedRect(opt.rect, m_radius, m_radius, Qt::BottomRightCorner);
                }
    
                // 处理选中状态与自定义背景色
                QBrush bgBrush;
                if (opt.state & QStyle::State_Selected) {
                    bgBrush = QColor("#FF0000");
                } else {
                    bgBrush = opt.data(Qt::BackgroundRole).value<QBrush>();
                }
                painter->fillPath(path, bgBrush);
    
                // 手动绘制文本,避免父类绘制覆盖背景
                painter->drawText(opt.rect, opt.displayAlignment, opt.text);
            } else {
                // 非边角单元格正常绘制
                QStyledItemDelegate::paint(painter, opt, index);
            }
        }
    
    private:
        int m_radius;
    };
    
  2. 绑定Delegate到表格:

    // 给整个表格设置Delegate,圆角半径设为5
    ui->tableWidget->setItemDelegate(new RoundedCornerDelegate(5, ui->tableWidget));
    

方案对比

  • 方案一:实现简单,无需修改单元格绘制逻辑,适合静态表格;若表格带滚动条,需额外调整frame的裁剪区域。
  • 方案二:精确控制边角样式,适配动态表格,但需处理文本对齐、选中状态等细节。

内容的提问来源于stack exchange,提问作者Borage

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 22:44:54