目录
三、指定区域:只需将上一步的DragWidget加入应用的布局中即可
一、目标:文件拖动到指定区域上传文件
二、实现
from PySide6.QtWidgets import QWidget, QFileDialog, QApplication
class DragWidget(QWidget):
def __init__(self, parent=None):
super(DragWidget, self).__init__(parent)
# 设置允许该区域接收拖放事件
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
# 获取拖放的文件列表
files = event.mimeData().urls()
# 如果文件列表非空,则接收拖放事件
if files:
event.accept()
else:
event.ignore()
def dropEvent(self, event):
files = event.mimeData().urls()
for file in files:
# 拖入的文件路径
file_path = file.toLocalFile()
print(file_path)
# 利用这个路径,我们可以打开文件选择框,并定位到刚刚拖入的文件
upload_path, _ = QFileDialog.getSaveFileName(self, "Upload", file_path)
# 将文件上传到指定路径
if __name__ == '__main__':
app = QApplication([])
window = DragWidget()
window.show()
app.exec()
三、指定区域:只需将上一步的DragWidget加入应用的布局中即可
四、稍稍复杂一点的:带删除按钮和右键菜单
from PySide6.QtCore import QPoint, Qt
from PySide6.QtWidgets import QWidget, QFileDialog, QApplication, QListWidget, QVBoxLayout, QListWidgetItem, \
QPushButton, QHBoxLayout, QLabel, QMenu, QAbstractItemView
from functools import partial
class DragWidget(QWidget):
def __init__(self, parent=None):
super(DragWidget, self).__init__(parent)
# 设置允许该区域接收拖放事件
self.setAcceptDrops(True)
self.paths = []
self.layout = QVBoxLayout()
self.setLayout(self.layout)
self.list_widget = QListWidget()
# 设置列表允许多选
self.list_widget.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
self.layout.addWidget(self.list_widget)
def render_list_widget(self):
self.list_widget.clear()
for idx, item in enumerate(self.paths):
# 创建QListWidgetItem实例
list_item = QListWidgetItem()
widget = QWidget()
row_layout = QHBoxLayout()
widget.setLayout(row_layout)
label = QLabel(item)
# 在QListWidgetItem上设置ContextMenuPolicy属性为Qt.CustomContextMenu
label.setContextMenuPolicy(Qt.CustomContextMenu)
# 将list_item与右键菜单signal customContextMenuRequested连接
label.customContextMenuRequested.connect(self.show_menu)
button = QPushButton('X')
button.clicked.connect(partial(self.on_btn_clicked, list_item))
button.setFixedSize(20, 20)
button.setStyleSheet("background-color: red; color: white;")
row_layout.addWidget(label)
row_layout.addWidget(button)
row_layout.setContentsMargins(0, 0, 1, 1) # 去掉边距
list_item.setSizeHint(row_layout.sizeHint())
self.list_widget.addItem(list_item)
self.list_widget.setItemWidget(list_item, widget)
def on_btn_clicked(self, list_item):
"""
处理按钮的信号槽函数
"""
row = self.list_widget.row(list_item)
self.list_widget.takeItem(row)
del self.paths[row]
def show_menu(self, widget):
# 创建右键菜单
menu = QMenu()
# 添加删除项目的选项
delete_action = menu.addAction("删除")
# 如果是删除按钮的右键菜单,则获取对应的 QListWidgetItem 实例
if isinstance(widget, QPushButton):
list_item = widget.parent().parent()
else:
list_item = self.list_widget.currentItem()
# 如果当前有选中的项目,则在右键菜单中显示删除选项
if list_item is not None:
action = menu.exec_(self.list_widget.mapToGlobal(widget))
if action == delete_action:
# 获取选中项目的列表
selected_items = self.list_widget.selectedItems()
for item in selected_items:
# 获取项目所在行号
row = self.list_widget.row(item)
# 从QListWidget控件中删除行
self.list_widget.takeItem(row)
del self.paths[row]
def dragEnterEvent(self, event):
# 获取拖放的文件列表
files = event.mimeData().urls()
# 如果文件列表非空,则接收拖放事件
if files:
event.accept()
else:
event.ignore()
def dropEvent(self, event):
files = event.mimeData().urls()
for file in files:
# 拖入的文件路径
file_path = file.toLocalFile()
self.paths.append(file_path)
self.render_list_widget()
if __name__ == '__main__':
app = QApplication([])
window = DragWidget()
window.show()
app.exec()