PyQt5 鼠标跟踪 QLabel 对象
PyQt5 Mouse Tracking Over QLabel Object
我正在使用 PyQt5 创建一个应用程序。该应用程序有一个带有多个小部件的主窗口。其中一个小部件是显示视频的 QLabel 对象。当我选中单选按钮时,我想在鼠标悬停在视频上时跟踪光标并显示光标坐标。
我创建了一个 MouseTracking class,我将 QLabel 对象作为 window
传递给它。我已经通过打印它的几何形状验证了传递给 class 的。但不知何故,我没有将鼠标跟踪与 window
联系起来。这是 MouseTracking class 的代码。我做错了什么?
class MouseTracker(QLabel):
def __init__(self, window):
super().__init__(window)
self.window = window
self.window.setMouseTracking(True)
self.initUI()
def initUI(self):
self.label = QLabel(self)
self.label.setAlignment(Qt.AlignCenter)
self.label.setStyleSheet('background-color: white; border: 1px solid black')
self.show()
def mouseMoveEvent(self, event):
x = event.x()
y = event.y()
print("X, Y = ", x, y)
self.label.setGeometry(x+30, y-15, 90, 40)
self.label.setText('(%d, %d)' % (x, y))
在您的代码中,您启用了 "window" 的 mouseTracking 属性,但您正在监视 MouseTracker 的 mouseMoveEvent 方法,这是不正确的。如果您想在不覆盖任何方法的情况下跟踪小部件的事件,那么您必须使用事件过滤器。
在下面的示例中,我尝试根据您的描述来实现您的应用程序,例如绿色的QLabel 代表视频显示的QLabel。综合以上,解决方案如下:
from PyQt5 import QtCore, QtGui, QtWidgets
class MouseTracker(QtCore.QObject):
positionChanged = QtCore.pyqtSignal(QtCore.QPoint)
def __init__(self, widget):
super().__init__(widget)
self._widget = widget
self.widget.setMouseTracking(True)
self.widget.installEventFilter(self)
@property
def widget(self):
return self._widget
def eventFilter(self, o, e):
if o is self.widget and e.type() == QtCore.QEvent.MouseMove:
self.positionChanged.emit(e.pos())
return super().eventFilter(o, e)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
self.video_label = QtWidgets.QLabel()
self.video_label.setStyleSheet("background-color: green; border: 1px solid black")
tracker = MouseTracker(self.video_label)
tracker.positionChanged.connect(self.on_positionChanged)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(self.video_label)
lay.addWidget(QtWidgets.QLabel())
self.resize(640, 480)
self.label_position = QtWidgets.QLabel(
self.video_label, alignment=QtCore.Qt.AlignCenter
)
self.label_position.setStyleSheet('background-color: white; border: 1px solid black')
@QtCore.pyqtSlot(QtCore.QPoint)
def on_positionChanged(self, pos):
delta = QtCore.QPoint(30, -15)
self.label_position.show()
self.label_position.move(pos + delta)
self.label_position.setText("(%d, %d)" % (pos.x(), pos.y()))
self.label_position.adjustSize()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
我正在使用 PyQt5 创建一个应用程序。该应用程序有一个带有多个小部件的主窗口。其中一个小部件是显示视频的 QLabel 对象。当我选中单选按钮时,我想在鼠标悬停在视频上时跟踪光标并显示光标坐标。
我创建了一个 MouseTracking class,我将 QLabel 对象作为 window
传递给它。我已经通过打印它的几何形状验证了传递给 class 的。但不知何故,我没有将鼠标跟踪与 window
联系起来。这是 MouseTracking class 的代码。我做错了什么?
class MouseTracker(QLabel):
def __init__(self, window):
super().__init__(window)
self.window = window
self.window.setMouseTracking(True)
self.initUI()
def initUI(self):
self.label = QLabel(self)
self.label.setAlignment(Qt.AlignCenter)
self.label.setStyleSheet('background-color: white; border: 1px solid black')
self.show()
def mouseMoveEvent(self, event):
x = event.x()
y = event.y()
print("X, Y = ", x, y)
self.label.setGeometry(x+30, y-15, 90, 40)
self.label.setText('(%d, %d)' % (x, y))
在您的代码中,您启用了 "window" 的 mouseTracking 属性,但您正在监视 MouseTracker 的 mouseMoveEvent 方法,这是不正确的。如果您想在不覆盖任何方法的情况下跟踪小部件的事件,那么您必须使用事件过滤器。
在下面的示例中,我尝试根据您的描述来实现您的应用程序,例如绿色的QLabel 代表视频显示的QLabel。综合以上,解决方案如下:
from PyQt5 import QtCore, QtGui, QtWidgets
class MouseTracker(QtCore.QObject):
positionChanged = QtCore.pyqtSignal(QtCore.QPoint)
def __init__(self, widget):
super().__init__(widget)
self._widget = widget
self.widget.setMouseTracking(True)
self.widget.installEventFilter(self)
@property
def widget(self):
return self._widget
def eventFilter(self, o, e):
if o is self.widget and e.type() == QtCore.QEvent.MouseMove:
self.positionChanged.emit(e.pos())
return super().eventFilter(o, e)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
self.video_label = QtWidgets.QLabel()
self.video_label.setStyleSheet("background-color: green; border: 1px solid black")
tracker = MouseTracker(self.video_label)
tracker.positionChanged.connect(self.on_positionChanged)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(self.video_label)
lay.addWidget(QtWidgets.QLabel())
self.resize(640, 480)
self.label_position = QtWidgets.QLabel(
self.video_label, alignment=QtCore.Qt.AlignCenter
)
self.label_position.setStyleSheet('background-color: white; border: 1px solid black')
@QtCore.pyqtSlot(QtCore.QPoint)
def on_positionChanged(self, pos):
delta = QtCore.QPoint(30, -15)
self.label_position.show()
self.label_position.move(pos + delta)
self.label_position.setText("(%d, %d)" % (pos.x(), pos.y()))
self.label_position.adjustSize()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())