pySide Qt バインディングを使用して Python スクリプトでウィジェットを作成しましQtGui.LineEdit()
た。ファイルをデスクトップから QLineEdit にドラッグして、QLineEdit のテキストをファイルのパスに設定できるようにしたいと考えています。ドラッグ アンド ドロップ操作を有効にしましたQLineEdit.setDragEnabled(True)
が、ここから先に進む方法を失ったボットです。これを達成する方法を知っている人はいますか?
3 に答える
通常、イベントの場合、QObject.eventFilter と QObject.installEventFilter を使用して、イベントをインターセプトして処理できます。ただし、QDrag/QDrop イベントでは機能しないようです (もし私がこれについて間違っている場合は、他の誰かが私に知らせてください。私はそれを機能させる方法を見つけようとしてすべての髪を引っ張っているので)。フィルタリング)。
私が知っている最善の方法は、QLineEdit をサブクラス化し、dragEnterEvent、dragMoveEvent、および dropEvent メソッドをオーバーロードして、クラスにドラッグされているものが有効かどうかを確認することです。何かのようなもの:
from PySide.QtGui import QLineEdit
class FileEdit(QLineEdit):
def __init__( self, parent ):
super(FileEdit, self).__init__(parent)
self.setDragEnabled(True)
def dragEnterEvent( self, event ):
data = event.mimeData()
urls = data.urls()
if ( urls and urls[0].scheme() == 'file' ):
event.acceptProposedAction()
def dragMoveEvent( self, event ):
data = event.mimeData()
urls = data.urls()
if ( urls and urls[0].scheme() == 'file' ):
event.acceptProposedAction()
def dropEvent( self, event ):
data = event.mimeData()
urls = data.urls()
if ( urls and urls[0].scheme() == 'file' ):
# for some reason, this doubles up the intro slash
filepath = str(urls[0].path())[1:]
self.setText(filepath)
上記の eventFilter メカニズムの使用は、次のように使用すると機能します。
from PyQt4.QtCore import QObject, QEvent
class QLineEditDropHandler(QObject):
def eventFilter(self, watched, event):
if event.type() == QEvent.DragEnter:
# we need to accept this event explicitly to be able to receive QDropEvents!
event.accept()
if event.type() == QEvent.Drop:
md = event.mimeData()
if md.hasUrls():
obj.setText(url.toLocalFile())
return True
return super().eventFilter(watched, event)
これで、サブクラス化せずに任意の行編集でドロップ ハンドラーを使用できます。
lineEdit.installEventFilter(QLineEditDropHandler(self))
エリックの回答のわずかに改善されたバージョン (希望) は、既存のオブジェクトにドラッグ アンド ドロップ機能を追加できるインジェクターの短い実装です。これは、QtDesignerで設計する際に役立ちました-
from PyQt4.QtGui import QLineEdit
# reference taken from : http://stackoverflow.com/questions/11872141/drag-a-file-into-qtgui-qlineedit-to-set-url-text
class lineEdit_dragFile_injector():
def __init__(self, lineEdit, auto_inject = True):
self.lineEdit = lineEdit
if auto_inject:
self.inject_dragFile()
def inject_dragFile( self ):
self.lineEdit.setDragEnabled(True)
self.lineEdit.dragEnterEvent = self._dragEnterEvent
self.lineEdit.dragMoveEvent = self._dragMoveEvent
self.lineEdit.dropEvent = self._dropEvent
def _dragEnterEvent( self, event ):
data = event.mimeData()
urls = data.urls()
if ( urls and urls[0].scheme() == 'file' ):
event.acceptProposedAction()
def _dragMoveEvent( self, event ):
data = event.mimeData()
urls = data.urls()
if ( urls and urls[0].scheme() == 'file' ):
event.acceptProposedAction()
def _dropEvent( self, event ):
data = event.mimeData()
urls = data.urls()
if ( urls and urls[0].scheme() == 'file' ):
# for some reason, this doubles up the intro slash
filepath = str(urls[0].path())[1:]
self.lineEdit.setText(filepath)
上記を別のファイル (例: file_lineEdit.py) に保存し、次のように使用します - #使用例:
#in the main APP file, just add:
import file_lineEdit
...
if __name__ == "__main__":
app = QApplication(sys.argv)
window = QDialog()
ui = Ui_Dialog()
ui.setupUi(window)
file_lineEdit.lineEdit_dragFile_injector(ui.lineEdit)
file_lineEdit.lineEdit_dragFile_injector(ui.lineEdit_2)
file_lineEdit.lineEdit_dragFile_injector(ui.lineEdit_3)
window.show()
sys.exit(app.exec_())