2

I am using a QTreeView with a custom delegate and i subclassed QAbstractItemModel. I would like to see gridlines for items without children.

At first display, everything’s looks fine but whenever the mouse hovers over an item, the bottom or top line dissappears and reappears when hovering back to the item.

since this is my first post, it seems that i cannot post some images to show the unwanted effect.

But i guess something's wrong with my custom delegate or my stylesheet for the QTreeView :

void ProjetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if (index.column() > 0 && !index.model()->hasChildren(index))
    {        
        QPen pen;
        pen.setColor(QColor(Qt::lightGray));
        pen.setWidth(1);
        painter->setPen(pen);
        painter->drawRect(option.rect);
        QStyledItemDelegate::paint(painter,option,index);
    }
    else QStyledItemDelegate::paint(painter,option,index);
}

The stylesheet used is :

QString treeViewStyle =
    "QTreeView { show-decoration-selected: 1; }"
    "QTreeView::item:hover { background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 lightgray, stop: 1 white); }"
    "QTreeView::item:selected:active { background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 lightgray, stop: 1 lightgray); color: black; }"
    "QTreeView::item:selected:!active { background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 lightgray, stop: 1 lightgray); color: black;}" ;

Has anyone an idea of how to get rid of this dynamic behavior and keep the initial correct view at first display ?

Thanks.

IbliSS
  • 25
  • 1
  • 7

3 Answers3

1

Using an item delegate might be good, but it might result in low performances when displaying lots of items, since every item has to cycle through its paint method. Also, if using different delegates for every column (with some having their own paint method), this might be a problem.

Another approach could be to implement QTreeView.drawRow(), which has the advantage of not drawing actual rectangles that might result in inconsistent drawing with non-black (or with alpha component) colors. I am using PyQt, but this should to be still readable for other languages.

def drawRow(self, painter, option, index):
    QtGui.QTreeView.drawRow(self, painter, option, index)
    painter.setPen(QtCore.Qt.lightGray)
    y = option.rect.y()
    #saving is mandatory to keep alignment through out the row painting
    painter.save()
    painter.translate(self.visualRect(self.model().index(0, 0)).x() - self.indentation() - .5, -.5)
    for sectionId in range(self.header().count() - 1):
        painter.translate(self.header().sectionSize(sectionId), 0)
        painter.drawLine(0, y, 0, y + option.rect.height())
    painter.restore()
    #don't draw the line before the root index
    if index == self.model().index(0, 0):
        return
    painter.drawLine(0, y, option.rect.width(), y)

The code above draws an horizontal line before every row and a vertical one before every column, keeping track of the header section size and tree indentation; keep in mind that I've not checked how it behaves with the rootIsDecorated property.

musicamante
  • 41,230
  • 6
  • 33
  • 58
0

Try to use border if that is problem. Its hard to say anything.

You can red and other bright color and mark items(using border or bg) see which color appears. it will help you to find out which item is creating problem.

Yash
  • 6,644
  • 4
  • 36
  • 26
  • Thanks for this answer. I found a alternative solution using stylesheet and the paint method from the base class QStyledItemDelegate but it's not exactly what i wanted initially.`"QTreeView::item:!has-children { border: 0.5px ; border-style: solid ; border-color: lightgray ;}"` – IbliSS Jul 09 '14 at 12:29
  • I will still consider it like workaround or hack. Anyways... cool – Yash Jul 09 '14 at 14:24
0

I know this post is pretty old but still i think i can contribute:

The thing is that you use

QStyledItemDelegate::paint(painter,option,index);

after(!) you drew your rectangle, so this can (and i guess actually IS) overpainting your rectangle. I had the same issue with a QTreeView where i wanted to paint a grid

Hope this helps