捕捉鼠标事件
Catch the mouse event
不知道QMouseEvent的参数到底怎么给class。我应该创建新的 class 来在我的 QTextEdit 中实现 QMouseEvent 吗?
class Test(QMainWindow):
def __init__(self):
super().__init__()
self.txt = QTextEdit(self)
self.txt.setMouseTracking(True)
self.txt.mouseReleaseEvent(QMouseEvent())
class Test2(QTextEdit):
def __init__(self):
super().__init__()
def mouseReleaseEvent(self, e):
print("text edit is clicked")
ui = Test()
ui.show()
因为很多次有人问如何检测影响小部件的事件,所以在这个答案中我将详细说明解决方案,它将用作未来问题的规范答案。
要检测来自小部件的事件,有几种解决方案:
- 覆盖一个方法
如果小部件具有处理该事件的方法,那么一个选项是覆盖该方法并将其与信号相关联,以便可以通知其他对象。
在鼠标释放事件的特定情况下,这是由 mouseReleaseEvent 方法处理的。
from PyQt5 import QtCore, QtWidgets
class TextEdit(QtWidgets.QTextEdit):
released = QtCore.pyqtSignal()
def mouseReleaseEvent(self, event):
super().mouseReleaseEvent(event)
self.released.emit()
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.textedit = TextEdit()
self.textedit.released.connect(self.handle_released)
self.setCentralWidget(self.textedit)
@QtCore.pyqtSlot()
def handle_released(self):
print("released")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
- 使用事件过滤器
Qt 允许您使用事件过滤器监视事件,因此您可以利用此功能以与先前解决方案类似的方式发出信号。
在继承自QAbstractScrollArea的类情况下,鼠标方法被传递到视口,因此必须监视该对象。
from PyQt5 import QtCore, QtWidgets
class ReleaseFilter(QtCore.QObject):
released = QtCore.pyqtSignal()
def __init__(self, widget):
super().__init__(widget)
self._widget = widget
self.widget.installEventFilter(self)
@property
def widget(self):
return self._widget
def eventFilter(self, obj, event):
if obj is self.widget and event.type() == QtCore.QEvent.MouseButtonRelease:
self.released.emit()
return super().eventFilter(obj, event)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.textedit = QtWidgets.QTextEdit()
rf = ReleaseFilter(self.textedit.viewport())
rf.released.connect(self.handle_released)
self.setCentralWidget(self.textedit)
@QtCore.pyqtSlot()
def handle_released(self):
print("released")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
不知道QMouseEvent的参数到底怎么给class。我应该创建新的 class 来在我的 QTextEdit 中实现 QMouseEvent 吗?
class Test(QMainWindow):
def __init__(self):
super().__init__()
self.txt = QTextEdit(self)
self.txt.setMouseTracking(True)
self.txt.mouseReleaseEvent(QMouseEvent())
class Test2(QTextEdit):
def __init__(self):
super().__init__()
def mouseReleaseEvent(self, e):
print("text edit is clicked")
ui = Test()
ui.show()
因为很多次有人问如何检测影响小部件的事件,所以在这个答案中我将详细说明解决方案,它将用作未来问题的规范答案。
要检测来自小部件的事件,有几种解决方案:
- 覆盖一个方法
如果小部件具有处理该事件的方法,那么一个选项是覆盖该方法并将其与信号相关联,以便可以通知其他对象。
在鼠标释放事件的特定情况下,这是由 mouseReleaseEvent 方法处理的。
from PyQt5 import QtCore, QtWidgets
class TextEdit(QtWidgets.QTextEdit):
released = QtCore.pyqtSignal()
def mouseReleaseEvent(self, event):
super().mouseReleaseEvent(event)
self.released.emit()
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.textedit = TextEdit()
self.textedit.released.connect(self.handle_released)
self.setCentralWidget(self.textedit)
@QtCore.pyqtSlot()
def handle_released(self):
print("released")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
- 使用事件过滤器
Qt 允许您使用事件过滤器监视事件,因此您可以利用此功能以与先前解决方案类似的方式发出信号。
在继承自QAbstractScrollArea的类情况下,鼠标方法被传递到视口,因此必须监视该对象。
from PyQt5 import QtCore, QtWidgets
class ReleaseFilter(QtCore.QObject):
released = QtCore.pyqtSignal()
def __init__(self, widget):
super().__init__(widget)
self._widget = widget
self.widget.installEventFilter(self)
@property
def widget(self):
return self._widget
def eventFilter(self, obj, event):
if obj is self.widget and event.type() == QtCore.QEvent.MouseButtonRelease:
self.released.emit()
return super().eventFilter(obj, event)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.textedit = QtWidgets.QTextEdit()
rf = ReleaseFilter(self.textedit.viewport())
rf.released.connect(self.handle_released)
self.setCentralWidget(self.textedit)
@QtCore.pyqtSlot()
def handle_released(self):
print("released")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())