PDA

View Full Version : QTreeView::drawRow() problem



yogeshm02
25th May 2008, 17:42
Hi
I've reimplemented QTreeView::drawRow(). Everything is fine except I need a way to determine how to draw alternating row background or in short how to find out whether background should be drawn with alternate background colour or not. Currently I'm using this

const int def_item_height = itemDelegate()->sizeHint(option, model->index(0, 0)).height();
int row_no;
if(verticalScrollMode() == QAbstractItemView::ScrollPerItem){
row_no = (visualRect(index).top() / def_item_height) + verticalScrollBar()->value();
}else{
row_no = (verticalScrollBar()->value() + visualRect(index).top()) / def_item_height;
}
const bool alternate_on = row_no & 1;

As you can see, above code only works if all rows have same height. Any suggestions, please...

jpn
25th May 2008, 18:02
QTreeView seems to store that information as a private member before it calls drawRow() from drawTree(). There is no way for you to access that private member unless you include a private header (which might not be available on all environments so you might not want to do that)...

This is roughly the way QTreeView does it ("d" is a pointer to QTreeViewPrivate):


void QTreeView::drawTree(QPainter *painter, const QRegion &region) const
{
...

foreach (visible item) {
...
d->current = i;
...
drawRow(painter, option, viewItems.at(i).index);
}

...
}

void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
...

if (alternate) {
if (d->current & 1) {
opt.features |= QStyleOptionViewItemV2::Alternate;
} else {
opt.features &= ~QStyleOptionViewItemV2::Alternate;
}
}

...
}

It would be much nicer if QTreeView::drawTree() would set the option so you could just check it from opt.features in QTreeView::drawRow() reimplementation...

But one question: why do you need a custom drawRow()?

yogeshm02
26th May 2008, 08:53
QTreeView seems to store that information as a private member before it calls drawRow() from drawTree(). There is no way for you to access that private member unless you include a private header (which might not be available on all environments so you might not want to do that)...


Just wondered if there was something which I was missing; so the thread.


But one question: why do you need a custom drawRow()?
Always draw branches on the first *visible* column Always have the first visible column span all columns if it has child rows


Actually I just had to copy code from QTreeView::drawRow() and change it by about 20%. Apart from alternate background, there are two more places where I need the data stored in private pointer; while one of them I can certainly live without, following is the one I'm not sure of


// when the row contains an index widget which has focus,
// we want to paint the entire row as active
bool indexWidgetHasFocus = false;
if ((current.row() == index.row()) && !d->editors.isEmpty()) {
const int r = index.row();
QWidget *fw = QApplication::focusWidget();
for (int c = 0; c < header->count(); ++c) {
QModelIndex idx = d->model->index(r, c, parent);
if (QWidget *editor = indexWidget(idx)) {
if (ancestorOf(editor, fw)) {
indexWidgetHasFocus = true;
break;
}
}
}
}

jpn
26th May 2008, 09:06
Always draw branches on the first *visible* column

Have you tried QTreeView::drawBranches()?



Always have the first visible column span all columns if it has child rows

Have you tried QTreeView::setFirstColumnSpanned()?

yogeshm02
26th May 2008, 09:37
Have you tried QTreeView::drawBranches()?
Yes, but it is very tightly built around drawRow(). So, I cant use it for this purpose.


Have you tried QTreeView::setFirstColumnSpanned()?
Yes. The problem with it is that setFirstColumnSpanned() needs to be explicitly set on the index; this seems a bit cumbersome given that it can be done automatically with drawRow(). It also draws selection thinking that selection always start at column having index == 0 and hence when that column is moved the selection is drawn in two parts.

andrey_s
14th October 2009, 21:13
Actually I just had to copy code from QTreeView::drawRow() and change it by about 20%. Apart from alternate background, there are two more places where I need the data stored in private pointer; while one of them I can certainly live without, following is the one I'm not sure of <...>

Hi yogeshm02,

Did you find a way how to obtain pointer to the private data?
I also have to override drawRow or most likely even drawTree method and I need that pointer to make it work.