Image Viewer GUI无法正确映射鼠标按下事件的坐标

时间:2018-12-08 09:49:13

标签: python pyqt pyqt5 qlabel qpixmap

我正在尝试将来自各种来源的基于PyQt5的图像查看器Python代码拼凑在一起,并将功能扩展到在加载的图像内裁剪感兴趣的区域(ROI)。问题在于,在确定像素位置时,映射的坐标和鼠标单击会考虑滚动条和菜单条。以下是加载图像并提供边框功能的代码,但是由于偏移,我似乎无法准确绘制/裁剪框。

Mono<Object>

1 个答案:

答案 0 :(得分:0)

在这些情况下,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')