PDA

View Full Version : QGraphicsView and embeded widgets



bunjee
9th October 2008, 04:24
Hey there,

I have a QGraphicsView which contains another QGraphicsView embeded in a QGraphicsProxyWidget.

Here is my insertWidget function :


/* virtual */ void qkListBase::insertWidget(int index,
QWidget * widget,
int stretch,
Qt::Alignment alignment)
{
if (contains(widget)) return;

Q_D(qkListBase);

QGraphicsProxyWidget * proxyWidget = scene()->addWidget(widget);

QPalette p(widget->palette());
p.setColor(QPalette::Window, Qt::transparent);
widget->setPalette(p);

qkListBasePrivate::item * Item = new qkListBasePrivate::item(proxyWidget);
Item->proxyWidget = proxyWidget;
Item->stretch = stretch;
Item->alignment = alignment;

d->items.push_back(Item);

d->resetGeometry();
}

- When I add a widget into my main QGraphicsView / scene : it works fine.
- When I add a widget into a QGraphicsView inside my main QGraphicsView I get the following :


warning: QPainter::begin: A paint device can only be painted by one painter at a time.

warning: QPainter::begin: A paint device can only be painted by one painter at a time.

warning: ASSERT: "state" in file kernel\qwidget.cpp, line 4470

warning: Invalid parameter passed to C runtime function.

warning: Invalid parameter passed to C runtime function.

warning: QPainter::begin: A paint device can only be painted by one painter at a time.

Anyone knows why ?

wysota
9th October 2008, 09:56
What is the point of having a graphicsview inside a graphicsview?

bunjee
9th October 2008, 11:08
Why not ? After all QGraphicsView is a widget like the others.

I'm using QGraphicsView as a list item container for both Widgets and QGraphicsItems.

bunjee
9th October 2008, 14:49
I'm on Qt 4.4.3 Windows.

Consider the following code :


QGraphicsView * group = new QGraphicsView;
QGraphicsScene * scene = new QGraphicsScene;
group->setScene(scene);

QGraphicsView * group2 = new QGraphicsView;
QGraphicsScene * scene2 = new QGraphicsScene;
group2->setScene(scene2);

group->scene()->addWidget(group2);
QLineEdit * lineEdit = new QLineEdit;
group2->scene()->addWidget(lineEdit); // <<< The trouble maker

group->show();

There is no way to add a widget inside a QGraphicsView that is embedded into another one.

wysota
9th October 2008, 20:38
Why not ? After all QGraphicsView is a widget like the others.
I'm asking about a reason, maybe there is a better way to do it.


I'm using QGraphicsView as a list item container for both Widgets and QGraphicsItems.

Why not use an item group instead?

bunjee
10th October 2008, 00:25
I'm looking for an explanation for :

Why doesn't this work:


QGraphicsView * group = new QGraphicsView;
QGraphicsScene * scene = new QGraphicsScene;
group->setScene(scene);

QGraphicsView * group2 = new QGraphicsView;
QGraphicsScene * scene2 = new QGraphicsScene;
group2->setScene(scene2);

group->scene()->addWidget(group2);
QLineEdit * lineEdit = new QLineEdit;
group2->scene()->addWidget(lineEdit); // <<< The trouble maker

group->show();

If there is any.

wysota
10th October 2008, 01:03
Yes, I can imagine embedding a GV into a GV was not forseen by the team who implemented "widgets on graphics view". I really don't see why anyone would want to embed a widget into a graphicsview that is embedded into a graphicsview. You can have the same functionality with much simpler design...

bunjee
10th October 2008, 02:11
In that case that statement in Qt doc is not really true :


The QGraphicsProxyWidget class provides a proxy layer for embedding a QWidget in a QGraphicsScene.
QGraphicsProxyWidget embeds any QWidget-based widget

They are simpler design, but they are a huge flexibility trade-off.

What I'm trying to do is the following :

I'm coding a custom graphicsView based list that supports the following :
- Mixing QGraphicsItem and QWidget seamlessly.

That way I'm getting the best of both world : having a QWidget enabled list that also supports QGraphicsItem in case I need 10 000 low memory items.
(As you can see I don't like the concept of model view delegates).

I've also developped my own QGroupBox based on my QGraphicsView list which also supports both QGraphicsItem and widget.

Only problem is when I mix my list and my groupBox with a QWidget, QPainter error blows up.

I think that might be a Qt 4.4.3 design flaw.

wysota
10th October 2008, 09:09
In that case that statement in Qt doc is not really true :
So open the appropriate source file of the reference and change "any" to "almost any" and then focus on finding solution to your problem.



They are simpler design, but they are a huge flexibility trade-off.
Somehow I don't see a tradeoff of substituting a graphicsview with a graphicsitem.


Only problem is when I mix my list and my groupBox with a QWidget, QPainter error blows up.

I think that might be a Qt 4.4.3 design flaw.

You could probably call it a bug, but on the other hand I completely understand this "improper" behaviour. Again I suggest to substitute the internal view by an item containing other items. Keep in mind that "widgets on graphics view" is a relatively new and very complicated architecture that required many internal changes to Qt in various places. Don't expect it to do everything without problems. Your problem is probably because two different views at once try to paint the same widget which is an abnormal situation.

bunjee
10th October 2008, 13:26
So open the appropriate source file of the reference and change "any" to "almost any" and then focus on finding solution to your problem.

Well the solution is to get hired by the trolls to modify QGraphicsView design... or report a bug :-). I don't see any valid solution that is not a hack.


Somehow I don't see a tradeoff of substituting a graphicsview with a graphicsitem.

Consider the following scenario : you're coding a KDE like desktop widget that supports various transformations and animations.
- You inherit QGraphicsView.
- Now you're adding your widget window items using scene()->addItem().
- One of them happens to contain a QGraphicsView representing some random diagram... You're screwed.

When you're looking at other modern GUI like say cocoa / core animation. They are some animations / interactions and opengl components that you simply cannot do properly using current Qt release. Because your whole widget is never based on some vectorial QGraphicsView representation. So most of your Qt app design is last century.

Which will - hopefully - change in 4.5.


Again I suggest to substitute the internal view by an item containing other items

Yeah but if you do that you're reinventing the wheel for each specific "group" item, why can't we be generic ?

And you cannot use a QGraphicsItem coupled with a QWidget in something else than QGraphicsView.

wysota
12th October 2008, 08:43
You're screwed.
So be sure not to do that. Qt is not perfect and it can't do everything. As for now we have to live with it.


When you're looking at other modern GUI like say cocoa / core animation. They are some animations / interactions and opengl components that you simply cannot do properly using current Qt release.
Well... I don't think they allow you to do some things graphics view enables you to do...


Yeah but if you do that you're reinventing the wheel for each specific "group" item, why can't we be generic ?
I don't see any reinventing the wheel here. You want an item containing other items. For me it looks like QGraphicsItemGroup.


And you cannot use a QGraphicsItem coupled with a QWidget in something else than QGraphicsView.
Yes, and you can't do many other things as well, like drawing widgets from external threads. Just accept it and focus on solving your problem :)