2017-11-03 164 views
1

사용자가로드 한 그림 위에 사각형을 클릭하고 그리는 방법에 대해 혼란스러워합니다. 따라하기 위해 시도한 몇 가지 예제를 발견했지만 아무 것도 작동하지 않는 것처럼 보입니다. 왜 고쳐야하는지, 어떻게 고쳐야하는지.PYQT 그림 위에 선택 사각형 그리기

일부 중단 점을 넣었으므로 mouseMoveEvent 함수에 포함되지 않는 것 같지만 그 이유는 확실하지 않습니다. 어떤 도움이라도 대단히 감사 할 것입니다.

나는

은 내가 QGraphics에로드 한 사진에 클릭 수 및 드래그 싶습니다과 상태 표시 줄 출력에 다음 X와 Y를 상자를 그리고있다 싶습니다 무엇 구형의 양쪽 점의 좌표. 또한 사용자가 두 번째로 그림을 클릭 할 때까지 사각형을 그대로두기를 원합니다.

예 나는

What I would like

Simple example

현재 코드

class MainWindow(QMainWindow, Ui_MainWindow): 
    def __init__(self, *args, **kwargs): 
     QMainWindow.__init__(self, *args, **kwargs) 
     self.setupUi(self) 
     self.setUpMainUiFunction() 

    def setUpMainUiFunction(self): 
     self.actionOpen.triggered.connect(self.OpenDialog) 
     self.Button_LoadPhoto.clicked.connect(self.OpenDialog) 

     open = QAction(QIcon("icons/open.bmp"), "open", self) 
     save = QAction(QIcon("icons/save.bmp"), "save", self) 
     NormalCursor = QAction(QIcon("icons/cursor-normal.png"), "NormalCursor", self) 
     CrosshairCursor = QAction(QIcon("icons/crosshair.png"), "CrosshairCursor", self) 

     self.TopToolBar.addAction(open) 
     self.TopToolBar.addAction(save) 
     self.LeftToolBar.addAction(NormalCursor) 
     self.LeftToolBar.addAction(CrosshairCursor) 

     # self.TopToolBar.actionTriggered[QAction].connect(self.toolbtnpressed) 

    def OpenDialog(self): 
     options = QFileDialog.Options() 
     options |= QFileDialog.DontUseNativeDialog 
     PicturePath = QStandardPaths.standardLocations(QStandardPaths.PicturesLocation)[0] 
     filenames, _ = QFileDialog.getOpenFileNames(self, "Open File", PicturePath, "JPEG File (*.png)", options=options) 
     for filename in filenames: 
      pixmap = QPixmap(filename) 
      self.showPicture(pixmap) 
      self.statusbar.showMessage("Successfully Loaded: {}".format(filename)) 

    def showPicture(self, picture): 
     sub = QMdiSubWindow(self) 
     loadPicture = LoadPicture(picture, sub) 
     sub.setWidget(loadPicture) 
     sub.setObjectName("Load_Picture_window") 
     sub.setWindowTitle("New Photo") 
     self.mdiArea.addSubWindow(sub) 
     sub.show() 
     sub.resize(picture.size()) 
     loadPicture.log.MousePixmapSignal.connect(self.updatePixel) 

    def updatePixel(self, point, color): 
     self.UserInput_PixelValue_X.setText("{}".format(point.x())) 
     self.UserInput_PixelValue_Y.setText("{}".format(point.y())) 

     self.UserInput_PixelValue_R.setText("{}".format(color.red())) 
     self.UserInput_PixelValue_G.setText("{}".format(color.green())) 
     self.UserInput_PixelValue_B.setText("{}".format(color.blue())) 

이것은 seprate 파일에을 발견했다. 우리는 그것을위한 방법 mouseMoveEvent, mousePressEvent,를 QGraphicsView의 mouseReleaseEvent을 덮어 써야합니다이 기능을 구현하기 위해

class LogObject(QObject): 
    MousePixmapSignal = pyqtSignal(QPoint, QColor) 


class PictureItem(QGraphicsPixmapItem): 
    def __init__(self, log, *args, **kwargs): 
     QGraphicsPixmapItem.__init__(self, *args, **kwargs) 
     self.setAcceptHoverEvents(True) 
     self.log = log 

    def hoverMoveEvent(self, event): 
     point = event.pos().toPoint() 
     color = QColor(self.pixmap().toImage().pixel(point.x(), point.y())) 
     self.log.MousePixmapSignal.emit(point, color) 
     QGraphicsPixmapItem.hoverMoveEvent(self, event) 

    def hoverEnterEvent(self, event): 
     QApplication.setOverrideCursor(Qt.CrossCursor) 
     QGraphicsPixmapItem.hoverMoveEvent(self, event) 

    def hoverLeaveEvent(self, event): 
     QApplication.setOverrideCursor(Qt.ArrowCursor) 
     QGraphicsPixmapItem.hoverLeaveEvent(self, event) 


    def paintEvent(self, event): 
     qp = QPainter(self) 
     br = QBrush(QColor(100, 10, 10, 40)) 
     qp.setBrush(br) 
     qp.drawRect(QRect(self.begin, self.end)) 

    def mousePressEvent(self, event): 
     self.begin = event.pos() 
     self.end = event.pos() 
     QGraphicsPixmapItem.mousePressEvent(self, event) 
     self.update() 

    def mouseMoveEvent(self, event): 
     self.end = event.pos() 
     QGraphicsPixmapItem.mouseMoveEvent(self, event) 
     self.update() 

    def mouseReleaseEvent(self, event): 
     self.begin = event.pos() 
     self.end = event.pos() 
     QGraphicsPixmapItem.mouseReleaseEvent(self, event) 
     self.update() 

class LoadPicture(QWidget, Ui_GraphicsArea): 
    def __init__(self, pixmap, parent=None): 
     QWidget.__init__(self, parent) 
     self.setupUi(self) 
     self.log = LogObject(self) 
     self.PictureArea.setScene(QGraphicsScene()) 
     self.item = PictureItem(self.log, pixmap) 
     self.PictureArea.scene().addItem(self.item) 
     self.resize(pixmap.size()) 
+0

QRuberband를 참조하십시오. – eyllanesc

+0

나는 오늘 오후에 실제로 그것을 발견했다. 그러나 웬일인지 그것을 통합하는 방법을 클릭하지 않고있다. 계속 'TypeErrors'가 발생합니다. – laxer

+0

'TypeError : QRubberBand (QRubberBand.Shape, parent : QWidget = None) : 인수 2에 예기치 않은 유형'PictureItem''이 (가) 정확히 – laxer

답변

1

우리는 다음과 같은 파일 작성 :

QGraphicsView.py

class GraphicsView(QGraphicsView): 
    rectChanged = pyqtSignal(QRect) 

    def __init__(self, *args, **kwargs): 
     QGraphicsView.__init__(self, *args, **kwargs) 
     self.rubberBand = QRubberBand(QRubberBand.Rectangle, self) 
     self.setMouseTracking(True) 
     self.origin = QPoint() 
     self.changeRubberBand = False 

    def mousePressEvent(self, event): 
     self.origin = event.pos() 
     self.rubberBand.setGeometry(QRect(self.origin, QSize())) 
     self.rectChanged.emit(self.rubberBand.geometry()) 
     self.rubberBand.show() 
     self.changeRubberBand = True 
     QGraphicsView.mousePressEvent(self, 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) 

    def mouseReleaseEvent(self, event): 
     self.changeRubberBand = False 
     QGraphicsView.mouseReleaseEvent(self, event) 

이를 GraphicsArea_GUI.py 클래스에서 다음을 변경해야합니다.

,210

에 :

from GraphicsView import GraphicsView 
[...] 
self.PictureArea = GraphicsView(self.scrollAreaWidgetContents) 

초기 클래스는이 연결되어, 당신은 왼쪽 상단 위치와 우리가 관련 QRect가 보낸 신호를 방출 오른쪽 아래를 원하는대로 우리가 그 형상을 업데이트하려면 QRubberBand를 사용 슬롯.

[...] 
    loadPicture.log.MousePixmapSignal.connect(self.updatePixel) 
    loadPicture.PictureArea.rectChanged.connect(self.onRectChanged) 

def onRectChanged(self, r): 
    topLeft = r.topLeft() 
    bottomRight = r.bottomRight() 
    print(topLeft.x(), topLeft.y(), bottomRight.x(), bottomRight.y()) 
+0

있습니다. 답변 해 주셔서 감사합니다. 나는 너의 모든 도움으로 이걸 배웠다. – laxer