PDA

View Full Version : Conditional rubber band selection in QGraphicsView



stevel
13th January 2011, 00:34
I have a QGraphicsView based object in my project, with rubber band selection enabled. In the project, we have several selection modes. In some modes, some types of objects can be selected, and in other modes other types of objects can be selected.
Anyone have a suggestion as to where I should interfere with the selection of the items, if they are not the type of item that should be selected with the current mode? I've already implemented an event handler that controls mouse press selection, but there don't seem to be events for rubber band selection that I can find.

Thanks for any suggestions.

high_flyer
13th January 2011, 07:51
I think the simplest way to do this would be to set your items 'ItemIsSelectable" flag to QGraphicsItem::ItemIsSelectable when the mode allows the items to be selected, or remove the flag making the item not selectable in modes where items should not be selectable.

stevel
13th January 2011, 17:23
That might be simplest in a simple situation, but I have multiple windows, with potentially thousands of items, and the calculation as to whether or not they are selectable is fairly complex. For example, there are several different cursors, and each allows selection of certain types of items, but some of those items are selectable in some windows, and not in others. In the case of a click, I am intercepting the event, as I mentioned above, and that allows me to look at which cursor is selected, which window it's in, and which type of item it is. I don't think that changing the selectable state on the items is practical, unless I can change it in response to the rubber band selection event, which kind of brings me full circle back to my original question. Any other thoughts? (Thanks for the suggestion, by the way.)

high_flyer
13th January 2011, 19:33
I don't quite follow on the problem.
The fact that you have a complex set of rules to decide which item should be selectable or not, is a code that will have to be written somewhere in your application - there is not way around that.
Since you want to make the items not/selectable for the rubber band as well, I don't see how you can come around settings the selectable flag on the items, if some items should be selected and others not, under one rubber band.
The only other way would be to have your select logic run while you drag the rubber band, and deselect them while you do it.
Not an approach I would recommend, specially as you said you have many items.

Usually such complex rules to do something, tend to show a not well thought through design.
So I would suggest as first step to take the time, and optimize the way the selection logic should work.
And only then go about how to implement it.

stevel
13th January 2011, 21:18
I think I have a pretty clean implementation in place of a complex system, and I will try to explain the problem more clearly. I may well be wrong, and changing the selectable state of the items may be a better solution, but at the moment I am not seeing it.

We have multiple windows, which serve very different purposes. There are multiple types of items, some of which are present on some of these window, and some of which are not. (They are all QGrapicsItems, although some are QProxyWidgets.) I currently have the selectable state set to true for all items. When the user clicks on an item, I decide what to do with the click in the event message handler. I could update the selectable state for each item in each window when ever the user either selects a different cursor, or activates a different window, but I don't think this would be as efficient as responding to the event. (Again we could have even as many as hundreds of thousands of items in the views.)

I am not sure if I have clarified the question, or just repeated it. Let me know.

Added after 1 31 minutes:

Actually, I've been thinking about it, and event though my selection criteria are quite complex, you may be right that going back to setting the selectable state on each item might be better then what I am doing. I can change the state on the items when the user selects a different cursor, and/or when a window is activate. I can also set the state of some kinds of items differently in some windows then in others. I will play with this, but maybe I should back off on the way I was doing this. Thanks for the comments. The only worry I still have is how quick looping through thousands of items to set the state to a different value will be, but I think that this won't be too bad.

high_flyer
14th January 2011, 08:32
The only worry I still have is how quick looping through thousands of items to set the state to a different value will be, but I think that this won't be too bad.
What I don't understand (out from what you explain so far) is why do you need to loop over so many items?
As far as I can tell from what you have written is that you have two cases:
1. When a single item is clicked - should be selected or not)
2. Rubber band - which item under it should be selected.
In both cases you deal with one or several items - surly not all items all over the application - thus, again, fail to see where the problem is...
It seems to me you are over complicating things - but I could be wrong, due to misunderstanding, or just because I don't know anything about your code.