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

Я создал QGraphicsPathItem, передав конструктору QPainterPath с примерно 10 QPoint. Теперь, как я могу перемещать точки на пути вокруг?

Например:

Это для создания коробки:

path = QtGui.QPainterPath()
path.moveTo(0, 0)
path.lineTo(10, 0)
path.lineTo(10, 10)
path.lineTo(0, 10)

line = QtGui.QGraphicsPathItem()
line.setPath(path)

Теперь, по прошествии некоторого времени, я хочу сделать эту коробку шире, захватив верхнюю и нижнюю правые точки и переместив их вправо. Как я могу получить доступ к точкам? Документация Qt для QPainterPath указывает, что path.elementAt(i) — это способ доступа к данным внутри пути, но он возвращает QElementObject, и я не смог найти много документации для «объекта элемента», и это определенно не QPointF (что я бы хотел ожидать получить... верно?). Итак, как я могу получить QPointF из этого элемента? И как только я получу очки, можно ли просто вызвать их QPointF.setX() и QPointF.setY(), и линия будет перерисовываться, или мне нужно переустановить ее в QGraphicsPathItem с новым вызовом line.setPath()?

В качестве примечания это PyQt4, python 2.7. Однако я приму ответ на С++, если он у вас есть, хотя я вообще не знаю С++, его довольно легко перевести.


person Spencer    schedule 14.04.2018    source источник


Ответы (1)


получить координаты можно через path.elementAt(i).x, path.elementAt(i).y, а установить новые значения методом path.setElementPositionAt().

В следующем разделе я покажу пример.

import sys

import random

from PyQt4 import QtGui, QtCore

def movePoints():
    p = line.path()
    for i in range(p.elementCount()):
        xo, yo = p.elementAt(i).x, p.elementAt(i).y
        xn, yn = (e+10*(random.random()-0.5) for e in  (xo, yo))
        p.setElementPositionAt(i, xn, yn)
    line.setPath(p)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    w = QtGui.QGraphicsView()
    scene = QtGui.QGraphicsScene(w)
    w.setScene(scene)
    timer = QtCore.QTimer()
    timer.timeout.connect(movePoints)

    path = QtGui.QPainterPath()
    path.moveTo(0, 0)
    path.lineTo(10, 0)
    path.lineTo(10, 10)
    path.lineTo(0, 10)

    line = QtGui.QGraphicsPathItem()
    line.setPath(path)
    scene.addItem(line)
    timer.start(1000)
    w.show()
    sys.exit(app.exec_())

Если вы хотите использовать QPointF , код, эквивалентный примеру, следующий:

def movePoints():
    p = line.path()
    for i in range(p.elementCount()):
        point = QtCore.QPointF(p.elementAt(i))
        point += QtCore.QPointF(10*random.random()-5, 10*random.random()-5)
        p.setElementPositionAt(i, point.x(), point.y())
    line.setPath(p)
person eyllanesc    schedule 14.04.2018
comment
Спасибо, это как раз то, что мне было нужно! Я могу использовать p.setElementPositionAt() для своих нужд. Можете ли вы указать мне хороший учебный ресурс для приведения в python? Я впервые об этом слышу. - person Spencer; 14.04.2018
comment
@Spencer Прочитайте doc.qt.io/archives/qt -4,8/ - person eyllanesc; 14.04.2018
comment
Интересно, я не знал, что вы можете проводить кастинг таким образом. Думаю, я просто предположил, что вы можете использовать только встроенные методы Python (str, int, float и т. д.). - person Spencer; 14.04.2018
comment
@Spencer В c++ вы можете создавать операторы, я думаю, что в Python вы добавляете еще один конструктор в QPointF - person eyllanesc; 14.04.2018
comment
Да, теперь, когда я смотрю на это, ты прав. Извините, я немного устал прошлой ночью... Это не выполнение приведения С++ как таковое, это просто создание нового QPointF с элементом в качестве конструктора. Спасибо за помощь! - person Spencer; 15.04.2018