в настоящее время я создаю минималистичную программу просмотра svg, в которой пользователь должен иметь возможность выбирать подэлементы нарисованной графики.
Кусочная визуализация svg достигается с помощью
QGraphicsSvgItem с общим средством визуализации. Затем элементы добавляются один за другим в QGraphicsScene, который связан с QGraphicsView.
Нет, самое сложное. Мне нужен одиночный выбор элементов (щелчком по ним) и множественный выбор с помощью резинки.
В настоящее время я борюсь с распространением событий щелчка мыши. В документации сказано, что все события распространяются от детей к родителям. Другими словами: щелкнув SvgItem, я бы предположил, что обработчик события Item запускает до обработчик средства просмотра. Это не тот случай.
Я создал пример приложения:
from PyQt5 import QtWidgets
from PyQt5.QtSvg import QGraphicsSvgItem, QSvgRenderer
class SvgItem(QGraphicsSvgItem):
def __init__(self, id, renderer, parent=None):
super().__init__(parent)
self.id = id
self.setSharedRenderer(renderer)
self.setElementId(id)
bounds = renderer.boundsOnElement(id)
self.setPos(bounds.topLeft())
self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, True)
def mousePressEvent(self, event: 'QtWidgets.QGraphicsSceneMouseEvent'):
print('svg item: ' + self.id + ' - mousePressEvent()')
super().mousePressEvent(event)
def mouseReleaseEvent(self, event: 'QtWidgets.QGraphicsSceneMouseEvent'):
print('svg item: ' + self.id + ' - mouseReleaseEvent()')
super().mouseReleaseEvent(event)
class SvgViewer(QtWidgets.QGraphicsView):
def __init__(self, parent):
super().__init__(parent)
self._scene = QtWidgets.QGraphicsScene(self)
self._renderer = QSvgRenderer()
self.setScene(self._scene)
def set_svg(self, data):
self.resetTransform()
self._scene.clear()
self._renderer.load(data)
item1 = SvgItem('p2', self._renderer)
self._scene.addItem(item1)
item2 = SvgItem('p3', self._renderer)
self._scene.addItem(item2)
def mousePressEvent(self, event: 'QtWidgets.QGraphicsSceneMouseEvent'):
print('SvgViewer - mousePressEvent()')
super().mousePressEvent(event)
def mouseReleaseEvent(self, event: 'QtWidgets.QGraphicsSceneMouseEvent'):
print('SvgViewer - mouseReleaseEvent()')
super().mouseReleaseEvent(event)
class Window(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.viewer = SvgViewer(self)
vb_layout = QtWidgets.QVBoxLayout(self)
vb_layout.addWidget(self.viewer)
img = b'''
<svg viewBox='0 0 108 95' xmlns='http://www.w3.org/2000/svg'>
<g transform='scale(0.1)'>
<path id = "p2" d='M249,699v43h211v-43h-64l-2,3l-2,4l-4,3c0,0-1,2-2,2h-4c-2,0-3,0-4,1c-1,1-3,1-3,
2l-3,4c0,1-1,2-2,2h-4c0,0-2,1-3,0l-3-1c-1,0-3-1-3-2c-1-1,0-2-1-3l-1-3c-1-1-2-1-3-1c-1,0-4,
0-4-1c0-2,0-3-1-4v-3v-3z'/>
<path id = "p3" d='M385,593c0,9-6,15-13,15c-7,0-13-6-13-15c0-8,12-39,14-39c1,0,12,31,12,39'/>
</g>
</svg>'''
self.viewer.set_svg(img)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 600, 400)
window.show()
sys.exit(app.exec_())
Щелчок по отображаемому элементу svg дает следующий вывод консоли:
SvgViewer - mousePressEvent()
svg item: p3 - mousePressEvent()
SvgViewer - mouseReleaseEvent()
svg item: p3 - mouseReleaseEvent()
Моя цель - следующее поведение:
Как я могу пропустить обработку событий в средстве просмотра, когда щелчок левой кнопкой мыши находится над видимым элементом (предпочтительно без какой-либо логики, основанной на ручных проверках положения)?
Любое предложение более чем приветствуется!
что означает прямоугольник выделения не создается?






Не могли бы вы мне лучше объяснить, чего вы хотите, чтобы не происходило, когда вы щелкаете левой кнопкой мыши по видимому элементу? С другой стороны, элементы не являются виджетами, поэтому логика иная, поэтому было бы здорово, если бы вы указали в документации, что вы указываете, что события мыши распространяются от родителей к дочерним элементам в QGraphicsItem.