如何将文件拖拽到Qt Designer生成的QListWidget控件中?
基于Qt Designer生成的QListWidget实现外部文件拖拽功能
不用自定义QListWidget子类,通过Qt的事件过滤器机制即可直接针对Designer生成的现有控件实现拖拽功能,完整实现步骤如下:
1. 修正UI加载代码的错误
你现有代码中提前关闭了UI文件,会导致加载失败,先修正这部分逻辑:
from PySide2 import QtWidgets, QtCore, QtGui, QtUiTools import os class MyTestClass(QtWidgets.QWidget): def __init__(self, parent=None): super(MyTestClass, self).__init__(parent) filePath = os.path.dirname(os.path.abspath(__file__)) uiFileLocation = os.path.join(filePath, "ui", "myDesignerUI.ui") uiFile = QtCore.QFile(uiFileLocation) if uiFile.open(QtCore.QFile.ReadOnly): # 加载UI要在文件关闭前执行 self.widget = QtUiTools.QUiLoader().load(uiFile) uiFile.close() self.widget.setParent(self) # 调整父窗口大小适配UI self.resize(self.widget.size()) # 拿到UI中的QListWidget控件 self.list_widget = self.widget.findChild(QtWidgets.QListWidget, "LIST_MyFiles") # 开启拖放接受,安装事件过滤器 self.list_widget.setAcceptDrops(True) self.list_widget.installEventFilter(self) self.createConnections()
2. 重写eventFilter方法处理拖放事件
在MyTestClass类中添加eventFilter方法,处理拖拽的全流程事件:
def eventFilter(self, watched, event): # 只处理目标QListWidget的事件 if watched == self.list_widget: # 拖拽进入事件:校验文件格式 if event.type() == QtCore.QEvent.DragEnter: if event.mimeData().hasUrls(): # 检查是否所有拖拽的文件都是符合要求的格式 valid = True for url in event.mimeData().urls(): if url.isLocalFile(): suffix = os.path.splitext(url.toLocalFile())[-1].lower() if suffix not in (".obj", ".fbx"): valid = False break else: valid = False break if valid: event.acceptProposedAction() return True event.ignore() return True # 拖拽移动事件:保持允许拖放状态 elif event.type() == QtCore.QEvent.DragMove: event.acceptProposedAction() return True # 拖拽释放事件:添加文件到列表 elif event.type() == QtCore.QEvent.Drop: for url in event.mimeData().urls(): if url.isLocalFile(): file_path = url.toLocalFile() # 可选:去重判断,避免重复添加同一文件 duplicate = False for i in range(self.list_widget.count()): if self.list_widget.item(i).text() == file_path: duplicate = True break if not duplicate: self.list_widget.addItem(file_path) event.acceptProposedAction() return True # 其他事件走默认逻辑 return super().eventFilter(watched, event)
注意事项
- 代码中已经做了后缀大小写不敏感的校验,
.OBJ/.FBX格式的文件也能正常识别 - 如果不需要显示全路径只需要显示文件名,可以将
addItem(file_path)替换为addItem(os.path.basename(file_path)),文件全路径可以存在item的data中方便后续调用 - 你在UI中已经配置了
dragDropMode为DropOnly,符合需求无需额外修改
内容的提问来源于stack exchange,提问作者user17421458
相关产品推荐
相关产品推荐

