我正在尝试拦截特定编辑框的 paste()。经过大量阅读和挠头后,我决定尝试使用大锤子和猴子补丁。这对我也不起作用。有谁知道为什么?
import sys
from PyQt4 import QtGui
def myPaste():
print("paste") # Never gets here
if __name__ == "__main__":
# QtGui.QLineEdit.paste = myPaste # Try #1
app = QtGui.QApplication(sys.argv)
window = QtGui.QMainWindow()
window.setWindowTitle("monkey")
centralWidget = QtGui.QWidget(window)
edit = QtGui.QLineEdit(centralWidget)
# QtGui.QLineEdit.paste = myPaste # Try #2
edit.paste = myPaste # Try #3
window.setCentralWidget(centralWidget)
window.show()
app.exec_()
Run Code Online (Sandbox Code Playgroud)
根据反馈......我能够使用事件过滤器建议来解决我的问题。更新的示例代码如下...
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = QtGui.QMainWindow()
window.setWindowTitle("monkey")
centralWidget = QtGui.QWidget(window)
edit = QtGui.QLineEdit(centralWidget)
window.setCentralWidget(centralWidget)
def eventFilter(obj, e):
if isinstance(obj, QtGui.QLineEdit):
if (e.type() == QtCore.QEvent.KeyPress):
if (e.matches(QtGui.QKeySequence.Paste)):
obj.paste()
t=str(obj.text()).title() # Special handling here...uppercase each word for example
obj.setText(t)
return True
return False
else:
return QtGui.QMainWindow.eventFilter(obj, e)
window.eventFilter = eventFilter
edit.installEventFilter(window)
window.show()
app.exec_()
Run Code Online (Sandbox Code Playgroud)
你不能“猴子补丁”QLineEdit.paste()的原因是因为它不是一个虚函数。虚函数的重要之处在于,当它们被覆盖时,重新实现的函数将被 Qt 内部调用;而非虚拟覆盖只会被 Python 代码调用。因此,由于QLinedit.paste()不是虚拟的,您将不得不拦截通常会导致 Qt 在内部调用它的所有事件。
这将意味着重新实现QLineEdit.keyPressEvent,以便您可以捕获默认键绑定的快捷方式;以及QLineEdit.contextMenuEvent,以便您可以修改默认上下文菜单。而且,根据您尝试执行的操作,您可能还需要覆盖默认的拖放处理。(如果您不想使用子类,可以使用事件过滤器来监视所有相关事件)。
该QClipboard类,可以访问系统剪贴板,这将允许你把它粘贴之前截取的文字。每个应用程序都有一个剪贴板对象,可以通过QApplication.clipboard()或访问它qApp.clipboard()。