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

问题描述 投票:0回答:1

我正在使用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)   
python pyqt pyqt5 python-3.6
1个回答
0
投票

QCursor不是“静态图像”,而是与鼠标光标相关的“抽象”对象,因此没有出于您的目的使用它。

您正在寻找的是在现有图像或显示该图像的小部件上绘图。由于您可能想保持图像不变,因此第二个选择就是您要寻找的内容。

想法是,您调用paintEvent方法的基类实现,然后绘制over。使用简单的线条手工绘制十字准线并不难,但是您需要使用不同的颜色在十字周围画一个额外的边框,以确保即使在较亮或较暗的背景下,它的可见性也是如此。在此示例中,我使用的是Qt在CursorShape enum文档中使用的光标图像,但是只要其中心正好位于其[[the中心,您就可以使用所需的任何图像(提示:使用正方形图片的宽度/高度为奇数)。

from PyQt5 import QtCore, QtGui, QtWidgets class Window(QtWidgets.QWidget): def __init__(self): super().__init__() layout = QtWidgets.QGridLayout(self) self.label = QtWidgets.QLabel() layout.addWidget(self.label) self.label.setPixmap(QtGui.QPixmap('myimage.png')) self.label.installEventFilter(self) self.cursorPos = None # I'm using the crosshair cursor as shown at # https://doc.qt.io/qt-5/qt.html#CursorShape-enum self.cursorPixmap = QtGui.QPixmap('cursor-cross.png') def eventFilter(self, source, event): if event.type() == QtCore.QEvent.MouseButtonPress: # set the current position and schedule a repaint of the label self.cursorPos = event.pos() self.label.update() elif event.type() == QtCore.QEvent.Paint: # intercept the paintEvent of the label and call the base # implementation to actually draw its contents self.label.paintEvent(event) if self.cursorPos is not None: # if the cursor position has been set, draw it qp = QtGui.QPainter(self.label) # translate the painter at the cursor position qp.translate(self.cursorPos) # paint the pixmap at an offset based on its center qp.drawPixmap(-self.cursorPixmap.rect().center(), self.cursorPixmap) return True return super().eventFilter(source, event) if __name__ == '__main__': import sys app = QtWidgets.QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())
[除此之外,另一种方法是使用Graphics View Framework,将像素图添加到场景中,并在用户单击图像时为光标添加/移动另一个像素图。处理QGraphicsViews,QGraphicsScenes及其项目要复杂一些,但是如果您需要与图像进行更高级的交互,通常是更好的选择。

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_())

这两种方法对用户的行为都相同,并且您可以看到它们看上去完全相同。

image comparison of the two methods

© www.soinside.com 2019 - 2024. All rights reserved.