在 PyQt 中 window 调整大小后,如何继续在图像上绘图?
How do I keep drawing on image after window resize in PyQt?
我写了一段代码在 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_())
您有以下错误:
场景坐标与视图坐标不同,所以要建立矩形的正确位置必须使用mapToScene()
方法
为什么要添加和删除项目?最好的是重复使用
您希望矩形的位置相对于 QGraphicsPixmapItem
,因此矩形必须是 QGraphicsPixmapItem
.
[ 的子元素=29=]
使用上面我们得到以下内容:
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)
我写了一段代码在 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_())
您有以下错误:
场景坐标与视图坐标不同,所以要建立矩形的正确位置必须使用
mapToScene()
方法为什么要添加和删除项目?最好的是重复使用
您希望矩形的位置相对于
[ 的子元素=29=]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)