PDA

View Full Version : [QT4 M/V] QTreeView::DrawBranches()



lunatike
17th June 2008, 14:55
Hello all,

I've ported my application to Qt4 using qt model view framework.
But my TreeView (which extends QTreeView) does not paint the dotted line (branches).

How i can do it?
I've tried to overload drawBranches, drawTree and drawRow without success.

Any help would be highly appreciated...!

PS: I saw some threads on this forum but none helped me...

caduel
17th June 2008, 16:36
Well, please give us more details :)

Possible 'mistakes' are:
* signature errors (forgotten const)
* QTreeView::rootIsDecorated set to false
* indentation set to 0

But without more information it is hard to help.

Christoph

lunatike
17th June 2008, 17:22
Well, please give us more details :)

Possible 'mistakes' are:
* signature errors (forgotten const)
* QTreeView::rootIsDecorated set to false
* indentation set to 0

But without more information it is hard to help.

Christoph
Thanks for your answer.

* Signatures are same (the plus/minus color is changed)
* rootIsDecorated set to false should not interfer with the drawing of items at depth >= 2 (i guess).
* indentation != 0

More precisely, i think i don't know what i should write in drawbranches or drawTree...
Here is an example code i tried... I try to put the same on drawbranches...


void MyTreeView::drawTree(QPainter *painter, const QRegion &region) const {
QColor color(Qt::blue);
painter->setPen(color);
painter->save();

QTreeView::drawTree(painter, region);
painter->restore();
}


Any tip would be appreciated.
I simply want a trivial dotted line :p

(But no QStyleSheet)

aamer4yu
18th June 2008, 05:44
I havent used that function myself, but can suggest the following to try -

try drawing something in that function. MYTreeView::drawTree()
something like -
painter->drawLine(region.x,region.y,region.x+region.width() ,region.y+region.height);

Also check how calling the base function works ( QTreeView::drawTree(painter, region)) .
try calling QTreeView::drawTree once before the drawline. and once after it. Hope you will move ahead :)

caduel
18th June 2008, 07:28
I don't quite see, what the purpose of your drawTree function is.
You modify the pen (which might be overriden internally, if I had to guess) and then restore the painter afterwards?
I would guess that QTreeView restores its own modifications anyway.

That aside, try to replace your MyTreeView with an instance of QTreeView.
If the dotted line still is not drawn, the issue is not with your code but with the configuration of the tree view. If it is drawn, check your code closer.

If that check should show that indeed your code is responsible, then I would comment out drawTree (and other functions you might have overloadad) and find the culprit that way.

HTH

PS: You don't call drawTree yourself, do you?

lunatike
18th June 2008, 08:34
I havent used that function myself, but can suggest the following to try -

try drawing something in that function. MYTreeView::drawTree()
something like -
painter->drawLine(region.x,region.y,region.x+region.width() ,region.y+region.height);

Also check how calling the base function works ( QTreeView::drawTree(painter, region)) .
try calling QTreeView::drawTree once before the drawline. and once after it. Hope you will move ahead :)

Thanks for helping.
I simply put a breakpoint in my drawTree method and see that she's never called...
Signature is the same, this method is protected in QTreeView and i extend this class. (don't understand!)

However my drawbranches get called. And the above code change the plus/minus color...



I don't quite see, what the purpose of your drawTree function is.
You modify the pen (which might be overriden internally, if I had to guess) and then restore the painter afterwards?
I would guess that QTreeView restores its own modifications anyway.

That aside, try to replace your MyTreeView with an instance of QTreeView.
If the dotted line still is not drawn, the issue is not with your code but with the configuration of the tree view. If it is drawn, check your code closer.

If that check should show that indeed your code is responsible, then I would comment out drawTree (and other functions you might have overloadad) and find the culprit that way.

HTH

PS: You don't call drawTree yourself, do you?

I read somewhere that the painter is a stack. save operations put on stack and are *never* (i guess) released. The restore operation is the only way to do that.
But i guess youre right on the fact that this pen should be overwritten.
BUT (lol) my pen color in drawBranches (see above) still the one i specified...

The dotted line is printed but in the same color as the treeView background(white) so she's not visible. If you select items this line appears in white.

I will try to change by a simple qtreeview.

PS: No i don't call drawTree() myself.
Thanks all for helping :)

lunatike
18th June 2008, 14:06
Ok it seems that the problem is in my code.
I have used the same model/view at another place, and branches are correctly displayed...
I tried to apply same options as the working one but no effect.
I cannot make the working view to not work and vice versa!

So can anyone tell me how i can specify for a model index a branch color (and apply it to the children...)

I think this will solves my problem.

Thanks.

jpn
18th June 2008, 16:16
Are you using style sheets or did you adjust palettes?

lunatike
18th June 2008, 16:29
I don't use stule sheets and i don't want to use them (Color have to be dynamic in the code).
So as you can see in the code above, i guess i just adjust palettes.
How can I do using this method?
Thx

lunatike
19th June 2008, 09:47
jpn: Perhaps you have a suggestion? thanks

jpn
19th June 2008, 13:31
The best solution I see is to use a proxy style and draw QStyle::PE_IndicatorBranch yourself. Various styles draw it differently, there is no unified way to adjust palettes so that it would look good on all platforms. And for example QPlastiqueStyle uses a mixture of colors in the palette (background + text) which makes it even more tedious to try to change the color with palettes.

lunatike
19th June 2008, 14:09
Ok, many thanks, i'll give it a try and give feedbacks.
I thought that it was possible to modify pen colour of the painter before calling supermethod QTreeView::drawBranches(), it's simple and qtreeview would be in charge of drawing (like currently)

If someone knows how to do that stuff, please tell me :)

Thanks all.

lunatike
19th June 2008, 15:07
Style seems to be ok.
I extend CommonStyle to overload branches color.
But i still not understand why "option->palette.dark().color()" returns the same colour as background (in QWindowsStyle::drawPrimitive)

But this method has an inconvenient: i cannot control the colour of branches of model indexes independently... Any idea ?

jpn
19th June 2008, 15:14
I thought that it was possible to modify pen colour of the painter before calling supermethod QTreeView::drawBranches(), it's simple and qtreeview would be in charge of drawing (like currently)

If someone knows how to do that stuff, please tell me :)
It's just that the QTreeView doesn't draw the branch indicator itself but passes required information to the current style to draw it. It's up to the style to decide the color... Anyway, QCommonStyle uses the pen color directly so you could even do it like this:


#include <QtGui>

// NOTE: you may use the ProxyStyle is available at Qt Centre wiki but make it inherit QCommonStyle instead of QStyle
#include "proxystyle.h"

class MyProxyStyle : public ProxyStyle
{
public:
explicit MyProxyStyle(const QString& baseStyle) : ProxyStyle(baseStyle)
{
}

void drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget = 0) const
{
if (element == QStyle::PE_IndicatorBranch)
{
painter->save();
painter->setPen(QPen(Qt::blue, 1, Qt::DashLine));
QCommonStyle::drawPrimitive(element, option, painter, widget);
painter->restore();
}
ProxyStyle::drawPrimitive(element, option, painter, widget);
}
};

int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QTreeWidget tree;
tree.setStyle(new MyProxyStyle(app.style()->objectName()));
for (int i = 0; i < 10; ++i)
new QTreeWidgetItem(&tree, QStringList() << QString::number(i));
tree.show();
return app.exec();
}

lunatike
19th June 2008, 16:59
It's what i did and it worked almost fine!
In fact it remains a problem:
When painting item on a modelindex, all the branches of the row of the model index are painted too.
And it's a bad behaviour.

I'm trying to resolve it and will be back !

Thanks for all your efforts!

aircraftstories
19th April 2011, 13:02
Just a little question : which version of windows have you ? XP or Seven ?

lunatike
19th April 2011, 14:31
in 2008? must be XP

aircraftstories
19th April 2011, 15:39
in 2008? must be XP

Yes ... lol