【问题标题】:Resizing QGraphicsItem based on position of child 'resizer' item [duplicate]根据子“调整大小”项目的位置调整 QGraphicsItem 的大小 [重复]
【发布时间】:2016-10-17 04:53:22
【问题描述】:

我正在尝试创建一个最小的 QGraphicsItem 作为其父级的调整大小。我想我快到了,但正在画一个空白,以及如何在移动父项时将其位置传达给父项。我要找的东西看起来像这样(没有文字):

这是我迄今为止所拥有的一个自包含的示例:

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

那么我如何将mouseMoveEvent 中的self.change 传达给父级,以便在移动Resizer 时调整父级的大小?欢迎任何其他建议。

我尝试将Resizer 转换为QGraphicsObject 的子类,以便它可以在mouseMoveEvent 上发出信号,但QGraphicsObject 没有绘制方法,我不确定如何显示Resizer现场。

欢迎对此提出任何建议。

【问题讨论】:

  • @DanielePantaleone 我有点同意。我解决它的方式有点不同。我将发布我的答案以防万一。
  • 没错。向受骗者发布一个好的解决方案有其自身的好处。但是,如果您将其发布到原始问题(如果您确定它是一个新的有价值的答案),那么您可能会获得更多的观点(在谷歌搜索上具有更多观点的旧问题索引更多)。下次注意。
  • @BhargavRao 太棒了!感谢您的建议 - 将在原版中发布。
  • 现在不要这样做。下次记住这一点。

标签: python c++ qt pyqt qgraphicsitem


【解决方案1】:

我结束了将Resizer 类转换为QGraphicsObject 的子类。事实证明可以重新实现paint方法(即使我的自动完成之前没有找到它)。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    相关资源
    最近更新 更多