如何实现QTableWidget/QListWidget圆角显示(裁剪边角单元格)
QTableWidget 圆角效果实现方案
针对你遇到的表格圆角需求,结合已实现的选中色、自定义单元格背景色,提供两种可行方案:
方案一:QFrame 裁剪(推荐)
利用QFrame的裁剪特性,将表格放入frame中,自动切掉超出圆角的部分,不影响现有样式:
UI布局调整:
将QTableWidget作为QFrame的子控件,通过布局让表格自适应frame大小。设置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));配置表格透明背景:
保留已实现的选中样式,同时将表格背景设为透明,避免覆盖frame的圆角:ui->tableWidget->setStyleSheet(R"( QTableWidget { background: transparent; border: none; } QTableWidget::item:selected { background-color: #FF0000; } )");
方案二:自定义Delegate 精确控制边角单元格
针对边角单元格单独绘制圆角背景,保留其他单元格的正常样式:
实现自定义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; };绑定Delegate到表格:
// 给整个表格设置Delegate,圆角半径设为5 ui->tableWidget->setItemDelegate(new RoundedCornerDelegate(5, ui->tableWidget));
方案对比
- 方案一:实现简单,无需修改单元格绘制逻辑,适合静态表格;若表格带滚动条,需额外调整frame的裁剪区域。
- 方案二:精确控制边角样式,适配动态表格,但需处理文本对齐、选中状态等细节。
内容的提问来源于stack exchange,提问作者Borage
相关产品推荐
相关产品推荐

