在这些情况下,QRubberBand最好是QLabel的儿子,因此不需要进行很多转换。
另一方面,事件的坐标与窗口相关,因此我们必须将其转换为QLabel的坐标。为此,一种简单的方法是将相对于窗口的局部坐标转换为全局坐标,然后将相对于QLabel的全局坐标转换为局部坐标。
最后,在缩放图像时,由于currentQRect相对于缩放后的QLabel相对,但内部QPixmap尚未缩放,因此会影响坐标。
def mousePressEvent (self, event): self.originQPoint = self.imageLabel.mapFromGlobal(self.mapToGlobal(event.pos())) self.currentQRubberBand = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self.imageLabel) self.currentQRubberBand.setGeometry(QtCore.QRect(self.originQPoint, QtCore.QSize())) self.currentQRubberBand.show()def mouseMoveEvent (self, event): p = self.imageLabel.mapFromGlobal(self.mapToGlobal(event.pos())) QtWidgets.QToolTip.showText(event.pos() , "X: {} Y: {}".format(p.x(), p.y()), self) if self.currentQRubberBand.isVisible() and self.imageLabel.pixmap() is not None: self.currentQRubberBand.setGeometry(QtCore.QRect(self.originQPoint, p).normalized() & self.imageLabel.rect())def mouseReleaseEvent (self, event): self.currentQRubberBand.hide() currentQRect = self.currentQRubberBand.geometry() self.currentQRubberBand.deleteLater() if self.imageLabel.pixmap() is not None: tr = QtGui.QTransform() if self.fitToWindowAct.isChecked(): tr.scale(self.imageLabel.pixmap().width()/self.scrollArea.width(), self.imageLabel.pixmap().height()/self.scrollArea.height()) else: tr.scale(1/self.scaleFactor, 1/self.scaleFactor) r = tr.mapRect(currentQRect) cropQPixmap = self.imageLabel.pixmap().copy(r) cropQPixmap.save('output.png')


