2016-06-15 12 views
1

親に対してリサイザとして機能する最小のQGraphicsItemを作成しようとしています。私はほとんどそこにいると思うが、空白を描いて、動いているときにその親アイテムにその位置を伝える方法。私は(テキストなし)次のようになりますためつもりだ:QGraphicsItemを子の「resizer」アイテムの位置に基づいてサイズ変更する

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_()) 

それでは、どのように私は伝えることができます。

enter image description here

そして、ここでは、私がこれまで持っているものの自己完結型の一例ですResizerが移動されているときに親のサイズが変更されるように、がmouseMoveEventにありますか?他の提案は歓迎されます。

私はそれがmouseMoveEvent上の信号を発することができるようにQGraphicsObjectのサブクラスにResizerを変換しようとしましたが、QGraphicsObject paintメソッドを持っていると私は現場にResizerを表示する方法についてはわからないよされません。

これに関するアドバイスは大歓迎です。

+0

@ダニエルパントリアルン私は多少なりとも同意します。私がそれを解決する方法は少し異なっています。私はそれが役に立つかもしれないために私の答えを掲示しています。 – pbreach

+0

正確に。詐欺師に良い解決策を投稿することは、それ自体の特権です。しかし、それを元の質問に投稿した場合(新しいメリットがあると確信できる場合)、より多くの意見を得ることができます(Google検索でより多くの意見を表示する古い質問)。次回は注意してください。 –

+0

@BhargavRao素晴らしい!アドバイスをいただきありがとうございます。 – pbreach

答えて

1

ResizerクラスをサブクラスQGraphicsObjectに変換し終えました。ペイントメソッドを再実装することは可能でした(私の自動補完ではそれが以前に見つからなかったとしても)。

Resizer.itemChangeは、親のBoxクラスの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_()) 
関連する問題