我有一个
QTableWidget
(或者,QListWidget
),我想按以下方式设置样式:
单元格的“选定”颜色应该是某种固定的颜色。我可以通过使用以下样式表来做到这一点:
QTableWidget::item:selected { background-color: #FF0000 }
单元格的“未选择”颜色应根据我的代码中的颜色向量单独设置。我可以通过在创建时为每个
QBrush
分配 QTableWidgetItem
来做到这一点:
QColor col = color_vector.value(i);
QBrush brush(col);
item->setData(Qt::BackgroundRole, QVariant(brush));
整个表格应该有圆角(本质上是“剪裁”表格中角项的边框)。
最后一部分我还没有实现。
我尝试过以下方法:
我可以使用此样式表将表格的角变圆:
QTableWidget
{
border: 1px solid;
background: transparent;
border-radius: 5px
}
尽管这会在表格周围绘制圆形边框,但各个单元格的背景仍然在角落处“突出”。
我可以为
border-radius
设置相同的 QTableWidget::item
,但是所有单元格的所有角都将被圆化,而不仅仅是表格的边缘。由于 QTableWidgetItem
本身不是 QWidget
,我认为我无法将样式分配给特定项目。
QDelegate
:我尝试对
QStyledItemDelegate
进行子类化并覆盖 paint()
函数。但似乎并没有多大作用。也许我犯了一个错误(对 Qt 来说仍然很新,所以很有可能),或者更改可能被我在样式表/setData 中设置的选项覆盖了?
这是我为
paint(painter, option, index)
实现所做的尝试:
painter->setRenderHint(QPainter::Antialiasing);
QPainterPath path;
path.addRoundedRect(option.rect, 5, 5);
painter->fillPath(path, option.backgroundBrush);
QStyledItemDelegate::paint(painter, option, index);
然后将其添加到表格小部件对象中:
table->setItemDelegateForRow(0, new RoundedCornerDelegate(table));
这甚至还不是最终想要的结果(我仍然需要找出一种只绘制一个圆角的方法),但它似乎不起作用:该项目的背景仍然绘制为纯矩形。即使我将上面代码中的画笔更改为不同的东西,我也没有看到在顶部绘制了不同颜色的圆角矩形(也许在下面?)。
QFrame
:我之前没有使用过
QFrame
,所以我不确定这是否是预期用途。但我在 UI 编辑器中创建了一个 QFrame
,并将该表添加为子表。然后我尝试了:
ui->frame->setStyleSheet("* { border: 1px solid; border-radius: 5 }");
QWidget* child = qobject_cast<QWidget*>(ui->frame->children().at(0));
ui->frame->setFixedSize(child->size());
但这只会给出奇怪的结果:
QFrame
周围的边框似乎只存在于子项不存在的地方,并且子项不完全可见。
sigma 说道:
看起来您可以通过构造具有圆角矩形形状的 QRegion 并使用 QWidget::setMask(QRegion const&).
来实现此目的
这让我找到了这个答案:如何圆化QWidget角,并基于它,我做了以下最小的可重现示例:
#include <QApplication>
#include <QTableWidget>
#include <QHeaderView>
#include <QPainterPath>
int main(int argc,char*argv[])
{
QApplication a(argc, argv);
//the following is just my setup
//just a container widget
QWidget *w = new QWidget();
QTableWidget *table = new QTableWidget(w);
table->setGeometry(100,100,200,90);
table->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
table->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
//filling the table
table->insertColumn(0);
table->insertColumn(1);
table->insertRow(0);
table->insertRow(1);
table->insertRow(2);
table->setItem(0,0,new QTableWidgetItem("item1"));
table->item(0,0)->setData(Qt::BackgroundRole, QVariant(QBrush(Qt::green)));
table->setItem(1,0,new QTableWidgetItem("item2"));
table->item(1,0)->setData(Qt::BackgroundRole, QVariant(QBrush(Qt::green)));
table->setItem(2,0,new QTableWidgetItem("item3"));
table->item(2,0)->setData(Qt::BackgroundRole, QVariant(QBrush(Qt::green)));
table->setItem(0,1,new QTableWidgetItem("item4"));
table->item(0,1)->setData(Qt::BackgroundRole, QVariant(QBrush(Qt::green)));
table->setItem(1,1,new QTableWidgetItem("item5"));
table->item(1,1)->setData(Qt::BackgroundRole, QVariant(QBrush(Qt::green)));
table->setItem(2,1,new QTableWidgetItem("item6"));
table->item(2,1)->setData(Qt::BackgroundRole, QVariant(QBrush(Qt::green)));
//removing headers
table->verticalHeader()->setVisible(false);
table->horizontalHeader()->setVisible(false);
//stylesheet of table and its items
table->setStyleSheet("QTableWidget"
"{"
"background: rgb(4, 104, 38);"
"border: 1px solid white;"
"border-radius: 10px;"
"color: black;"
"selection-background-color: transparent;"
"}"
"QTableWidget::item"
"{"
"border: 1px solid white;"
"border-radius: 0px;"
"}");
table->viewport()->setStyleSheet("background: rgb(4, 104, 38);"
"border: 1px solid white;"
"border-radius: 10px;"
"color: black;");
//SOLUTION
//setting mask on the table's viewport
//get the viewport's rect
QRect rect = table->viewport()->rect();
QPainterPath path;
//I had to adjust it so it hides the corners that were poking out
//just made it smaller
rect.adjust(+1,+1,-1,-1);
//add the rect to the path so we can draw it as a rounded one
path.addRoundedRect(rect, 7, 7);
//feed the rounded rect to a region that we'll use as a mask
QRegion mask = QRegion(path.toFillPolygon().toPolygon());
//set the viewport's mask
table->viewport()->setMask(mask);
w->setMaximumSize(800,600);
w->show();
return a.exec();
}
这是它的样子,你可以看到一些边缘和边框很粗糙,但这已经是我能做到的了:
第一种方法:
样式表在这种情况下不起作用,因为
QTableWidgetItem
不是派生自 QWidget
。
设置其样式的唯一方法是通过 ::item 子控件,但无法获取没有状态的单个项目。
第二种方法:
您还没有指定您到底如何使用
QStyledItemDelegate::paint
,所以我的猜测是您没有正确覆盖它,请参阅答案上的Qt子类QStyledItemDelegate绘制方法从未被调用。
如果解决了这个问题,您将需要绘制一个仅具有特定圆角的矩形。看一下这个,看看如何:在 Qt 中绘制只有 2 个圆角的矩形
我尝试过这种方法,但我建议不要这样做,因为要达到预期的结果需要太多的工作和混乱。
第三种方法:
使用
QFrame
作为容器只会添加另一层,它会在表格小部件及其视口之间导致同样的问题。