I want to make a QGraphicsScene
and show it in QGraphicsView
. I want to scroll the scene by middle mouse button and make rubber band selection by left button. But I don't know how to make the rubber band selection appear only by left mouse button.
Here's my code:
# -*- coding: utf-8 -*-
import os, sys
from PyQt5 import QtWidgets, QtCore, QtGui, QtSvg
class MegaSceneView(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(MegaSceneView, self).__init__(parent)
self._scale_factor = 1.0
self._scale_by = 1.2
self.setAcceptDrops(True)
self.setRenderHint(QtGui.QPainter.Antialiasing)
self.setMouseTracking(True)
self.setRubberBandSelectionMode(QtCore.Qt.IntersectsItemShape)
self.setDragMode(QtWidgets.QGraphicsView.RubberBandDrag)
self._prev_mouse_scene_pos = None
def mousePressEvent(self, event):
if (event.buttons() & QtCore.Qt.MidButton) != QtCore.Qt.NoButton:
self._prev_mouse_scene_pos = (event.pos())
super(MegaSceneView, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
super(MegaSceneView, self).mouseReleaseEvent(event)
self._prev_mouse_scene_pos = None
def mouseMoveEvent(self, event):
super(MegaSceneView, self).mouseMoveEvent(event)
if (event.buttons() & QtCore.Qt.MidButton) != QtCore.Qt.NoButton:
cur_mouse_pos = (event.pos())
if self._prev_mouse_scene_pos is not None:
delta_x = cur_mouse_pos.x() - self._prev_mouse_scene_pos.x()
delta_y = cur_mouse_pos.y() - self._prev_mouse_scene_pos.y()
self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() - delta_x)
self.verticalScrollBar().setValue(self.verticalScrollBar().value() - delta_y)
self._prev_mouse_scene_pos = (event.pos())
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mega_view = MegaSceneView()
mega_scene = QtWidgets.QGraphicsScene(-500, -500, 1000, 1000)
# mega_scene = QtWidgets.QGraphicsScene()
rect_item_1 = QtWidgets.QGraphicsRectItem(-30, -20, 60, 40)
mega_scene.addItem(rect_item_1)
rect_item_2 = QtWidgets.QGraphicsRectItem(-20, -30, 40, 60)
mega_scene.addItem(rect_item_2)
rect_item_2.setPos(300, 200)
mega_view.setScene(mega_scene)
mega_view.show()
sys.exit(app.exec_())
What should I add to make the rubber band appear only by left button?
You can set the drag mode in the mousePressEvent
and mouseReleaseEvent
functions in your view class, so it stays in the RubberBandDrag
as default, but switches to NoDrag
mode when the middle mouse button is held.
Like so - c++, but the idea is the same in all languages - :
void YourViewClass::mousePressEvent(QMouseEvent* event) {
if (event->buttons() == Qt::MiddleButton)
setDragMode(QGraphicsView::NoDrag);
}
void YourViewClass::mouseReleaseEvent(QMouseEvent* event) {
if (event->button() == Qt::MiddleButton)
setDragMode(QGraphicsView::RubberBandDrag);
}
There isn't a built-in way to do this. You will need to subclass the mousePressEvent
, mouseMoveEvent
, and mouseReleaseEvent
for your graphics view and create the visible rubber band yourself. (QRubberBand
works well for this.) When the user releases the mouse, you then need to convert the rubber band extents into scene coordinates and call QGraphicsScene::setSelectionArea
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With