【问题标题】:How do I keep drawing on image after window resize in PyQt?在 PyQt 中调整窗口大小后如何继续在图像上绘图?
【发布时间】:2019-01-16 18:09:55
【问题描述】:

我已经编写了一个代码来在 QGraphicsView 中的图像上绘制一个矩形,但是如果我调整图像的大小,例如全屏,矩形的位置就会错位。有没有什么办法解决这一问题? 我认为一种可能的解决方案是每次在左上角对齐图像,但我不能在 setAlignment() 中给出 2 个参数。

代码如下:(按钮仅用于显示atm)

class MyWidget(QWidget):
def __init__(self):
    super().__init__()

    self.b1 = QPushButton('Next Image')
    self.b2 = QPushButton('Crop')
    self.b3 = QPushButton('Clear')

    self.view = GraphicsView()
    h_box = QHBoxLayout()
    v_box = QVBoxLayout()
    v_box.addWidget(self.b1)
    v_box.addWidget(self.b2)
    v_box.addWidget(self.b3)
    h_box.addWidget(self.view)
    h_box.addLayout(v_box)
    self.setLayout(h_box)
    #self.resize(800, 800)
    self.setWindowTitle("Super Duper Cropper")

    self.show()



class GraphicsView(QGraphicsView):

def __init__(self):
    super().__init__()
    self.setScene(QGraphicsScene())

    self.item = QGraphicsPixmapItem(QPixmap('test.jpg'))
    self.scene().addItem(self.item)



def mousePressEvent(self, event):
    self.xi = event.x()
    self.yi = event.y()

def mouseMoveEvent(self, event):
    self.xf = event.x()
    self.yf = event.y()
    self.draw_rect()


def mouseReleaseEvent(self, event):
    self.xf = event.x()
    self.yf = event.y()
    self.draw_rect()

def draw_rect(self):
    self.scene().removeItem(self.item)
    self.scene().addItem(self.item)

    self.scene().addRect(self.xi, self.yi, self.xf-self.xi, self.yf-self.yi, pen=QPen(QColor(51, 153, 255), 2,
                        Qt.SolidLine), brush=QBrush(QColor(0, 255, 0, 40)))



if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyWidget()
    window.show()
    app.aboutToQuit.connect(app.deleteLater)
    sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt pyqt5 qgraphicsview qgraphicsscene


    【解决方案1】:

    您有以下错误:

    • 场景坐标与视图坐标不同,所以要建立矩形的正确位置,必须使用mapToScene()方法。

    • 为什么要添加和删除项目?最好的办法是重复使用

    • 您希望矩形的位置相对于QGraphicsPixmapItem,因此矩形必须是QGraphicsPixmapItem 的子级。

    使用上面我们得到以下内容:

    class GraphicsView(QGraphicsView):
        def __init__(self):
            super().__init__()
            self.setScene(QGraphicsScene())
            self.item = QGraphicsPixmapItem(QPixmap('test.jpg'))
            self.scene().addItem(self.item)
            self.rect_item = QGraphicsRectItem(QRectF(), self.item)
            self.rect_item.setPen(QPen(QColor(51, 153, 255), 2, Qt.SolidLine))
            self.rect_item.setBrush(QBrush(QColor(0, 255, 0, 40)))
    
        def mousePressEvent(self, event):
            self.pi = self.mapToScene(event.pos())
            super().mousePressEvent(event)
    
        def mouseMoveEvent(self, event):
            pf = self.mapToScene(event.pos())
            if (self.pi - pf).manhattanLength() > QApplication.startDragDistance():
                self.pf = pf
                self.draw_rect()
            super().mouseMoveEvent(event)
    
        def mouseReleaseEvent(self, event):
            pf = self.mapToScene(event.pos())
            if (self.pi - pf).manhattanLength() > QApplication.startDragDistance():
                self.pf = pf
                self.draw_rect()
            super().mouseReleaseEvent(event)
    
        def draw_rect(self):
            r = QRectF(self.pi, self.pf).normalized()
            r = self.rect_item.mapFromScene(r).boundingRect()
            self.rect_item.setRect(r)
    

    【讨论】:

    • 我正在删除和添加,因为图片没有更新我写它的方式。我仍然是这方面的初学者。非常感谢!现在可以使用了
    • @DanielT。如果我的回答对您有帮助,别忘了标记为正确,如果您不知道怎么做,请查看tour,这是最好的感谢方式。
    猜你喜欢
    • 2017-11-04
    • 2010-12-21
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多