QTreeView::indicator:checked{ image: url(:/checked); } QTreeView::indicator:unchecked{ image: url(:/unchecked); }
但它会更改树视图中的所有复选框.有没有办法用样式表来做,或者我需要使用委托吗?
解决方法
你可以做什么:
样式表
您无法将属性分配给列或项目,也无法通过索引访问列.
但是你可以使用一些伪状态选择器,例如:first,:middle和:last:
QTreeView::indicator:first:checked{ background: red; } QTreeView::indicator:middle:checked{ background: blue; } QTreeView::indicator:unchecked{ background: lightgray; }
为简单起见,我使用颜色而不是图像.
但请注意,这些伪状态是实际当前可见的状态,因此如果允许用户对列重新排序,则列的样式可能会更改.例如,如果用户拖动其中一个:middlecolumns并将其放在最后,则该框将不再是蓝色.
DecorationRole
你可以使用Qt :: DecorationRole伪造它.
为此,您必须通过继承QTreeView或安装event filter来接收mousePressEvent.然后,当用户单击图标区域时,您可以更改图标(通过Qt :: DecorationRole发出dataChanged()).
当然,这不适用于键盘.
自定义ItemDelegate
子类QStyledItemDelegate并覆盖paint(),就像你建议的那样.
自定义风格
如果要创建样式很重的应用程序,则可能必须迟早创建自定义样式.样式表只是不支持某些功能.
为此,子类QProxyStyle
覆盖drawPrimitive并在传递QStyle :: PE_IndicatorViewItemCheck时处理绘图.您还将收到一个QStyleOptionViewItem,其中包含一些有用的属性,如checkState,features(如果有复选框,则包含QStyleOptionViewItem :: HasCheckIndicator),当然还有索引,以便您可以确定要绘制的复选框类型.
编辑:附录
使用自定义QStyledItemDelegate的示例
void MyItemDelegate::paint(QPainter * painter,const QStyleOptionViewItem & option,const QModelIndex & index) const { QStyledItemDelegate::paint(painter,option,index); QStyleOptionViewItem opt = option; initStyleOption(&opt,index); const QWidget *widget = option.widget; QStyle *style = widget ? widget->style() : QApplication::style(); QRect checkRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator,&opt,widget); drawCheckBox(painter,checkRect,opt.checkState,index); } void MyItemDelegate::drawCheckBox(QPainter * painter,const QRect & checkRect,Qt::CheckState checkState,const QModelIndex & index) const { if (checkState == Qt::Checked) { switch (index.column()) { case 0: painter->fillRect(checkRect,Qt::red); break; default: painter->fillRect(checkRect,Qt::blue); } } else { painter->fillRect(checkRect,Qt::lightGray); } }
这个例子快速而简单.只需在QStyledItemDelegate绘制的复选框上绘制.但是需要你填满整个盒子,否则原件将是可见的.
您可以尝试使用QStyledItemDelegate绘制除复选框之外的任何内容,然后绘制复选框,但这有点难,如果您不想花太多时间在它上面会留下一些小的绘图工件.
使用自定义QProxyStyle的示例
void MyStyle::drawPrimitive(PrimitiveElement pe,const QStyleOption * opt,QPainter * p,const QWidget * w) const { if (pe == QStyle::PE_IndicatorViewItemCheck) { const QStyleOptionViewItem * o = static_cast<const QStyleOptionViewItem *>(opt); drawCheckBox(p,opt->rect,o->checkState,o->index); return; } QProxyStyle::drawPrimitive(pe,opt,p,w); }
drawCheckBox()函数与第一个示例中的相同.正如您所看到的,这种方式更简单,更清洁并且没有任何缺点.您可以全局应用样式,也可以仅应用于单个窗口小部件.