PDA

View Full Version : QGraphicItem mouse click detection



PrimeCP
18th July 2007, 20:49
I have an application that allows the user to draw arrows between boxes using the QGraphics items, views, etc. The arrows are a line with an arrow head drawn on the right hand side, with text at the base of the arrow (non arrow side).

The problem is that the bounding rectangles overlap a lot when the arrows intersect or become near each other. What is the best way to determine what arrow is closest to the mouse click point? My current method is "ok" in that it works most of the time, but it can be confused and selects the wrong arrow. The method I use is to create a line (not on the screen) from the arrow head to the click point and from the arrow tail to the click point, combine those line lengths and do the same for each arrow found under the click point. The arrow with the least combined length is usually the closest, so I change its color (select it).

In a nutshell, if a bunch of bounding rectangles intersect, what is the best way to determine which arrow is actually closest to the clicked point on the screen (the bounding rectangles are larger than the line so that they can fit the arrow head and text)?

Gopala Krishna
18th July 2007, 21:24
I have an approach here using QLineF::intersect() . I guess it might work.

Whenever a user clicks, create a small line with the click position and some neighbouring point. Now iterate through all possible items in clicked area, and check for intersection with the arrow line and above created small line. Since the line is small you may find the nearest arrow.
Just make sure this checking is done in scene coordintaes.

aamer4yu
20th July 2007, 07:54
Override the QGraphicsItem::shape() function . This function is used in collision detection, and u can precisely give the shape of arrow in it. Use QPainterPath to define the shape of the arrow.
I guess this helps :)

Gopala Krishna
20th July 2007, 12:35
Obviously the above solution from aamer is better than from mine. :)
Somehow this didn't strike to my mind :o