2013-08-01 61 views
1

這個python pyqt代碼的工作原理如何。 但是,我不喜歡QLineEdit的子類,所以我可以檢測到文件放到我的QLineEdit字段。我喜歡用更加優雅和簡單的「連接」技術(新樣式信號/插槽處理)來檢測編輯字段的文本更改。沒有子類化的PyQt Drop事件?

我的問題:是否有信號/插槽連接解決方​​案來處理編輯字段上的刪除而不必繼承QLineEdit?

此外,它很煩人,我必須在子類中實現這兩種方法... dragEnterEvent & dropEvent使放置工作!

import sys 
from PyQt4 import QtGui, QtCore 

class dropedit(QtGui.QLineEdit): # subclass 
    def __init__(self, parent=None): 
     super(dropedit, self).__init__(parent) 
     self.setDragEnabled(True) 
     self.setAcceptDrops(True) 

    def dragEnterEvent(self, event): 
     print "dragEnterEvent:" 

     if event.mimeData().hasUrls(): 
      event.accept() # must accept the dragEnterEvent or else the dropEvent can't occur !!! 
     else: 
      event.ignore() 

    def dropEvent(self, event): 

     if event.mimeData().hasUrls(): # if file or link is dropped 

      urlcount = len(event.mimeData().urls()) # count number of drops 

      url = event.mimeData().urls()[0] # get first url 

      self.setText(url.toString()) # assign first url to editline 

      #event.accept() # doesnt appear to be needed 

class testDialog(QtGui.QDialog): 
    def __init__(self, parent=None): 
     super(testDialog, self).__init__(parent) 


     form = QtGui.QFormLayout() 
     form.setHorizontalSpacing(0) 

     myedit = dropedit() 
     form.addWidget(myedit) 

     self.setLayout(form) 
     self.setGeometry(300, 300, 400, 0) 
     self.setWindowTitle('drop test') 

     myedit.textChanged.connect(self.editchange) # new style signal slot connections 

    @QtCore.pyqtSlot(str) # int represent the column value 
    def editchange(self,data): 
     print "editchange:", data 

if __name__ == "__main__": 

    app = QtGui.QApplication([]) 
    dl = testDialog() 
    dl.exec_() 
    sys.exit(app.closeAllWindows()) 

回答

2

無需子類:您可以使用事件過濾器:

import sys 
from PyQt4 import QtGui, QtCore 

class testDialog(QtGui.QDialog): 
    def __init__(self, parent=None): 
     super(testDialog, self).__init__(parent) 

     form = QtGui.QFormLayout() 
     form.setHorizontalSpacing(0) 

     self.myedit = QtGui.QLineEdit() 
     self.myedit.setDragEnabled(True) 
     self.myedit.setAcceptDrops(True) 
     self.myedit.installEventFilter(self) 

     form.addWidget(self.myedit) 

     self.setLayout(form) 
     self.setGeometry(300, 300, 400, 0) 
     self.setWindowTitle('drop test') 

     self.myedit.textChanged.connect(self.editchange) # new style signal slot connections 

    @QtCore.pyqtSlot(str) # int represent the column value 
    def editchange(self,data): 
     print "editchange:", data.toLatin1() 

    def eventFilter(self, object, event): 
     if (object is self.myedit): 
      if (event.type() == QtCore.QEvent.DragEnter): 
       if event.mimeData().hasUrls(): 
        event.accept() # must accept the dragEnterEvent or else the dropEvent can't occur !!! 
        print "accept" 
       else: 
        event.ignore() 
        print "ignore" 
      if (event.type() == QtCore.QEvent.Drop): 
       if event.mimeData().hasUrls(): # if file or link is dropped 
        urlcount = len(event.mimeData().urls()) # count number of drops 
        url = event.mimeData().urls()[0] # get first url 
        object.setText(url.toString()) # assign first url to editline 
        #event.accept() # doesnt appear to be needed 
      return False # lets the event continue to the edit 
     return False 

if __name__ == "__main__": 

    app = QtGui.QApplication([]) 
    dl = testDialog() 
    dl.exec_() 
    sys.exit(app.closeAllWindows()) 
+0

哇!有趣的方法,但我希望能夠簡化和減少所需的代碼量。謝謝你的努力。我可能會在別處找到這種方法。 – panofish

+0

@panofish:你的意思是你想避免'eventFilter'code? – Frodon

+0

我認爲需要在accept()後返回'True'。並且不需要「忽略()」。 – Winand