Skip to main content
 首页 » 编程设计

python之PyQt 猴子修补 QLineEdit.paste

2025年05月04日18zengkefu

我正在尝试拦截特定编辑框的 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_() 

根据反馈...我能够使用事件过滤器建议来解决我的问题。更新后的示例代码如下...

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

请您参考如下方法:

您不能“猴子修补”QLineEdit.paste() 的原因是因为它不是虚拟 函数。虚函数的重要之处在于,当它们被覆盖时,重新实现的函数将被 Qt 内部调用;而非虚拟覆盖只会被 Python 代码调用。因此,由于 QLineedit.paste() 不是虚拟的,因此您必须拦截所有通常会导致它被 Qt 内部调用的事件。

这将意味着重新实现 QLineEdit.keyPressEvent , 这样你就可以捕获 default key bindings 的快捷方式;还有QLineEdit.contextMenuEvent , 以便您可以修改默认上下文菜单。而且,根据您尝试执行的操作,您可能还需要覆盖默认的拖放处理。 (如果您不想使用子类,可以使用 event-filter 来监视所有相关事件)。

QClipboard类提供对系统剪贴板的访问,这将允许您在粘贴文本之前截取文本。每个应用程序都有一个剪贴板对象,可以通过 QApplication.clipboard() 或 qApp.clipboard() 访问。