簡體   English   中英

PyQt猴子修補QLineEdit.paste嗎?

[英]PyQt monkey patching QLineEdit.paste?

我試圖攔截特定編輯框的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_()

您不能“ monkey-patch” QLineEdit.paste()的原因是因為它不是函數。 關於虛函數的重要一點是,當它們被重寫時,重新實現的函數將由Qt在內部調用; 而非虛擬替代只會被Python代碼調用。 因此,由於QLinedit.paste()不是虛擬的,因此您必須攔截所有通常導致Qt在內部調用它的事件

這將意味着重新實現QLineEdit.keyPressEvent ,以便您可以捕獲默認鍵綁定的快捷方式; 以及QLineEdit.contextMenuEvent ,以便您可以修改默認的上下文菜單。 而且,根據您要執行的操作,您可能還需要覆蓋默認的拖放處理。 (如果不想使用子類,則可以使用事件過濾器監視所有相關事件)。

QClipboard類提供對系統剪貼板的訪問,這使您可以在粘貼文本之前對其進行攔截。 每個應用程序都有一個剪貼板對象,可以通過QApplication.clipboard()qApp.clipboard()對其進行訪問。

為了做您想做的事情,您可以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_()

這里的事件過濾器僅負責鍵盤快捷鍵的粘貼。 正如我所說,您還需要考慮粘貼操作的其他來源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM