2016-06-15 2 views
1

부모에 대한 resizer 역할을하는 최소한의 QGraphicsItem을 만들려고합니다. 나는 내가 거의 다 왔다고 생각하지만 공백을 그리며 이동 될 때 부모 항목으로 그 위치를 전달하는 방법. 내가 무엇을 갈거야 것은 (텍스트가없는)이 같은 같습니다하위 'resizer'항목의 위치를 ​​기반으로 QGraphicsItem 크기 조정

enter image description here

을 그리고 여기에 자기가 지금까지 무엇을 예를 들어 다음과 같습니다

import sys 
from PyQt4.QtGui import * 
from PyQt4.QtCore import * 


class Resizer(QGraphicsEllipseItem): 

    def __init__(self, rect=QRectF(0, 0, 10, 10), parent=None, scene=None): 
     super().__init__(rect, parent, scene) 

     self.setFlag(QGraphicsItem.ItemIsMovable, True) 

    def mousePressEvent(self, mouseEvent): 
     self.resize = True 
     self.initialPos = self.scenePos() 
     self.setSelected(True) 

    def mouseMoveEvent(self, mouseEvent): 
     if self.resize: 
      self.currentPos = self.scenePos() 
      self.change = self.initialPos - self.currentPos 
     super().mouseMoveEvent(mouseEvent) 

    def mouseReleaseEvent(self, mouseEvent): 
     self.resize = False 
     self.setSelected(False) 


if __name__ == "__main__": 

    app = QApplication(sys.argv) 

    view = QGraphicsView() 
    scene = QGraphicsScene() 
    scene.setSceneRect(0, 0, 500, 500) 
    view.setScene(scene) 

    rect = QRectF(100, 100, 150, 50) 
    box = QGraphicsRectItem(rect) 

    scene.addItem(box) 

    resizer = Resizer(parent=box) 
    resizerWidth = resizer.rect().width()/2 
    resizerOffset = QPointF(resizerWidth, resizerWidth) 
    resizer.setPos(box.rect().bottomRight() - resizerOffset) 

    view.show() 

    sys.exit(app.exec_()) 

그래서 어떻게 전달할 수를 self.changemouseMoveEvent 부모가 Resizer이 이동 될 때 부모의 크기가 조정되는 방식으로 부모에게 이동 하시겠습니까? 다른 제안 사항은 환영합니다.

나는 그래서 mouseMoveEvent에 신호를 방출 할 수 있음을 QGraphicsObject의 서브 클래스에 Resizer하지만 QGraphicsObject이 페인트 방법이없는 내가 현장에 Resizer를 표시 할 수 있겠군요 오전 변환 시도했습니다.

이에 대한 조언을 환영합니다.

+0

@DanielePantaleone 다소 동의합니다. 내가 그것을 해결하는 방법은 약간 다르지만. 유용 할 수 있기 때문에 내 대답을 올리고 있습니다. – pbreach

+0

정확합니다. 속임수에 좋은 해결책을 게시하는 것은 자신 만의 특혜입니다. 그러나 원래의 질문에 게시하면 (새로운 유능한 답변이라고 확신하는 경우) 더 많은 의견을 얻을 수 있습니다 (Google 검색에서 더 많은 조회수 색인을 가진 오래된 질문). 다음 번에 메모 해 두십시오. –

+0

@BhargavRao 위대한! 조언 주셔서 감사합니다 - 원본에 게시됩니다. – pbreach

답변

1

Resizer 클래스를 QGraphicsObject의 하위 클래스로 변환하는 작업이 끝났습니다. 페인트 메소드를 다시 구현하는 것이 가능하다는 것이 판명되었습니다 (자동 완성으로 이전에 찾지 못했음).

Resizer.itemChangeBox 상위 클래스의 resize 메서드에 할당 된 신호를 내 보냅니다.이 신호는 리사이 저의 위치 변경 정보를 사용하여 상자의 사각형을 조정합니다.

이 방법을 사용하면 here 답변과 같이 마우스 누르기/이동/놓기 이벤트를 다시 구현하지 않고도 다른 항목에 대해서도 다시 사용할 수 있습니다.

import sys 
from PyQt4.QtGui import * 
from PyQt4.QtCore import * 

class Box(QGraphicsRectItem): 

    def __init__(self, position, rect=QRectF(0, 0, 100, 50), parent=None, scene=None): 
     super().__init__(rect, parent, scene) 

     self.setFlag(QGraphicsItem.ItemIsSelectable, True) 
     self.setFlag(QGraphicsItem.ItemIsMovable, True) 
     self.setFlag(QGraphicsItem.ItemIsFocusable, True) 
     self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) 

     self.setPos(position) 

     self.resizer = Resizer(parent=self) 
     resizerWidth = self.resizer.rect.width()/2 
     resizerOffset = QPointF(resizerWidth, resizerWidth) 
     self.resizer.setPos(self.rect().bottomRight() - resizerOffset) 
     self.resizer.resizeSignal.connect(self.resize) 

    def paint(self, painter, option, widget=None): 
     pen = QPen() 
     pen.setColor(Qt.black) 
     painter.setPen(pen) 
     painter.setBrush(Qt.transparent) 
     painter.drawRect(self.rect()) 

    @pyqtSlot() 
    def resize(self, change): 
     self.setRect(self.rect().adjusted(0, 0, change.x(), change.y())) 
     self.prepareGeometryChange() 
     self.update() 


class Resizer(QGraphicsObject): 

    resizeSignal = pyqtSignal(QPointF) 

    def __init__(self, rect=QRectF(0, 0, 10, 10), parent=None): 
     super().__init__(parent) 

     self.setFlag(QGraphicsItem.ItemIsMovable, True) 
     self.setFlag(QGraphicsItem.ItemIsSelectable, True) 
     self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) 
     self.rect = rect 

    def boundingRect(self): 
     return self.rect 

    def paint(self, painter, option, widget=None): 
     if self.isSelected(): 
      pen = QPen() 
      pen.setStyle(Qt.DotLine) 
      painter.setPen(pen) 
     painter.drawEllipse(self.rect) 

    def itemChange(self, change, value): 
     if change == QGraphicsItem.ItemPositionChange: 
      if self.isSelected(): 
       self.resizeSignal.emit(value - self.pos()) 
     return value 


if __name__ == "__main__": 

    app = QApplication(sys.argv) 

    view = QGraphicsView() 
    scene = QGraphicsScene() 
    scene.setSceneRect(0, 0, 500, 1000) 
    view.setScene(scene) 

    box = Box(QPointF(50, 50), scene=scene) 

    view.show() 

    sys.exit(app.exec_()) 
관련 문제