Изменение значения X прямоугольника фактически не перемещает его в GUI - PullRequest
1 голос
/ 29 января 2020

Я работаю над GUI в Python с PySide2. У меня есть GraphicsView, куда я помещу изображение, и я хотел бы нарисовать и переместить многоугольник вокруг этого изображения. Я нашел много примеров простого рисования многоугольников, кругов и т. Д. c. в PySide, PySide2 или PyQt 4/5 в Python. Однако я не смог выяснить, почему мои графические элементы не перемещаются по событию без удаления и перерисовки.

Я использую клавиатуру для изменения значения X на PySide2 QRectF. Значение X явно меняется, но прямоугольник фактически не двигается.

Вот минимальный пример:

from PySide2 import QtCore, QtGui, QtWidgets
from functools import partial

class DebuggingDrawing(QtWidgets.QGraphicsView):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # initialize the scene and set the size
        self._scene = QtWidgets.QGraphicsScene(self)
        self._scene.setSceneRect(0,0,500,500)
        self.setScene(self._scene)

        # make a green pen and draw a 10 wide, 20 high rectangle at x=20, y=30
        self.pen = QtGui.QPen(QtCore.Qt.green, 0)
        self.draw_rect = QtCore.QRectF(20, 30, 10, 20)
        # add the rectangle to our scene
        self._scene.addRect(self.draw_rect, self.pen)

    def move_rect(self, dx: int):
        # method for moving the existing rectangle
        # get the x value
        x = self.draw_rect.x()
        print('x: {} dx: {}'.format(x, dx))
        # use the moveLeft method of QRectF to change the rectangle's left side x value
        self.draw_rect.moveLeft(x + dx)
        self.update()


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()
        self.labelImg = DebuggingDrawing()

        # Get a keyboard shortcut and hook it up to the move_rect method
        next_shortcut = QtWidgets.QShortcut(QtGui.QKeySequence('Right'), self)
        next_shortcut.activated.connect(partial(self.labelImg.move_rect, 1))

        # get the left key shortcut, move_rect one pixel left
        back_shortcut = QtWidgets.QShortcut(QtGui.QKeySequence('Left'), self)
        back_shortcut.activated.connect(partial(self.labelImg.move_rect, -1))

        self.setCentralWidget(self.labelImg)

        self.setMaximumHeight(480)
        self.update()

if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    testing = MainWindow()
    testing.show()
    app.exec_()

Вот как выглядит результат:

enter image description here

Вы явно не можете видеть на изображении, но даже если значение прямоугольника x изменяется в соответствии с нашими вызовами печати, ничто не перемещается на изображении. Я подтвердил, что это не только мои глаза, потому что, если я нарисую новые прямоугольники в move_rect, они четко проявятся.

1 Ответ

2 голосов
/ 29 января 2020

draw_rect - это QRectF - вход для создания элемента (QGraphicsRectItem), который возвращается методом addRect(), аналогичным pen, то есть она берет информацию, но больше не использует ее. Идея состоит в том, чтобы переместить элемент, используя setPos():

class DebuggingDrawing(QtWidgets.QGraphicsView):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # initialize the scene and set the size
        self._scene = QtWidgets.QGraphicsScene(self)
        self._scene.setSceneRect(0, 0, 500, 500)
        self.setScene(self._scene)

        # make a green pen and draw a 10 wide, 20 high rectangle at x=20, y=30
        pen = QtGui.QPen(QtCore.Qt.green, 0)
        draw_rect = QtCore.QRectF(20, 30, 10, 20)
        # add the rectangle to our scene
        <b>self.item_rect = </b>self._scene.addRect(draw_rect, pen)

    def move_rect(self, dx: int):
        p = self.item_rect.pos()
        p += QtCore.QPointF(dx, 0)
        self.item_rect.setPos(p)

Если вы все еще хотите использовать draw_rect, вам нужно установить его снова в элементе:

    self.pen = QtGui.QPen(QtCore.Qt.green, 0)
    self.draw_rect = QtCore.QRectF(20, 30, 10, 20)
    # add the rectangle to our scene
    <b>self.item_rect = </b>self._scene.addRect(self.draw_rect, self.pen)

def move_rect(self, dx: int):
    # method for moving the existing rectangle
    # get the x value
    x = self.draw_rect.x()
    print('x: {} dx: {}'.format(x, dx))
    # use the moveLeft method of QRectF to change the rectangle's left side x value
    self.draw_rect.moveLeft(x + dx)
    <b>self.item_rect.setRect(self.draw_rect)</b>

Это рекомендовал прочитать "Graphics View Framework" , чтобы работали QGraphicsItems, QGraphicsView и QGraphicsScene.

...