У меня есть настраиваемые пользователем аннотации в графической сцене. Размер/поворот аннотаций регулируется перетаскиванием углов прямоугольника вокруг аннотации. Я использую пользовательский прямоугольник (вместо boundingRect), поэтому он следует повороту родительской аннотации. Углы управления отмечены двумя эллипсами, чьим родителем является прямоугольник, поэтому преобразования прямоугольника/эллипса/аннотации не вызывают затруднений.
Я хочу определить, когда курсор находится над одним из углов, какой это угол и точные координаты. Для этой задачи кажется, что я должен фильтровать hoverevents с помощью родительского прямоугольника, используя sceneEventFilter.
Я пробовал бесполезные способы реализации sceneEventFilter, но безрезультатно. Все события идут напрямую в функцию hoverEnterEvent. Я нашел только несколько примеров кода, которые делают что-то подобное, но я просто застрял. Кстати, я полностью самоучка на Python и QT за последние 3 месяца, так что, пожалуйста, потерпите меня. Я уверен, что упускаю что-то очень простое. Код представляет собой упрощенный графический интерфейс с двумя многоточиями. Мы пытаемся захватить события в sceneEventFilter, но всегда используем hoverEnterEvent.
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsItem
import sys
class myHandle(QtGui.QGraphicsEllipseItem):
def __init__(self, parent = None):
super(myHandle, self).__init__(parent)
def addTheHandle(self, h_parent = 'null', kind = 'null'):
handle_w = 40
if kind == 'scaling handle':
handle_x = h_parent.boundingRect().topRight().x() - handle_w/2
handle_y = h_parent.boundingRect().topRight().y() - handle_w/2
if kind == 'rotation handle':
handle_x = h_parent.boundingRect().topLeft().x() - handle_w/2
handle_y = h_parent.boundingRect().topLeft().y() - handle_w/2
the_handle = QtGui.QGraphicsEllipseItem(QtCore.QRectF(handle_x, handle_y, handle_w, handle_w))
the_handle.setPen(QtGui.QPen(QtGui.QColor(255, 100, 0), 3))
the_handle.setParentItem(h_parent)
the_handle.setAcceptHoverEvents(True)
the_handle.kind = kind
return the_handle
class myRect(QtGui.QGraphicsRectItem):
def __init__(self, parent = None):
super(myRect, self).__init__(parent)
def rectThing(self, boundingrectangle):
self.setAcceptHoverEvents(True)
self.setRect(boundingrectangle)
mh = myHandle()
rotation_handle = mh.addTheHandle(h_parent = self, kind = 'rotation handle')
scaling_handle = mh.addTheHandle(h_parent = self, kind = 'scaling handle')
self.installSceneEventFilter(rotation_handle)
self.installSceneEventFilter(scaling_handle)
return self, rotation_handle, scaling_handle
def sceneEventFilter(self, event):
print('scene ev filter')
return False
def hoverEnterEvent(self, event):
print('hover enter event')
class Basic(QtGui.QMainWindow):
def __init__(self):
super(Basic, self).__init__()
self.initUI()
def eventFilter(self, source, event):
return QtGui.QMainWindow.eventFilter(self, source, event)
def exit_the_program(self):
pg.exit()
def initUI(self):
self.resize(300, 300)
self.centralwidget = QtGui.QWidget()
self.setCentralWidget(self.centralwidget)
self.h_layout = QtGui.QHBoxLayout(self.centralwidget)
self.exit_program = QtGui.QPushButton('Exit')
self.exit_program.clicked.connect(self.exit_the_program)
self.h_layout.addWidget(self.exit_program)
self.this_scene = QGraphicsScene()
self.this_view = QGraphicsView(self.this_scene)
self.this_view.setMouseTracking(True)
self.this_view.viewport().installEventFilter(self)
self.h_layout.addWidget(self.this_view)
self.circle = self.this_scene.addEllipse(QtCore.QRectF(40, 40, 65, 65), QtGui.QPen(QtCore.Qt.black))
mr = myRect()
the_rect, rotation_handle, scaling_handle = mr.rectThing(self.circle.boundingRect())
the_rect.setPen(QtGui.QPen(QtCore.Qt.black))
the_rect.setParentItem(self.circle)
self.this_scene.addItem(the_rect)
self.this_scene.addItem(rotation_handle)
self.this_scene.addItem(scaling_handle)
def main():
app = QtGui.QApplication([])
main = Basic()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()