How to apply TreeView look & feel to a delegate?
Hi! I'm trying to add some pixmap (many pixmap in the same column, a progress bar and probably more stuff in the future) to my TreeView, I found the best way to do it is to set a delegate.
It does works properly, but it looks ugly when I select the row. I fill the background by doing painter.fillRect(option.rect, self.palette.highlight()), but on Windows Vista/7 it does not show the modern "explorer" look like it should, it shows a blue background.
I've search everywhere without any luck.
This is a snippet of my code:
Code:
class ProgressBarDelegate(QStyledItemDelegate):
def __init__(self, parent):
QStyledItemDelegate.__init__(self, parent)
self.palette = parent.palette()
def paint(self, painter, option, index):
if not index.isValid():
return None
#painter.save()
#if option.state & QStyle.State_Selected: #paint background if selected.
#painter.fillRect(option.rect, painter.brush())
#painter.fillRect(option.rect, self.palette.highlight())
progress = index.data()
bar_option.rect = option.rect
bar_option.rect.setHeight(option.rect.height() - 1)
bar_option.rect.setTop(option.rect.top() + 1)
bar_option.minimum = 0
bar_option.maximum = 100
bar_option.progress = int(progress)
bar_option.text = progress + '%'
bar_option.textVisible = True
bar_option.textAlignment = Qt.AlignCenter
#painter.restore()
This is the current result:
http://i.stack.imgur.com/TIJK1.jpg
This is what I want:
http://i.stack.imgur.com/7WtQx.jpg
related stackoverflow question > http://stackoverflow.com/questions/7...indows-vista-7
1 Attachment(s)
Re: How to apply TreeView look & feel to a delegate?
Is that what you wanted?
Attachment 7498
Code:
void ProgressBarDelegate
::paint( QPainter* painter,
const QStyleOptionViewItem
& option,
const QModelIndex
& index
) const {
if( index.column() == 1 )
{
if( option.
state & QStyle::State_Selected ) {
painter->fillRect( option.rect, option.palette.highlight() );
}
int progress = index.data().toInt();
progressBarOption.rect = option.rect;
progressBarOption.rect.setTop( option.rect.top() + 1 );
progressBarOption.rect.setHeight( option.rect.height() - 2 );
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.progress = progress;
progressBarOption.
text = QString::number(progress
) + "%";
progressBarOption.textVisible = true;
progressBarOption.textAlignment = Qt::AlignCenter;
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
}
Re: How to apply TreeView look & feel to a delegate?
If only... but no, that's what I got now. As I said, it looks *almost* ok, just because the highlight color is pretty much the same as the "explorer" box border.
Just try with a different delegate, try drawing a pixmap or just text.
This should illustrate what I mean:
Code:
void ProgressBarDelegate
::paint( QPainter* painter,
const QStyleOptionViewItem
& option,
const QModelIndex
& index
) const {
if( option.
state & QStyle::State_Selected ) {
painter->fillRect( option.rect, option.palette.highlight() );
}
QStyledItemDelegate::paint(painter, option, index);
}
2 Attachment(s)
Re: How to apply TreeView look & feel to a delegate?
I'm not getting what you want.
Do you want the 'modern highlight' - as you call it - to be over your progress bar/pixmap/anything, under it or not there at all?
The two example images you shown are not obious either. None of them have the progress bar cell selected.
If you want the highlight to be over the cell
Attachment 7501
then do that:
Code:
void ProgressBarDelegate
::paint( QPainter* painter,
const QStyleOptionViewItem
& option,
const QModelIndex
& index
) const {
if( index.column() == 1 )
{
int progress = index.data().toInt();
progressBarOption.rect = option.rect;
progressBarOption.rect.setTop( option.rect.top() + 1 );
progressBarOption.rect.setHeight( option.rect.height() - 2 );
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.progress = progress;
progressBarOption.
text = QString::number(progress
) + "%";
progressBarOption.textVisible = true;
progressBarOption.textAlignment = Qt::AlignCenter;
}
QStyledItemDelegate::paint(painter, option, index);
}
If you want to keep the highlight but in the background
Attachment 7502
then do this:
Code:
void ProgressBarDelegate
::paint( QPainter* painter,
const QStyleOptionViewItem
& option,
const QModelIndex
& index
) const {
QStyledItemDelegate::paint(painter, option, index);
if( index.column() == 1 )
{
int progress = index.data().toInt();
progressBarOption.rect = option.rect;
progressBarOption.rect.setTop( option.rect.top() + 1 );
progressBarOption.rect.setHeight( option.rect.height() - 2 );
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.progress = progress;
progressBarOption.
text = QString::number(progress
) + "%";
progressBarOption.textVisible = true;
progressBarOption.textAlignment = Qt::AlignCenter;
}
}
Note: in both cases there's no filling any rectangles.
If you want the cell not to be highlighted at all, then do what I've already showed just change the background color to white.
If you want something else - then I have no idea what you want :(
1 Attachment(s)
Re: How to apply TreeView look & feel to a delegate?
Sorry, yes, that's what I want (the "explorer" selection box over or under the progress bar). I wasn't able to see it clearly in your previous example.
The thing is, I'm not getting the same result. This is my code, which is the same that yours but written in pySide (python):
Code:
class ProgressBarDelegate(QStyledItemDelegate):
def __init__(self, parent):
QStyledItemDelegate.__init__(self, parent=parent)
def paint(self, painter, option, index):
QStyledItemDelegate.paint(self, painter, option, index)
progress = index.data()
bar_option.rect = option.rect
bar_option.rect.setHeight(option.rect.height() - 4)
bar_option.rect.setTop(option.rect.top() + 1)
bar_option.minimum = 0
bar_option.maximum = 100
bar_option.progress = int(progress)
bar_option.text = progress + '%'
bar_option.textVisible = True
bar_option.textAlignment = Qt.AlignCenter
Code:
def __init__(self, parent=None):
self.items = [["something", "1", "11", "t5est", "t3est"], ]
headers = ['a', 'b', 'c', 'd', 'e']
#QAbstractItemModel
self._model = SimpleListModel(headers, self.items)
self.setModel(self._model)
self.pb_delegate = ProgressBarDelegate(self)
self.setItemDelegateForColumn(2, self.pb_delegate)
This is the result:
Attachment 7503
Re: How to apply TreeView look & feel to a delegate?
I'm afraid I can't help you, I have no idea about python :(
But if you're not drawing the blue background, then style is doint it.
Try setting Window/Base/Button palette color to transparent on bar_option, maybe it will help - but that's only thing that comes to my mind.
Good luck.