interactive_graphics_view.py
Go to the documentation of this file.
1 # Copyright (c) 2011, Dirk Thomas, TU Darmstadt
2 # All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions
6 # are met:
7 #
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following
12 # disclaimer in the documentation and/or other materials provided
13 # with the distribution.
14 # * Neither the name of the TU Darmstadt nor the names of its
15 # contributors may be used to endorse or promote products derived
16 # from this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 # POSSIBILITY OF SUCH DAMAGE.
30 
31 from __future__ import division
32 
33 from python_qt_binding.QtCore import QPointF, QRectF, Qt
34 from python_qt_binding.QtGui import QTransform
35 from python_qt_binding.QtWidgets import QGraphicsView
36 
37 
38 class InteractiveGraphicsView(QGraphicsView):
39 
40  def __init__(self, parent=None):
41  super(InteractiveGraphicsView, self).__init__(parent)
42  self.setObjectName('InteractiveGraphicsView')
43 
44  self._last_pan_point = None
45  self._last_scene_center = None
46 
47  def mousePressEvent(self, mouse_event):
48  self._last_pan_point = mouse_event.pos()
49  self._last_scene_center = self._map_to_scene_f(QRectF(self.frameRect()).center())
50  self.setCursor(Qt.ClosedHandCursor)
51 
52  def mouseReleaseEvent(self, mouse_event):
53  self.setCursor(Qt.OpenHandCursor)
54  self._last_pan_point = None
55 
56  def mouseMoveEvent(self, mouse_event):
57  if self._last_pan_point is not None:
58  delta_scene = self.mapToScene(mouse_event.pos()) - self.mapToScene(self._last_pan_point)
59  if not delta_scene.isNull():
60  self.centerOn(self._last_scene_center - delta_scene)
61  self._last_scene_center -= delta_scene
62  self._last_pan_point = mouse_event.pos()
63  QGraphicsView.mouseMoveEvent(self, mouse_event)
64 
65  def wheelEvent(self, wheel_event):
66  if wheel_event.modifiers() == Qt.NoModifier:
67  try:
68  delta = wheel_event.angleDelta().y()
69  except AttributeError:
70  delta = wheel_event.delta()
71  delta = max(min(delta, 480), -480)
72  mouse_before_scale_in_scene = self.mapToScene(wheel_event.pos())
73 
74  scale_factor = 1 + (0.2 * (delta / 120.0))
75  scaling = QTransform(scale_factor, 0, 0, scale_factor, 0, 0)
76  self.setTransform(self.transform() * scaling)
77 
78  mouse_after_scale_in_scene = self.mapToScene(wheel_event.pos())
79  center_in_scene = self.mapToScene(self.frameRect().center())
80  self.centerOn(
81  center_in_scene + mouse_before_scale_in_scene - mouse_after_scale_in_scene)
82 
83  wheel_event.accept()
84  else:
85  QGraphicsView.wheelEvent(self, wheel_event)
86 
87  def _map_to_scene_f(self, pointf):
88  point = pointf.toPoint()
89  if pointf.x() == point.x() and pointf.y() == point.y():
90  # map integer coordinates
91  return self.mapToScene(point)
92  elif pointf.x() == point.x():
93  # map integer x and decimal y coordinates
94  pointA = self.mapToScene((pointf + QPointF(0, -0.5)).toPoint())
95  pointB = self.mapToScene((pointf + QPointF(0, 0.5)).toPoint())
96  return (pointA + pointB) / 2.0
97  elif pointf.y() == point.y():
98  # map decimal x and integer y and coordinates
99  pointA = self.mapToScene((pointf + QPointF(-0.5, 0)).toPoint())
100  pointB = self.mapToScene((pointf + QPointF(0.5, 0)).toPoint())
101  return (pointA + pointB) / 2.0
102  else:
103  # map decimal coordinates
104  pointA = self.mapToScene((pointf + QPointF(-0.5, -0.5)).toPoint())
105  pointB = self.mapToScene((pointf + QPointF(-0.5, 0.5)).toPoint())
106  pointC = self.mapToScene((pointf + QPointF(0.5, -0.5)).toPoint())
107  pointD = self.mapToScene((pointf + QPointF(0.5, 0.5)).toPoint())
108  return (pointA + pointB + pointC + pointD) / 4.0


rqt_graph
Author(s): Dirk Thomas , Aaron Blasdel
autogenerated on Mon Oct 19 2020 03:41:30