Распространение события QGraphicsSvgItem (интерактивная программа просмотра svg)

в настоящее время я создаю минималистичную программу просмотра 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()

Моя цель - следующее поведение:

  1. пользователь нажимает на элемент -> этот элемент выбран (событие принимается, и прямоугольник выбора не создается)
  2. пользователь нажимает на пустую область и начинает перемещать мышь -> начинает появляться прямоугольник выбора

Как я могу пропустить обработку событий в средстве просмотра, когда щелчок левой кнопкой мыши находится над видимым элементом (предпочтительно без какой-либо логики, основанной на ручных проверках положения)?

Любое предложение более чем приветствуется!

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

eyllanesc 14.11.2018 02:21

что означает прямоугольник выделения не создается?

eyllanesc 14.11.2018 02:23
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
389
0

Другие вопросы по теме