QRubberBand move on QGraphicsView after resizing

妖精的绣舞 提交于 2020-02-16 06:15:31

问题


I have the same problem from this topic: QRubberBand move when I resize window, after a few try I realized that solution from this topic doesn't apply on QGraphics View. Why my selection move, arout QgraphicsView when I resize window.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
# from PyQt4 import QtCore, QtWidgets

class ResizableRubberBand(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(ResizableRubberBand, self).__init__(parent)
        self.draggable = False
        self.mousePressPos = None
        self.mouseMovePos = None
        self._band = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)
        self._band.setGeometry(550, 550, 550, 550)
        self._band.show()
        self.show()

    def mousePressEvent(self, event):
            if event.button() == QtCore.Qt.RightButton:
                self.mousePressPos = event.globalPos()                # global
                self.mouseMovePos = event.globalPos() - self.pos()    # local
                self.draggable = True
            elif event.button() == QtCore.Qt.LeftButton:
                self.position = QtCore.QPoint(event.pos())
                self.upper_left = self.position
                self.lower_right = self.position
                self.mode = "drag_lower_right"
                self._band.show()

    def mouseMoveEvent(self, event):
        if self.draggable and event.buttons() & QtCore.Qt.RightButton:
            globalPos = event.globalPos()
            print(globalPos)
            diff = globalPos - self.mouseMovePos
            self.move(diff)
            self.mouseMovePos = globalPos - self.pos()
        elif self._band.isVisible():
            # visible selection
            if self.mode is "drag_lower_right":
                self.lower_right = QtCore.QPoint(event.pos())
                # print(str(self.lower_right))
            elif self.mode is "drag_upper_left":
                self.upper_left = QtCore.QPoint(event.pos())
                # print(str(self.upper_left))
            # update geometry
            self._band.setGeometry(QtCore.QRect(self.upper_left, self.lower_right).normalized())

    def mouseReleaseEvent(self, event):
        self.draggable = False

my main class:

class Window(QtWidgets.QWidget):
    def __init__(self):
        super(Window, self).__init__()

        self.band = ResizableRubberBand()
        scene = QtWidgets.QGraphicsScene(self)
        photo = QtGui.QPixmap('image.jpg')
        scene.addPixmap(photo)
        self.band.setScene(scene)
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.band)



if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.setGeometry(800, 100, 600, 500)
    window.show()
    sys.exit(app.exec_())

before resize:

after resize:


回答1:


The problem is caused because the coordinate system of the image is not the same as that of the QRubberBand. So the solution is that you both share the same coordinate system and for this we add the QRubberBand to the scene.

from PyQt5 import QtCore, QtGui, QtWidgets


class GraphicsView(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(GraphicsView, self).__init__(parent)
        self.setScene(QtWidgets.QGraphicsScene(self))
        self.m_rubberBand = QtWidgets.QRubberBand(
            QtWidgets.QRubberBand.Rectangle
        )
        self.m_rubberBand.setGeometry(QtCore.QRect(-1, -1, 2, 2))
        self.m_rubberBand.hide()
        item = self.scene().addWidget(self.m_rubberBand)
        item.setZValue(1)
        self.m_draggable = False

        self.m_origin = QtCore.QPoint()

    def mousePressEvent(self, event):
        self.m_origin = self.mapToScene(event.pos()).toPoint()

        self.m_rubberBand.setGeometry(
            QtCore.QRect(self.m_origin, QtCore.QSize())
        )
        self.m_rubberBand.show()

        self.m_draggable = True
        super(GraphicsView, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if self.m_draggable:
            end_pos = self.mapToScene(event.pos()).toPoint()
            self.m_rubberBand.setGeometry(
                QtCore.QRect(self.m_origin, end_pos).normalized()
            )
            self.m_rubberBand.show()

    def mouseReleaseEvent(self, event):
        end_pos = self.mapToScene(event.pos()).toPoint()
        self.m_rubberBand.setGeometry(
            QtCore.QRect(self.m_origin, end_pos).normalized()
        )
        self.m_draggable = False


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = GraphicsView()
    photo = QtGui.QPixmap("image.jpg")
    w.scene().addPixmap(photo)
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())



来源:https://stackoverflow.com/questions/56442627/qrubberband-move-on-qgraphicsview-after-resizing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!