PyQt monkey patching QLineEdit.paste?

前端 未结 2 1311
北海茫月
北海茫月 2021-01-16 07:07

I am trying to intercept paste() for a specific edit box. After much reading and head scratching I decided to try the big hammer and monkey patch. This didn\'t work for me

相关标签:
2条回答
  • 2021-01-16 07:27

    In order to do what you want you can subclass QLineEdit and create a method that provides the custom paste functionality that you want (paste method isn't virtual so if it is overriden it won't be called from Qt code). In addition you will need an event filter to intercept the shortcut for CTRL+V. Probably you will have to filter the middle mouse button too which is also used to paste the clipboard content. From the event filter you can call your replacement of paste method.

    You can use the following code as starting point:

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

    The event filter here only takes care of the keyboard shortcut for pasting. As I said you need to consider also other sources of the paste operation.

    0 讨论(0)
  • 2021-01-16 07:35

    The reason you can't "monkey-patch" QLineEdit.paste() is because it's not a virtual function. The important thing about virtual functions is that when they are overridden, the reimplemented function will get called internally by Qt; whereas non-virtual overrides will only get called by Python code. So, since QLinedit.paste() isn't virtual, you will instead have to intercept all the events that would normally result in it being called internally by Qt.

    That will mean reimplementing QLineEdit.keyPressEvent, so that you can trap the shortcuts for the default key bindings; and also QLineEdit.contextMenuEvent, so that you can modify the default context menu. And, depending on what you're trying to do, you might also need to override the default drag-and-drop handling. (If you prefer not to use a subclass, an event-filter can be used to monitor all the relevant events).

    The QClipboard class provides access to the system clipboard, which will allow you to intercept the text before it is pasted. Every application has a single clipboard object, which can be accessed via QApplication.clipboard() or qApp.clipboard().

    0 讨论(0)
提交回复
热议问题