Reputation: 4777
I have a collection of QGraphicsItem
inside a QGraphicsScene
. I'm trying to get the behavior of holding ctrl
key and deselect any items within a selection marquee. The problem is that the current selection will clear on a mouse press. Is there something I'm missing to prevent this?
The only thing I can think of is saving the current selection on mouse release, then restoring it on the next mouse pressed event. This doesn't seem very elegant though so I'm hoping to avoid this.
Upvotes: 2
Views: 715
Reputation: 4777
This gives me the behavior I'm looking for. I know it's not the most efficient approach, so please let me know if this can still be improved!
# Override double click event so it doesn't clear selection
def mouseDoubleClickEvent(self, event):
pass
def mousePressEvent(self, event):
QtGui.QGraphicsView.mousePressEvent(self, event)
# Save state of mouse button and any key modifiers
self.mouseButton = event.button()
self.modifiers = event.modifiers()
# If a modifier key is held, don't clear the selection!
if self.modifiers == QtCore.Qt.SHIFT or self.modifiers == QtCore.Qt.CTRL:
if self.lastSelection:
for item in self.lastSelection:
item.setSelected(True)
else:
self.scene().clearSelection()
def mouseMoveEvent(self, event):
QtGui.QGraphicsView.mouseMoveEvent(self, event)
# Only apply if the left mouse button is being held down
if self.mouseButton == QtCore.Qt.MouseButton.LeftButton:
# Add items to current selection if shift is held down
if self.modifiers == QtCore.Qt.SHIFT:
sel = set( self.lastSelection ).union( set( self.scene().selectedItems() ) )
for item in sel:
item.setSelected(True)
# Remove items from current selection if ctrl is held down
elif self.modifiers == QtCore.Qt.CTRL:
sel = set( self.lastSelection ).union( set( self.scene().selectedItems() ) )
dif = set( self.lastSelection ).symmetric_difference( set( self.scene().selectedItems() ) )
for item in sel:
selectState = not (item not in self.lastSelection or item not in dif)
item.setSelected(selectState)
def mouseReleaseEvent(self, event):
QtGui.QGraphicsView.mouseReleaseEvent(self, event)
# Reset values
self.mouseButton = None
self.modifiers = None
self.lastSelection = self.scene().selectedItems() # Store last selected items
So now if I hold ctrl
it will deselect items, holding shift
will add to the selection, and a normal mouse click will just clear the selection as expected.
The only thing to add to this would be to include shift
& ctrl
to a single mouse click, but since holding ctrl
does add AND remove then this is good enough for now.
Upvotes: 2