我正在尝试拦截特定编辑框的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_()
答案 0 :(得分:4)
你不能“猴子补丁”QLineEdit.paste
的原因是因为它不是虚拟功能。只能重新实现QLinedit.sizeHint之类的虚函数,这通常可以通过创建带有重叠方法的子类来完成:
class LineEdit(QtGui.QLineEdit):
def sizeHint(self):
if some_condition:
# do something funky
return QtCore.QSize(42, 42)
# otherwise default to the base-class method
return QtGui.QLineEdit.sizeHint(self)
关于虚函数的重要一点是,当它们被重写时,重新实现的函数将由Qt在内部调用;而非虚拟覆盖只能由Python代码调用。
因此,由于QLinedit.paste()
不是虚拟的,因此您必须拦截通常会导致Qt内部调用的所有事件。
这意味着重新实现QLineEdit.keyPressEvent,以便您可以捕获default key bindings的快捷方式;还有QLineEdit.contextMenuEvent,以便您可以修改默认上下文菜单。 (并且,根据您要执行的操作,您可能还需要覆盖默认的拖放操作)。
答案 1 :(得分:2)
为了做你想做的事,你可以继承QLineEdit
并创建一个方法来提供你想要的自定义粘贴功能(paste
方法不是虚拟的,所以如果它被覆盖它就赢了'从Qt代码调用)。此外,您还需要一个事件过滤器来拦截CTRL + V的快捷方式。可能你也必须过滤鼠标中键,它也用于粘贴剪贴板内容。在事件过滤器中,您可以调用替换paste
方法。
您可以使用以下代码作为起点:
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class myEditor(QLineEdit):
def __init__(self, parent=None):
super(myEditor, self).__init__(parent)
def myPaste(self):
self.insert("custom text pasted! ")
class myWindow(QMainWindow):
def __init__(self, parent=None):
super(myWindow, self).__init__(parent)
self.customEditor = myEditor(self)
self.setCentralWidget(self.customEditor)
self.customEditor.installEventFilter(self)
def eventFilter(self, obj, e):
if (obj == self.customEditor):
if (e.type() == QEvent.KeyPress):
if (e.matches(QKeySequence.Paste)):
self.customEditor.myPaste()
return True
return False
else:
return QMainWindow.eventFilter(obj, e)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = myWindow()
window.show()
app.exec_()
此处的事件过滤器仅用于粘贴键盘快捷键。正如我所说,你还需要考虑粘贴操作的其他来源。