1

この python pyqt コードは、意図したとおりに機能します。しかし、QLineEdit フィールドへのファイルのドロップを検出できるように、QLineEdit をサブクラス化する必要はありません。編集フィールドへのテキストの変更を検出するために使用した、よりエレガントでシンプルな「接続」手法 (新しいスタイルのシグナル/スロット処理) が気に入っています。

私の質問: 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())
4

2 に答える 2

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())
于 2013-08-02T00:55:26.463 に答える