2

I am building an editor using C++/Qt which has a click-and-drag feel to it. The behavour is similar to schematic editors (Eagle, KiCAD, etc), Microsoft Visio, or other programs where you drag objects from a toolbar into a central editing area.

My problem is that when the user clicks inside the custom widget I want to be able to select the instance of the box-like object and manipulate it. There will also be lines connecting the boxes together. However, I can't decide on an efficient method for selecting those objects.

I have two main thoughts on how to do the programming for this: The first is that the widget which is drawing the entire editor would simply encapsulate every one of the instances of the box. The other is to have each instance of the box (which is in my Model) carry with it an instance of a QWidget which would handle rendering the box (which would be in my View...but it would end up being strongly attached to the model). As for the lines connecting them, since they don't have a square bounding boxes they will have to be rendered by the containing widget.

So here is the summary of how I see this being done:

  • The editor widget turns into a container which holds the widgets and the widgets process their own click events. The potential issues here are that I don't know how to make the custom widget turn into a layout which lets click-and-drag functionality.
  • The editor widget takes care of all the rendering and processes the mouse clicks (the easier way in that I don't have to worry about layout...its just selecting the instances efficiently that I don't know what would be best).

So, now that there is a bit of background, for the 2nd method I plan on having each box-like instance having a bounding rectangle and the lines being represented by 3-4 pixel wide bounding rectangle segments (they are at 90 degree angles). I could iterate through every single box and line, but that seems really inefficient.

The big question: Is there some sort of data structure I can hold rectangles in and link them to widgets (or anything else for that matter) and then give it two coordinates (such as mouse coordinates) and have it spit me out the bounding box or linked object that those coordinates are inside of?

Kevin Gosse
  • 38,392
  • 3
  • 78
  • 94
Los Frijoles
  • 4,771
  • 5
  • 30
  • 49
  • 3
    Determining if a point is within a rectangle is trivial and quick. Unless you're going to have tens of thousands of these rectangles, I think iterating through them will be fast enough. – Mark Ransom Oct 20 '12 at 03:26
  • 1
    [R*-Trees](http://en.wikipedia.org/wiki/R*_tree) is a good data structure for doing this type of lookups but I'm pretty sure it's massive overkill for your case. I suggest confirming that the iterative method won't do the job before you start getting fancy with your data structures. – Ze Blob Oct 20 '12 at 03:34
  • 2
    A quad tree would seem like a natural fit for this kind of problem (http://en.wikipedia.org/wiki/Quadtree). – RA. Oct 20 '12 at 03:45

1 Answers1

2

It sounds like your real question is about finding a good way to implement your editor, not the specifics of rectangle intersection performance.

You may be interested in Qt's "Diagram Scene" example project, which demonstrates the QGraphicsScene API. It sounds like a good fit for the scenario you describe. (The full source for the example ships with Qt.)

enter image description here

The best part is that you still don't have to implement hit testing yourself, because the API already provides what you are looking for (e.g., QGraphicsScene::itemAt()).

It's worth noting that internally, QGraphicsScene uses a simple iterative method to perform hit tests. As others have pointed out, this isn't going to be a serious bottleneck unless your scenes have a lot of individual items.

jmk
  • 1,938
  • 14
  • 15
  • And here I was about to re-invent the wheel...Thanks a ton for pointing this out. Next time I'll be sure to look at the examples in the documentation (I didn't realize it was so extensive). – Los Frijoles Oct 27 '12 at 19:24
  • Yup, they have a lot of good examples that cover a wide range of features! – jmk Oct 28 '12 at 17:36