我QtGui.LineEdit()
使用 pySide Qt 绑定在 python 脚本中制作了一个小部件,我希望能够将文件从桌面拖到 QLineEdit 中,以将 QLineEdit 中的文本设置为文件的路径。我已经完成QLineEdit.setDragEnabled(True)
了启用拖放操作,但我是一个不知道如何从这里开始的机器人。有谁知道如何实现这一目标?
问问题
5690 次
3 回答
6
通常,对于事件,您可以使用 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)
于 2012-08-08T20:34:03.890 回答
6
当像这样使用时,使用上面提到的 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)
现在,可以在任何行编辑上使用 drop 处理程序,而无需子类化:
lineEdit.installEventFilter(QLineEditDropHandler(self))
于 2015-03-24T13:41:47.870 回答
2
Erics 答案的一个稍微改进的版本(我希望)将是一个注入器的简短实现,它可以将拖放功能添加到现有的对象。这在使用 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),然后按以下方式使用它 - #usage 示例:
#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_())
于 2014-07-24T21:56:15.470 回答