为了账号安全,请及时绑定邮箱和手机立即绑定

改变 QGraphicsView 的方向

改变 QGraphicsView 的方向

倚天杖 2022-01-11 20:23:19
我有一些与 some 相关联的 x 和 y 坐标,QGraphicItems然后放入QGraphicView. 我最近注意到,在选择具有 RubberBand 功能的项目时,我的点的方向不正确。我有 4 个重叠的点,它们重叠在错误的位置,我做了一些调试,发现我的原点从左上角开始,Y+ 向下,X+ 向右。我想要我的系统,这样 Y+ 会随着它的上升而变大。我已经截取了一个屏幕截图来显示当前代码的结果(我将在下面粘贴)并且我在点旁边放了数字。这些数字代表该位置有多少个点。另外,我已经设置了 X 和 Y 方向。然后移动点旁边的数字来代表我想要实现的目标。连同我正在寻找的 X 和 Y 方向。我还注意到它似乎正在标准化坐标。如果我能保留实际的 X 和 Y 位置,那将是最好的。这是我目前拥有的照片这就是我想要的这是我当前的代码from PyQt5.QtCore import *from PyQt5.QtGui import *from PyQt5.QtWidgets import *import sysfrom math import sqrtclass LogObject(QObject):    hovered = pyqtSignal()    notHovered = pyqtSignal()class Point(QGraphicsRectItem):    def __init__(self, x, y, name):        super(Point, self).__init__(QRectF(0, 0, 30, 30))        self.setFlag(QGraphicsItem.ItemIsSelectable, True)        self.name = name        self.x = x        self.y = y        self.setBrush(QBrush(Qt.black))        self.setAcceptHoverEvents(True)        self.log = LogObject()        self.setPos(x, y)    def itemChange(self, change, value):        if change == self.ItemSelectedChange:            self.setBrush(QBrush(Qt.green) if value else QBrush(Qt.black))        return QGraphicsItem.itemChange(self, change, value)    def hoverEnterEvent(self, event):        self.setBrush(QColor("red"))        self.log.hovered.emit()        QGraphicsItem.hoverMoveEvent(self, event)    def hoverLeaveEvent(self, event):        self.setBrush(QColor("black"))        self.log.notHovered.emit()        QGraphicsItem.hoverMoveEvent(self, event)    def mousePressEvent(self, event):        print(self.name)        QGraphicsItem.mousePressEvent(self, event)class Viewer(QGraphicsView):    photoClicked = pyqtSignal(QPoint)    rectChanged = pyqtSignal(QRect)    def __init__(self, parent):        super(Viewer, self).__init__(parent)        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)        self.setMouseTracking(True)        self.origin = QPoint()        self.changeRubberBand = False        self._zoom = 0        self._empty = True        self._scene = QGraphicsScene(self)
查看完整描述

1 回答

?
慕的地6264312

TA贡献1817条经验 获得超6个赞

这个想法是用 (1, -1) 缩放场景,这将使 Y 轴反转。另一方面,QGraphicsView 已经有一个 fitInView 方法,所以我将使用它,因为您当前的方法会产生问题


class LogObject(QObject):

    hovered = pyqtSignal()

    notHovered = pyqtSignal()



class Point(QGraphicsRectItem):

    def __init__(self, x, y, name):

        super(Point, self).__init__(QRectF(0, 0, 30, 30))

        self.setFlag(QGraphicsItem.ItemIsSelectable, True)

        self.name = name

        self.setBrush(QBrush(Qt.black))

        self.setAcceptHoverEvents(True)

        self.log = LogObject()

        self.setPos(x, y)


    def itemChange(self, change, value):

        if change == self.ItemSelectedChange:

            self.setBrush(QBrush(Qt.green) if value else QBrush(Qt.black))

        return QGraphicsItem.itemChange(self, change, value)


    def hoverEnterEvent(self, event):

        self.setBrush(QColor("red"))

        self.log.hovered.emit()

        QGraphicsItem.hoverMoveEvent(self, event)


    def hoverLeaveEvent(self, event):

        self.setBrush(QColor("black"))

        self.log.notHovered.emit()

        QGraphicsItem.hoverMoveEvent(self, event)


    def mousePressEvent(self, event):

        print(self.name)

        QGraphicsItem.mousePressEvent(self, event)



class Viewer(QGraphicsView):

    photoClicked = pyqtSignal(QPoint)

    rectChanged = pyqtSignal(QRect)


    def __init__(self, parent):

        super(Viewer, self).__init__(parent)

        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)

        self.setMouseTracking(True)

        self.origin = QPoint()

        self.changeRubberBand = False


        self._zoom = 0

        self._empty = True

        self.setScene(QGraphicsScene(self))


        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)

        self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)

        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.setFrameShape(QFrame.NoFrame)

        self.area = float()

        self.setPoints()

        self.viewport().setCursor(Qt.ArrowCursor)

        QTimer.singleShot(0, self.reset_fit)


    def setItems(self):

        self.data = {

            "x": [

                -2414943.8686,

                -2417160.6592,

                -2417160.6592,

                -2417856.1783,

                -2417054.7618,

                -2416009.9966,

                -2416012.5232,

                -2418160.8952,

                -2418160.8952,

                -2416012.5232,

                -2417094.7694,

                -2417094.7694,

            ],

            "y": [

                10454269.7008,

                10454147.2672,

                10454147.2672,

                10453285.2456,

                10452556.8132,

                10453240.2808,

                10455255.8752,

                10455183.1912,

                10455183.1912,

                10455255.8752,

                10456212.5959,

                10456212.5959,

            ],

        }

        maxX = max(self.data["x"])

        minX = min(self.data["x"])

        maxY = max(self.data["y"])

        minY = min(self.data["y"])

        distance = sqrt((maxX - minX) ** 2 + (maxY - minY) ** 2)


        self.area = QRectF(minX, minY, distance, distance)

        self.scene().setSceneRect(

            QRectF(minX, -minY, distance, distance)

        )  # Tried this but didn't seem to do anything

        for i, (x, y) in enumerate(zip(self.data["x"], self.data["y"])):

            p = Point(x, y, "Point__" + str(i))

            p.log.hovered.connect(self.hoverChange)

            p.log.notHovered.connect(self.notHoverChange)

            self.scene().addItem(p)


    def setPoints(self):

        self.setItems()

        self.setDragMode(self.ScrollHandDrag)


    def wheelEvent(self, event):

        if event.angleDelta().y() > 0:

            factor = 1.25

            self._zoom += 1

        else:

            factor = 0.8

            self._zoom -= 1

        if self._zoom > 0:

            self.scale(factor, factor)

        elif self._zoom == 0:

            self.reset_fit()

        else:

            self._zoom = 0


    def hoverChange(self):

        self.viewport().setCursor(Qt.PointingHandCursor)


    def notHoverChange(self):

        self.viewport().setCursor(Qt.ArrowCursor)


    def mousePressEvent(self, event):

        if event.button() == Qt.LeftButton:

            self.origin = event.pos()

            self.rubberBand.setGeometry(QRect(self.origin, QSize()))

            self.rectChanged.emit(self.rubberBand.geometry())

            self.rubberBand.show()

            self.changeRubberBand = True

            return


        elif event.button() == Qt.MidButton:

            self.viewport().setCursor(Qt.ClosedHandCursor)

            self.original_event = event

            handmade_event = QMouseEvent(

                QEvent.MouseButtonPress,

                QPointF(event.pos()),

                Qt.LeftButton,

                event.buttons(),

                Qt.KeyboardModifiers(),

            )

            QGraphicsView.mousePressEvent(self, handmade_event)


        super(Viewer, self).mousePressEvent(event)


    def mouseReleaseEvent(self, event):

        point = event.pos()

        print(self.mapToScene(point))

        if event.button() == Qt.LeftButton:

            self.changeRubberBand = False

            if self.rubberBand.isVisible():

                self.rubberBand.hide()

                rect = self.rubberBand.geometry()

                rect_scene = self.mapToScene(rect).boundingRect()

                selected = self.scene().items(rect_scene)

                if selected:

                    print(

                        "".join("Item: %s\n" % child.name for child in selected)

                    )

                else:

                    print(" Nothing\n")

            QGraphicsView.mouseReleaseEvent(self, event)


        elif event.button() == Qt.MidButton:

            self.viewport().setCursor(Qt.ArrowCursor)

            handmade_event = QMouseEvent(

                QEvent.MouseButtonRelease,

                QPointF(event.pos()),

                Qt.LeftButton,

                event.buttons(),

                Qt.KeyboardModifiers(),

            )

            QGraphicsView.mouseReleaseEvent(self, handmade_event)

        super(Viewer, self).mouseReleaseEvent(event)


    def mouseMoveEvent(self, event):

        if self.changeRubberBand:

            self.rubberBand.setGeometry(

                QRect(self.origin, event.pos()).normalized()

            )

            self.rectChanged.emit(self.rubberBand.geometry())

            QGraphicsView.mouseMoveEvent(self, event)

        super(Viewer, self).mouseMoveEvent(event)


    def hoverMoveEvent(self, event):

        point = event.pos().toPoint()

        print(point)

        QGraphicsView.hoverMoveEvent(event)


    def reset_fit(self):

        r = self.scene().itemsBoundingRect()

        self.resetTransform()

        self.setSceneRect(r)

        self.fitInView(r, Qt.KeepAspectRatio)

        self._zoom = 0

        self.scale(1, -1)



class Window(QWidget):

    def __init__(self):

        super(Window, self).__init__()

        self.viewer = Viewer(self)

        self.btnLoad = QToolButton(self)

        self.btnLoad.setText("Fit Into View")

        self.btnLoad.clicked.connect(self.fitPoints)


        VBlayout = QVBoxLayout(self)

        VBlayout.addWidget(self.viewer)

        HBlayout = QHBoxLayout()

        HBlayout.setAlignment(Qt.AlignLeft)

        HBlayout.addWidget(self.btnLoad)


        VBlayout.addLayout(HBlayout)


    def fitPoints(self):

        self.viewer.reset_fit()


查看完整回答
反对 回复 2022-01-11
  • 1 回答
  • 0 关注
  • 529 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信