QGraphicsRectItem - координаты точки интереса без применения матрицы преобразования
QGraphicsRectItem вставляется в QGraphicsScene, и к этому объекту может быть применено преобразование, что означает перевод и / или вращение.
Есть ли способ, как легко получить координаты (см. Рисунок), даже если объект находится в любом месте пространства, без применения матрицы преобразования?
Пример кода:
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import Qt,QRectF
from PySide2.QtGui import QImage,QPen
from PySide2.QtWidgets import QGraphicsItem
import cv2
class testUi(QtWidgets.QDialog):
def __init__(self, parent=None):
super(testUi, self).__init__(parent)
self.window = 'RectItem'
self.title = 'Test'
self.size = (1600, 1600)
self.create()
def create(self):
self.setWindowTitle(self.title)
self.resize(QtCore.QSize(*self.size))
self.view = graphView(self)
self.mainLayout = QtWidgets.QVBoxLayout()
self.mainLayout.addWidget(self.view)
self.editL = QtWidgets.QLineEdit()
self.editL.setPlaceholderText('Input angle for rotation')
self.mainLayout.addWidget(self.editL)
self.editL1 = QtWidgets.QLineEdit()
self.editL1.setPlaceholderText('Input x value for translation')
self.mainLayout.addWidget(self.editL1)
self.editL2 = QtWidgets.QLineEdit()
self.editL2.setPlaceholderText('Input y value for translation')
self.mainLayout.addWidget(self.editL2)
self.butt = QtWidgets.QPushButton('Apply transform')
self.butt.clicked.connect(self.applyTransform)
self.mainLayout.addWidget(self.butt)
self.butt1 = QtWidgets.QPushButton('Info')
self.butt1.clicked.connect(self.info)
self.mainLayout.addWidget(self.butt1)
self.setLayout(self.mainLayout)
self.addRect()
def applyTransform(self):
rotAlfa = None
traX = None
traY = None
if self.editL.text().lstrip("-").isdigit():
rotAlfa = float(self.editL.text())
else:
rotAlfa = 0
if self.editL1.text().lstrip("-").isdigit():
traX = float(self.editL1.text())
else:
traX = 0
if self.editL2.text().lstrip("-").isdigit():
traY = float(self.editL2.text())
else:
traY = 0
if rotAlfa != None and traX != None and traY != None:
for item in self.view._scene.items():
if item.__class__.__name__ == 'RectItem':
origin = item.transformOriginPoint()
transform = QtGui.QTransform()
transform.translate(origin.x(), origin.y())
transform.translate(traX, traY)
transform.rotate(rotAlfa, Qt.ZAxis)
transform.translate(-origin.x(), -origin.y())
item.setTransform(transform)
def info(self):
print('Info')
for item in self.view._scene.items():
if item.__class__.__name__ == 'RectItem':
origin = item.transformOriginPoint()
print((origin.x(), origin.y()), 'Origin x, y')
def addRect(self):
height, width = 1080, 1920
self.blank_image = np.zeros((height, width, 3), np.uint8)
self.copyBlankImg = self.blank_image.copy()
lenght = 100
width = 50
xCenterRect = 400
yCenterRect = 200
self.rectan = RectItem(QRectF(xCenterRect - int(lenght / 2), yCenterRect - int(width / 2), lenght, width))
self.rectan.setPen(QPen(QtGui.QColor(255, 150, 0)))
self.rectan.setTransformOriginPoint(xCenterRect, yCenterRect)
self.view._scene.addItem(self.rectan)
cv2.circle(self.copyBlankImg, (xCenterRect, yCenterRect), 1, (150, 150, 0), 2)
"""cv2.putText(self.copyBlankImg, str('Center point'),
(xCenterRect + 20, yCenterRect), cv2.FONT_ITALIC, 1, (150, 150, 0), 2)"""
cv2.circle(self.copyBlankImg, (xCenterRect + int(lenght / 2), yCenterRect), 5, (0, 0, 255), 2)
cv2.putText(self.copyBlankImg, str('Point of interest'),
(xCenterRect + int(lenght / 2) + 20, yCenterRect + 20), cv2.FONT_ITALIC, 1, (0, 0, 255), 2)
cv2.putText(self.copyBlankImg, str('Need to know new coordinates after transformation'),
(50, yCenterRect + 80), cv2.FONT_ITALIC, 1, (0, 0, 255), 2)
rgbObrImage = cv2.cvtColor(self.copyBlankImg, cv2.COLOR_BGR2RGB)
qObrImage = QImage(rgbObrImage.data, rgbObrImage.shape[1], rgbObrImage.shape[0],
QImage.Format_RGB888)
self.view.setPhoto(QtGui.QPixmap(qObrImage))
class RectItem(QtWidgets.QGraphicsRectItem):
def __init__(self, rectF):
super(RectItem, self).__init__()
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
self.setRect(rectF)
def itemChange(self, change, value):
print(change, value, 'change, value')
if change == QGraphicsItem.ItemPositionChange or QGraphicsItem.ItemRotationChange:
print('Position or rotation change')
return value
class graphView(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(graphView, self).__init__(parent)
self._scene = QtWidgets.QGraphicsScene()
self.val_zoom = 0
self._mapaPixmap = QtWidgets.QGraphicsPixmapItem()
self._scene.addItem(self._mapaPixmap)
self.setScene(self._scene)
self.setTransformationAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
self.setResizeAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
self.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(30, 30, 30)))
self.setFrameShape(QtWidgets.QFrame.NoFrame)
self.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding))
def wheelEvent(self, event):
if event.angleDelta().y() > 0:
factor = 1.25
self.val_zoom += 1
else:
factor = 0.8
self.val_zoom -= 1
if self.val_zoom > 0:
self.scale(factor, factor)
elif self.val_zoom == 0:
self.fitWindow()
else:
self.val_zoom = 0
def fitWindow(self, scale=True):
rect = QtCore.QRectF(self._mapaPixmap.pixmap().rect())
if not rect.isNull():
self.setSceneRect(rect)
unity = self.transform().mapRect(QtCore.QRectF(0, 0, 1, 1))
self.scale(1 / unity.width(), 1 / unity.height())
viewrect = self.viewport().rect()
scenerect = self.transform().mapRect(rect)
factor = min(viewrect.width() / scenerect.width(),
viewrect.height() / scenerect.height())
self.scale(factor, factor)
self.val_zoom = 0
def setPhoto(self, pixmap=None):
self.val_empty = False
self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
self._mapaPixmap.setPixmap(pixmap)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = testUi()
window.setGeometry(500, 300, 800, 600)
window.show()
sys.exit(app.exec_())