Python 在PyQt5标签小部件中设置光标

Python 在PyQt5标签小部件中设置光标,python,pyqt,pyqt5,python-3.6,Python,Pyqt,Pyqt5,Python 3.6,我正在用PyQt中的网络摄像头制作一个图像采集程序。每当我点击标签小部件中的图像时,我都需要在该位置放置一个额外的固定光标(例如,要有一个参考点)。我创建了一个游标对象,设置了一个形状和位置(从单击的位置获得)。但是,我没有看到在单击的位置(即Qpoint)创建额外的光标 下面是代码片段: def eventFilter(self, source, event): if event.type()==QtCore.QEvent.MouseButtonPress: s

我正在用PyQt中的网络摄像头制作一个图像采集程序。每当我点击标签小部件中的图像时,我都需要在该位置放置一个额外的固定光标(例如,要有一个参考点)。我创建了一个游标对象,设置了一个形状和位置(从单击的位置获得)。但是,我没有看到在单击的位置(即Qpoint)创建额外的光标

下面是代码片段:

 def eventFilter(self, source, event):
     if  event.type()==QtCore.QEvent.MouseButtonPress:
         self.new_cursor=QtGui.QCursor()               # the additional cursori want to place
         self.new_cursor.setShape(self,Qt.PointingHandCursor) # setting shape

         self.cursor_clicked=event.pos()           # getting position from the click

         self.cursor_clicked=self.label.mapFromParent(event.pos()) #mapping to widget coords.

         self.cursor_x=self.cursor_clicked.x()
         self.cursor_y=self.cursor_clicked.y()
         self.new_cursor.setPos(self.cursor_x,self.cursor_y)
         self.setCursor(self.new_cursor)


     return QtWidgets.QWidget.eventFilter(self,source,event)   
QCursor不是一个“静态图像”,而是一个与鼠标光标相关的“抽象”对象,因此它没有任何用途

您要查找的是在现有图像或显示该图像的小部件上绘图。
因为您可能希望图像保持不变,所以第二个选项是您要查找的内容

其思想是调用
paintEvent
方法的基类实现,然后在其上绘制。
用简单的线条手工画十字线并不难,但你需要用不同的颜色在十字周围画一个额外的边框,以确保十字线即使在较亮或较暗的背景下也可见,这使得十字线没有必要过长;在本例中,我使用的是Qt在文档中使用的光标图像,但只要其中心正好位于其中心,您就可以使用所需的任何图像(提示:使用宽度/高度奇数的方形图像)

除此之外,另一种方法是使用,将pixmap添加到场景中,并在用户单击图像时为光标添加/移动另一个pixmap。处理QGraphicsView、QGraphicsCENES及其项稍微复杂一些,但如果您需要更高级的图像交互,通常这是更好的方法

from PyQt5 import QtCore, QtGui, QtWidgets

class Window(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        layout = QtWidgets.QGridLayout(self)

        self.view = QtWidgets.QGraphicsView()
        layout.addWidget(self.view)
        # remove any border around the view
        self.view.setFrameShape(0)
        self.scene = QtWidgets.QGraphicsScene()
        self.view.setScene(self.scene)

        pixmap = QtGui.QPixmap('myimage.png')
        # adapt the view's size to that of the pixmap
        self.view.setFixedSize(pixmap.size())

        # add a pixmap to a scene, which returns a QGraphicsPixmapItem
        self.pixmapItem = self.scene.addPixmap(pixmap)

        self.crossHairItem = None

        self.view.installEventFilter(self)

    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.MouseButtonPress:
            if not self.crossHairItem:
                # as above, get a QGraphicsPixmapItem for the crosshair cursor
                pixmap = QtGui.QPixmap('cursor-cross.png')
                self.crossHairItem = self.scene.addPixmap(pixmap)
                # set an offset of the item, so that its position is always
                # based on the center of the pixmap
                self.crossHairItem.setOffset(-pixmap.rect().center())
            self.crossHairItem.setPos(self.view.mapToScene(event.pos()))
        return super().eventFilter(source, event)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
这两种方法对用户的行为方式相同,正如您所看到的,它们看起来完全相同

from PyQt5 import QtCore, QtGui, QtWidgets

class Window(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        layout = QtWidgets.QGridLayout(self)

        self.view = QtWidgets.QGraphicsView()
        layout.addWidget(self.view)
        # remove any border around the view
        self.view.setFrameShape(0)
        self.scene = QtWidgets.QGraphicsScene()
        self.view.setScene(self.scene)

        pixmap = QtGui.QPixmap('myimage.png')
        # adapt the view's size to that of the pixmap
        self.view.setFixedSize(pixmap.size())

        # add a pixmap to a scene, which returns a QGraphicsPixmapItem
        self.pixmapItem = self.scene.addPixmap(pixmap)

        self.crossHairItem = None

        self.view.installEventFilter(self)

    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.MouseButtonPress:
            if not self.crossHairItem:
                # as above, get a QGraphicsPixmapItem for the crosshair cursor
                pixmap = QtGui.QPixmap('cursor-cross.png')
                self.crossHairItem = self.scene.addPixmap(pixmap)
                # set an offset of the item, so that its position is always
                # based on the center of the pixmap
                self.crossHairItem.setOffset(-pixmap.rect().center())
            self.crossHairItem.setPos(self.view.mapToScene(event.pos()))
        return super().eventFilter(source, event)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())