简体   繁体   中英

Why can't I use the mouse Event(mouseMoveEvent, mouseReleaseEvent) on the graphicsview?

I want to make cropping image tool by using python and pyqt5

Below code, I can't use the mouseMoveEvent and mouseReleaseEvent on the graphic view.

But, I only can use the mousePressEvent on the graphicview. I checked the interactive about QGraphicView properties.

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PIL import Image
from PyQt5 import uic

QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)

IS_RESULT = False

CROP_UI = uic.loadUiType("Image_crop_screen.ui")[0]
BRING_IN_IMG_ROUTE = "C:/Users/yoon/Desktop/test/test.jpg"

class MainScreen(QMainWindow, CROP_UI):
    def __init__(self):

        super().__init__()
        self.setupUi(self)

        # Graphic Screen set
        self.img = QGraphicsPixmapItem(QPixmap(BRING_IN_IMG_ROUTE))
        self.scene = QGraphicsScene()

        self.scene.addItem(self.img)
        self.graphicsView.setScene(self.scene)

        self.graphicsView.pencolor = QColor(240, 240, 240)
        self.graphicsView.brushcolor = QColor(255, 255, 255, 0)

        QGV = QGraphicsView()

        self.items = []

        # Full Screen set size
        _WIDTH_ADD = 25
        _HEIGHT_ADD = 25
        self.setGeometry(0, 0, 640 + _WIDTH_ADD, 500 + _HEIGHT_ADD)


    def moveEvent(self, e):

        rect = QRectF(self.rect())
        rect.adjust(0, 0, 0, 0)  # 창 스크롤 바 없애기 위해서 일부 크기 작게 설정

        self.scene.setSceneRect(rect)

    # Draw rectangular while moving mouse
    def mouseMoveEvent(self, e):
        # e.buttons()는 정수형 값을 리턴, e.button()은 move시 Qt.Nobutton 리턴
        print(Qt.LeftButton)
        print(e.buttons())
        print(e)


        if e.buttons() & Qt.LeftButton:
            self.end = e.pos()
            pen = QPen(self.parent().pencolor)
            brush = QBrush(self.parent().brushcolor)
            pen.setWidth(3)

            # 장면에 그려진 이전 선을 제거
            if len(self.items) > 0:
                self.scene.removeItem(self.items[-1])
                del (self.items[-1])

            rect = QRectF(self.start, self.end)
            self.items.append(self.scene.addRect(rect, pen, brush))

    def mousePressEvent(self, e):
        if e.button() == Qt.LeftButton:
            # 시작점 저장
            self.start = e.pos()
            self.end = e.pos()

            print(Qt.LeftButton)
            print(e.buttons())
            print(e)

    def mouseReleaseEvent(self, e):
        print("aaa2")

        if e.button() == Qt.LeftButton:
            global IS_RESULT

            print("ttt2")

            pen = QPen(self.parent().pencolor)
            brush = QBrush(self.parent().brushcolor)

            self.items.clear()
            rect = QRectF(self.start, self.end)
            self.scene.addRect(rect, pen, brush)

            print("(" + str(self.start.x()) + ", " + str(self.start.y()) + "), (" + str(self.end.x()) + ", " + str(
                self.end.y()) + ")")
            area = (self.start.x(), self.start.y(), self.end.x(), self.end.y())



if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainScreen()
    w.show()

    sys.exit(app.exec_())

If you want to listen to the events of the QGraphicsView you should not override the events of another widget since some events will not be transmitted. In this case it is better to use an event filter that tracks the mouse, in this case the events of the viewport() of the QGraphicsView should be monitored.

In the following example I show how to create rectangles with the mouse.

class MainScreen(QMainWindow, CROP_UI):
    def __init__(self):

        super().__init__()
        self.setupUi(self)

        # Graphic Screen set
        self.img = QGraphicsPixmapItem(QPixmap(BRING_IN_IMG_ROUTE))
        self.scene = QGraphicsScene()
        self.scene.addItem(self.img)
        self.graphicsView.setScene(self.scene)

        # Full Screen set size
        _WIDTH_ADD = 25
        _HEIGHT_ADD = 25
        self.setGeometry(0, 0, 640 + _WIDTH_ADD, 500 + _HEIGHT_ADD)

        self.graphicsView.viewport().installEventFilter(self)

        self.current_item = None
        self.start_pos = QPointF()
        self.end_pos = QPointF()

    def eventFilter(self, o, e):
        if self.graphicsView.viewport() is o:
            if e.type() == QEvent.MouseButtonPress:
                if e.buttons() & Qt.LeftButton:
                    print("press")
                    self.start_pos = self.end_pos = self.graphicsView.mapToScene(
                        e.pos()
                    )
                    pen = QPen(QColor(240, 240, 240))
                    pen.setWidth(3)
                    brush = QBrush(QColor(100, 255, 100, 100))
                    self.current_item = self.scene.addRect(QRectF(), pen, brush)
                    self._update_item()
            elif e.type() == QEvent.MouseMove:
                if e.buttons() & Qt.LeftButton and self.current_item is not None:
                    print("move")
                    self.end_pos = self.graphicsView.mapToScene(e.pos())
                    self._update_item()
            elif e.type() == QEvent.MouseButtonRelease:
                print("release")
                self.end_pos = self.graphicsView.mapToScene(e.pos())
                self._update_item()
                self.current_item = None

        return super().eventFilter(o, e)

    def _update_item(self):
        if self.current_item is not None:
            self.current_item.setRect(QRectF(self.start_pos, self.end_pos).normalized())

You have to create a class with type QGraphicView in which you will use the mouse events

class MyGraphicView(QGraphicsView):
   def __init__():
      super.__init__(self)
      self.myScene = QGraphicsScene()
      self.setScene(self.myScene)
      # the rest code

   def mousePressEvent(self, event):
      ...
   def mouseMoveEvent(self, event):
      ...
   def mouseReleaseEvent(self, event):
      ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM