css – 为QTreeView中的不同复选框设置不同的图像

前端之家收集整理的这篇文章主要介绍了css – 为QTreeView中的不同复选框设置不同的图像前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我将QTreeView子类化,我有两列有复选框.我想设置两个不同的图像:一个用于第一列,另一个用于第二列.我知道我可以在样式表中更改图像:
  1. QTreeView::indicator:checked{
  2. image: url(:/checked);
  3. }
  4.  
  5. QTreeView::indicator:unchecked{
  6. image: url(:/unchecked);
  7. }

但它会更改树视图中的所有复选框.有没有办法用样式表来做,或者我需要使用委托吗?

解决方法

简短回答:样式表不能这样做(据我所知).它们在Qt中是一个非常不成熟的特性,它们似乎也没有发展.

你可以做什么:

样式表

您无法将属性分配给列或项目,也无法通过索引访问列.

但是你可以使用一些伪状态选择器,例如:first,:middle和:last:

  1. QTreeView::indicator:first:checked{
  2. background: red;
  3. }
  4. QTreeView::indicator:middle:checked{
  5. background: blue;
  6. }
  7. QTreeView::indicator:unchecked{
  8. background: lightgray;
  9. }

为简单起见,我使用颜色而不是图像.
但请注意,这些伪状态是实际当前可见的状态,因此如果允许用户对列重新排序,则列的样式可能会更改.例如,如果用户拖动其中一个: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的示例

  1. void MyItemDelegate::paint(QPainter * painter,const QStyleOptionViewItem & option,const QModelIndex & index) const
  2. {
  3. QStyledItemDelegate::paint(painter,option,index);
  4. QStyleOptionViewItem opt = option;
  5. initStyleOption(&opt,index);
  6.  
  7. const QWidget *widget = option.widget;
  8. QStyle *style = widget ? widget->style() : QApplication::style();
  9.  
  10. QRect checkRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator,&opt,widget);
  11. drawCheckBox(painter,checkRect,opt.checkState,index);
  12. }
  13.  
  14. void MyItemDelegate::drawCheckBox(QPainter * painter,const QRect & checkRect,Qt::CheckState checkState,const QModelIndex & index) const
  15. {
  16. if (checkState == Qt::Checked)
  17. {
  18. switch (index.column())
  19. {
  20. case 0:
  21. painter->fillRect(checkRect,Qt::red);
  22. break;
  23. default:
  24. painter->fillRect(checkRect,Qt::blue);
  25. }
  26. }
  27. else
  28. {
  29. painter->fillRect(checkRect,Qt::lightGray);
  30. }
  31. }

这个例子快速而简单.只需在QStyledItemDelegate绘制的复选框上绘制.但是需要你填满整个盒子,否则原件将是可见的.

您可以尝试使用QStyledItemDelegate绘制除复选框之外的任何内容,然后绘制复选框,但这有点难,如果您不想花太多时间在它上面会留下一些小的绘图工件.

使用自定义QProxyStyle的示例

  1. void MyStyle::drawPrimitive(PrimitiveElement pe,const QStyleOption * opt,QPainter * p,const QWidget * w) const
  2. {
  3. if (pe == QStyle::PE_IndicatorViewItemCheck)
  4. {
  5. const QStyleOptionViewItem * o = static_cast<const QStyleOptionViewItem *>(opt);
  6. drawCheckBox(p,opt->rect,o->checkState,o->index);
  7. return;
  8. }
  9. QProxyStyle::drawPrimitive(pe,opt,p,w);
  10. }

drawCheckBox()函数与第一个示例中的相同.正如您所看到的,这种方式更简单,更清洁并且没有任何缺点.您可以全局应用样式,也可以仅应用于单个窗口小部件.

猜你在找的CSS相关文章