Embeded QGraphicsProxyWidget away from boundingRect
Hi,
Hi, I'm embedding and widget into a scene with a QGraphicsProxyWidget but the embedded widget is away from its boundingRect. See following image
http://www.qlands.com/other_files/scene03.jpg
Here is the code that adds it:
Code:
QGraphicsProxyWidget *item = new QGraphicsProxyWidget;
comboWidget = new myComboBox;
item->setWidget(comboWidget);
comboWidget->setValue("Item 1");
draggedPoint.setX(100);
draggedPoint.setY(100);
myscene.addItem(item);
item->setPos(draggedPoint);
I have been trying to move the widget to center the boundingRect but nothing seems to work.
Any ideas will be apppreciated,
Carlos.
Re: Embeded QGraphicsProxyWidget away from boundingRect
What do you mean that the widget is "away from its boundingRect()"? Bounding rect of an item has nothing to do with its position on the scene.
Re: Embeded QGraphicsProxyWidget away from boundingRect
Hi,
For example in the image that I posted I use the boundingRect of the item to draw the black small boxes. For this I capture the position of the boundingRect of the item in the scene and then I draw the small boxes around it. For other item types like polygons the small boxes are around the item because the polygon is centered on his boundingRect but not for Proxy widgets. See below for a polygon
http://www.qlands.com/other_files/scene04.jpg
Many thanks
Re: Embeded QGraphicsProxyWidget away from boundingRect
Re: Embeded QGraphicsProxyWidget away from boundingRect
Here is the code that set the boxes around an item
Code:
{
float xpos;
float ypos;
//The separation between the boundingRect of item and the boxes
separation = 10;
//tnkresizeitem is a class of QGraphicsPolygonItem. These are the boxes appearing around item
tnkresizeitem *titem;
//Get the position of the item;
xpos = Item->scenePos().x();
ypos = Item->scenePos().y();
//Upper left box
titem = new tnkresizeitem();
titem->setX(xpos - (Item->boundingRect().width()/2) -separation);
titem->setY(ypos - (Item->boundingRect().height()/2) - separation);
titem->setZValue(selItemZ);
titem->setResizePosition(tnkresizeitem::UpperLeft);
addItem(titem);
//Lower right box
titem = new tnkresizeitem();
titem->setX(xpos + (Item->boundingRect().width()/2) + separation);
titem->setY(ypos + (Item->boundingRect().height()/2) + separation);
titem->setZValue(selItemZ);
titem->setResizePosition(tnkresizeitem::LowerRight);
addItem(titem);
//Lower left box
titem = new tnkresizeitem();
titem->setX(xpos - (Item->boundingRect().width()/2) - separation);
titem->setY(ypos + (Item->boundingRect().height()/2) + separation);
titem->setZValue(selItemZ);
titem->setResizePosition(tnkresizeitem::LowerLeft);
addItem(titem);
//Upper right box
titem = new tnkresizeitem();
titem->setX(xpos + (Item->boundingRect().width()/2) + separation);
titem->setY(ypos - (Item->boundingRect().height()/2) - separation);
titem->setZValue(selItemZ);
titem->setResizePosition(tnkresizeitem::UpperRight);
addItem(titem);
//Top box
titem = new tnkresizeitem();
titem->setX(xpos);
titem->setY(ypos - (Item->boundingRect().height()/2) - separation);
titem->setZValue(selItemZ);
titem->setResizePosition(tnkresizeitem::Top);
addItem(titem);
//Bottom box
titem = new tnkresizeitem();
titem->setX(xpos);
titem->setY(ypos + (Item->boundingRect().height()/2) + separation);
titem->setZValue(selItemZ);
titem->setResizePosition(tnkresizeitem::Bottom);
addItem(titem);
//Left box
titem = new tnkresizeitem();
titem->setX(xpos - (Item->boundingRect().width()/2) - separation);
titem->setY(ypos);
titem->setZValue(selItemZ);
titem->setResizePosition(tnkresizeitem::Left);
addItem(titem);
//Right box
titem = new tnkresizeitem();
titem->setX(xpos + (Item->boundingRect().width()/2) + separation);
titem->setY(ypos);
titem->setZValue(selItemZ);
titem->setResizePosition(tnkresizeitem::Right);
addItem(titem);
}
Here is the definition of tnkresizeitem used in the function
Code:
{
public:
enum { Type = UserType + 37 };
enum resizePositions { None, UpperLeft, LowerRight, UpperRight, LowerLeft, Top, Bottom, Left, Right };
tnkresizeitem();
int type() const { return Type; }
void setResizePosition(resizePositions position) {resizeposition = position;};
resizePositions getResizePosition() {return resizeposition;};
protected:
resizePositions resizeposition; //Where the item is
};
Re: Embeded QGraphicsProxyWidget away from boundingRect
You are assuming that the point of origin of the item's coordinate system is in the middle of the item which is not the case for proxy widget items where the origin is in top left corner of the item. Better use:
Code:
QPointF topLeft
= item
->mapToScene
(item
->boundingRect
().
topLeft());
QPointF bottomLeft
= item
->mapToScene
(item
->boundingRect
().
bottomLeft());
QPointF topRight
= item
->mapToScene
(item
->boundingRect
().
topRight());
QPointF bottomRight
= item
->mapToScene
(item
->boundingRect
().
bottomRight());
Re: Embeded QGraphicsProxyWidget away from boundingRect
Here is an small application that re-creates the problem.
Code:
#include <QtCore>
#include <QtGui>
int main(int argc, char *argv[])
{
scene.setSceneRect(0, 0, 800, 480);
QGraphicsProxyWidget *w = new QGraphicsProxyWidget;
w->widget()->setGeometry(0,0,100,100); //Makes the pushbutton 100x100
//Creates a polygon of 100x100
p->setPolygon(poly);
//Sets both polygon and proxy widget in the same position.
p->setPos(100,100);
w->setPos(100,100);
//This would look as if the proxy widget has a black border all around it but this does not work.
scene.addItem(w);
scene.addItem(p);
view.show();
return app.exec();
}
Thanks,
Carlos.
Re: Embeded QGraphicsProxyWidget away from boundingRect
Thanks for the reply.
Is there any way to change the origin or move the internal widget?
Re: Embeded QGraphicsProxyWidget away from boundingRect
You can always subclass the proxy and reimplement boundingRect() for it or place it in another item with a boundingRect fitting your design.
Re: Embeded QGraphicsProxyWidget away from boundingRect
Hi,
I opted for sub-classing the proxy and reimplementing boudingrect but I still cant make it.
Here is the implementation:
Code:
{
newbound.setWidth(widget()->geometry().width());
newbound.setHeight(widget()->geometry().height());
center.setX(0);
center.setY(0);
newbound.moveCenter(center); //Centers the boundrect in 0,0 just like other types of items
return newbound;
};
Here is the result:
http://www.qlands.com/other_files/scene05.jpg
With this code is almost the same but just a quarter of the item is shown.
Re: Embeded QGraphicsProxyWidget away from boundingRect
I don't think that's enough as paint() still paints starting with (0,0). You probably have to reimplement it as well and translate the painter before calling the base class implementation. An alternative would be to implement an "effect" for the item that would translate it to coordinates you expect. Then you wouldn't have to touch the proxy class itself assuring that you don't break the way events are handled, etc.
Re: Embeded QGraphicsProxyWidget away from boundingRect
ok. I reimplemented the proxy paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
How can I tell the painter to start somewhere and not 0,0?
Re: Embeded QGraphicsProxyWidget away from boundingRect
I used the translate(x,y) but this mess up with the translations between the widget and proxy in the scene.
This may be a bit messy... I will follow your other suggestion of place it in another item with a boundingRect fitting your design.
Let me see if I can work out this suggestion.
Re: Embeded QGraphicsProxyWidget away from boundingRect
I managed to do it by embedding the proxy into a QGraphicsRectItem.
Thanks a lot for your advice.
[CLOSED]
Carlos.