更改QTreeView的行背景颜色是无效的

时间:2022-11-03 15:04:16

I have a QTreeView and want different background colors for rows, depending on their content. To achieve this, I derived a class MyTreeView from QTreeView and implemented the paint method as follows:

我有一个QTreeView,根据行内容,我希望行有不同的背景颜色。为此,我从QTreeView导出了myclass treeview,并实现了paint方法如下:

    void MyTreeView::drawRow (QPainter* painter,
                              const QStyleOptionViewItem& option,
                              const QModelIndex& index) const
    {
      QStyleOptionViewItem newOption(option);

      if (someCondition)
      {
        newOption.palette.setColor( QPalette::Base, QColor(255, 0, 0) );
        newOption.palette.setColor( QPalette::AlternateBase, QColor(200, 0, 0) );
      }
      else
      {
        newOption.palette.setColor( QPalette::Base, QColor(0, 0, 255) );
        newOption.palette.setColor( QPalette::AlternateBase, QColor(0, 0, 200) );
      }

      QTreeView::drawRow(painter, newOption, index);
    }

Initially, I set setAlternatingRowColors(true); for the QTreeView.

最初,我设置setAlternatingRowColors(真正的);QTreeView。

My problem: Setting the color for QPalette::Base has no effect. Every second row remains white.

我的问题:为QPalette设置颜色::Base没有效果。每一秒都是白色的。

However, setting QPalette::AlternateBase works as expected. I tried setAutoFillBackground(true) and setAutoFillBackground(false) without any effect.

但是,设置QPalette::交流发电机底座按预期工作。我尝试了setAutoFillBackground(true)和setAutoFillBackground(false),但没有任何效果。

Are there any hints how to solve this problem? Thank you.

有什么解决这个问题的建议吗?谢谢你!


Remark: Setting the color by adapting MyModel::data(const QModelIndex&, int role) for Qt::BackgroundRole does not provide the desired result. In this case, the background color is used only for a part of the row. But I want to color the full row, including the left side with the tree navigation stuff.

注:使用myadaptiveservereclificationdata (const qmodelindex&int role)为Qt设置颜色::BackgroundRole不提供所需的结果。在本例中,背景颜色仅用于行的一部分。但是我想给整行涂上颜色,包括左边的树导航。

Qt Version: 4.7.3

Qt版本:4.7.3


Update: For unknown reasons QPalette::Base seems to be opaque. setBrush does not change that. I found the following workaround:

更新:由于未知原因QPalette: Base似乎是不透明的。setBrush不会改变这一点。我发现了以下的变通方法:

    if (someCondition)
    {
        painter->fillRect(option.rect, Qt::red);
        newOption.palette.setBrush( QPalette::AlternateBase, Qt::green);
    }
    else
    {
        painter->fillRect(option.rect, Qt::orange);
        newOption.palette.setBrush( QPalette::AlternateBase, Qt:blue);
    }

3 个解决方案

#1


8  

If the only problem is that the expanding/collapsing controls do not have a background like rest of the row then use Qt::BackgroundRole in ::data() of your model (as described by pnezis in their answer) and add this to your tree view class:

如果唯一的问题是扩展/折叠控件不像其他行那样具有背景,那么请使用模型的::data(如pnezis在其回答中所描述的)中的Qt:::BackgroundRole,并将其添加到树形视图类中:

void MyTreeView::drawBranches(QPainter* painter,
                              const QRect& rect,
                              const QModelIndex& index) const
{
  if (some condition depending on index)
    painter->fillRect(rect, Qt::red);
  else
    painter->fillRect(rect, Qt::green);

  QTreeView::drawBranches(painter, rect, index);
}

I've tested this on Windows (Vista and 7) using Qt 4.8.0 and expanding/collapsing arrows have proper background. The problem is that those arrows are part of the view and thus cannot be handled in a model.

我在Windows (Vista和7)上使用Qt 4.8.0测试过这个,展开/折叠箭头有合适的背景。问题是,这些箭头是视图的一部分,因此不能在模型中处理。

#2


5  

Instead of subclassing QTreeView you should handle the background color through your model. Use the data() function and the Qt::BackgroundRole for changing the background color of the rows.

您应该通过模型来处理背景颜色,而不是子类化QTreeView。使用data()函数和Qt::BackgroundRole修改行的背景颜色。

QVariant MyModel::data(const QModelIndex &index, int role) const
{
   if (!index.isValid())
      return QVariant();

   if (role == Qt::BackgroundRole)
   {
       if (condition1)
          return QColor(Qt::red);
       else
          return QColor(Qt::green); 
   }

   // Handle other roles

   return QVariant();
}

#3


0  

https://www.linux.org.ru/forum/development/4702439

https://www.linux.org.ru/forum/development/4702439

if ( const QStyleOptionViewItemV4* opt = qstyleoption_cast<const QStyleOptionViewItemV4*>(&option) )
{
        if (opt.features & QStyleOptionViewItemV4::Alternate)
            painter->fillRect(option.rect,option.palette.alternateBase());
        else
            painter->fillRect(option.rect,painter->background());
}

#1


8  

If the only problem is that the expanding/collapsing controls do not have a background like rest of the row then use Qt::BackgroundRole in ::data() of your model (as described by pnezis in their answer) and add this to your tree view class:

如果唯一的问题是扩展/折叠控件不像其他行那样具有背景,那么请使用模型的::data(如pnezis在其回答中所描述的)中的Qt:::BackgroundRole,并将其添加到树形视图类中:

void MyTreeView::drawBranches(QPainter* painter,
                              const QRect& rect,
                              const QModelIndex& index) const
{
  if (some condition depending on index)
    painter->fillRect(rect, Qt::red);
  else
    painter->fillRect(rect, Qt::green);

  QTreeView::drawBranches(painter, rect, index);
}

I've tested this on Windows (Vista and 7) using Qt 4.8.0 and expanding/collapsing arrows have proper background. The problem is that those arrows are part of the view and thus cannot be handled in a model.

我在Windows (Vista和7)上使用Qt 4.8.0测试过这个,展开/折叠箭头有合适的背景。问题是,这些箭头是视图的一部分,因此不能在模型中处理。

#2


5  

Instead of subclassing QTreeView you should handle the background color through your model. Use the data() function and the Qt::BackgroundRole for changing the background color of the rows.

您应该通过模型来处理背景颜色,而不是子类化QTreeView。使用data()函数和Qt::BackgroundRole修改行的背景颜色。

QVariant MyModel::data(const QModelIndex &index, int role) const
{
   if (!index.isValid())
      return QVariant();

   if (role == Qt::BackgroundRole)
   {
       if (condition1)
          return QColor(Qt::red);
       else
          return QColor(Qt::green); 
   }

   // Handle other roles

   return QVariant();
}

#3


0  

https://www.linux.org.ru/forum/development/4702439

https://www.linux.org.ru/forum/development/4702439

if ( const QStyleOptionViewItemV4* opt = qstyleoption_cast<const QStyleOptionViewItemV4*>(&option) )
{
        if (opt.features & QStyleOptionViewItemV4::Alternate)
            painter->fillRect(option.rect,option.palette.alternateBase());
        else
            painter->fillRect(option.rect,painter->background());
}