Как исправить изображение при перемещении элемента в QGraphicsViewer - PullRequest
0 голосов
/ 09 июля 2020

Я разрабатываю программу просмотра изображений с помощью pyqt.

Я хочу, чтобы изображение фиксировалось при перемещении поля.

Однако изображение выталкивается, когда поле пытается достичь зрителя сторона вот так.

перед перемещением коробки после перемещения коробки

Это было реализовано с использованием QGraphicsView, QGraphicsScene и QGraphicsitem.

Это часть основного класса

        self.scene_r = GraphicsScene()
        self.scene_r.addPixmap(pix_resized)
        self.resizedView.setScene(self.scene_r)
        self.resizedView.centerOn(128,128)

Это класс QGraphicScene

class GraphicsScene(QGraphicsScene):
def __init__(self, parent=None):
    QGraphicsScene.__init__(self)
    rect_item = recItem(QRectF(0, 0, 100, 100))
    rect_item.setFlag(QGraphicsItem.ItemIsMovable, True)
    rect_item.setZValue(1)
    rect_item.setPen(Qt.green)
    self.addItem(rect_item)

Я пытался переопределить mouseMoveEvent () класса QGraphicsRectItem, но это не удалось.

1 Ответ

0 голосов
/ 09 июля 2020

Это происходит по двум причинам:

  1. Поскольку вы делаете элемент подвижным, вы можете перемещать его свободно, где угодно по вашему желанию.
  2. Когда прямоугольник сцены меньше, чем тот, который отображается в представлении, представление пытается гарантировать, что весь прямоугольник сцены остается видимым, возможно, путем прокрутки его содержимого.

Обратите внимание, что, если явно не установлено с помощью setSceneRect() (на сцене или в представлении результаты могут отличаться), Qt автоматически устанавливает прямоугольник сцены неявно на больший QRect, содержащий все видимые графические элементы.

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

Явно установить sceneRect

Вы можете установить sceneRect на определенный прямоугольник c, элемент или все существующие элементы. Обратите внимание: хотя в вашем случае это не сильно изменится, если вы установите прямоугольник для сцены или вида, в более сложных случаях (например, несколько видов, показывающих одну и ту же сцену) результат может отличаться.

    # on the view
    self.setSceneRect(self.scene_r.itemsBoundingRect())
    # alternativaly, on the scene
    self.setSceneRect(self.itemsBoundingRect())

Ограничьте область, в которой элемент может быть перемещен

В этом случае вы можете перехватить itemChange ItemPositionChange (обратите внимание, что должен быть установлен флаг ItemSendsGeometryChanges) и возвращает скорректированное значение до того, как оно действительно применяется:

class RecItem(QGraphicsRectItem):
    def __init__(self, *args):
        super().__init__(*args)
        self.setFlags(self.ItemSendsGeometryChanges)

    def itemChange(self, change, value):
        if change == self.ItemPositionChange:
            sceneRect = self.scene().sceneRect()
            newGeometry = self.boundingRect().translated(value)
            # the item pen must be taken into account
            halfPen = self.pen().width() / 2
            if value.x() < sceneRect.x():
                value.setX(sceneRect.x() + halfPen)
            if value.y() < sceneRect.y():
                value.setY(sceneRect.y() + halfPen)
            if newGeometry.right() + halfPen > sceneRect.right():
                value.setX(sceneRect.right() - newGeometry.width())
            if newGeometry.bottom() + halfPen > sceneRect.bottom():
                value.setY(sceneRect.bottom() - newGeometry.height())
            return value
        return super().itemChange(change, value)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...