PDA

View Full Version : itemAt - does not select rect



gjshannon
13th March 2009, 15:03
I am a relative newcomer to Qt, and am developing a process management tool using Qt.
The tool will display rectangles (tasks) with links between tasks.

I am using QGraphicsScene and QGraphicsItem with QGraphicsView as the widget to display.

I want to use the mouse buttons in traditional ways to add, view, or modify tasks and links.

I have reviewed the examples in Qt help plus I have a very similar example from the book "C++ GUI Programming with Qt4" by Blanchette and Summerfield, and am copying and modifying snippets from the Diagram application in this book.

So, when I use the right-mouse button I want to invoke one menu when the mouse is not over a task, and invoke a different menu when the mouse is over a task (should be simple, right?).

To keep it simple, I'm only working on tasks now; I'll get to links later.

I have a bug in my code so that when I right-mouse click the same menu appears, regardless of whether I am over a task or not.

The issue appears to be in the coordinates that I use to know where the mouse is and whether or not it is over a task.

The code that does this is

QGraphicsItem* selectedItem = this->itemAt(mouseEvent->scenePos());
in the method
void ProcessScene::mousePressEvent(QGraphicsSceneMouseE vent* mouseEvent)
where ProcessScene is a subclass of QGraphicsScene.

However, when I test this, knowing that the mouse is over an existing task in the view, the method "itemAt" does not return an item.

I'm stumped on where to look to debug this.

By the way, the help text, at least to me, seems ambiguous when discussing the coordinate systems returned for a QRectF. It isn't clear to me how to obtain coordinates that are consistent with the scene position returned by mouseEvent->scenePos(). It would be most helpful during debugging. I would be grateful for any suggestions on where to look for clarification.

Furthermore, on a separate note, a "task" object is a subclass of QGraphicsRectItem (per the example in the book). It requires reimplemening the paint function to add text.

Is there a better way? For example, is it preferred to use a QGraphicsWidget (such as QLabel) or maybe a combination of QGraphicsRectItem with a QGraphicsTextItem?

The reason I ask is that we will have many tasks displayed at once, and I want to minimize memory and processing.

Thanks in advance for the assistance.

Regards,

George

wysota
14th March 2009, 18:44
However, when I test this, knowing that the mouse is over an existing task in the view, the method "itemAt" does not return an item.
Check if the coordinates are correct and if they are within the item's sceneRect(). Also check if you implemented shape() properly, maybe you're just hitting a transparent area.


By the way, the help text, at least to me, seems ambiguous when discussing the coordinate systems returned for a QRectF. It isn't clear to me how to obtain coordinates that are consistent with the scene position returned by mouseEvent->scenePos(). It would be most helpful during debugging. I would be grateful for any suggestions on where to look for clarification.
Search the forum. I recently posted a verbose explanation of the GV coordinate system.


Furthermore, on a separate note, a "task" object is a subclass of QGraphicsRectItem (per the example in the book). It requires reimplemening the paint function to add text.
Consider adding a QGraphicsTextItem as a child of the rect item, you might get additional features (like inline editing) for free.

gjshannon
14th March 2009, 20:37
Thanks wysota.

I expermented with adding just a QGraphicsRectItem to make sure my code for finding items under the mouse worked, and it did just fine.

A defect occurs when using the example from the book I referenced, probably in the paint method or perhaps in the boundingRect method reimplemented in my subclass of QGraphicsRectItem.

I'll try your approach. Thanks.

wysota
14th March 2009, 21:51
Without knowing what you did in the reimplementation it is hard to find a solution. If I had to guess, I would say you implemented boundingRect() in a wrong way. If you show us the code, maybe we can spot the problem right away (you could have done that yesterday, you know...).