Страницы

Поиск по вопросам

пятница, 14 февраля 2020 г.

Реализация Drag&Drop на своем виджете

#python #pyqt5 #pyqt


У меня есть виджет и я хочу сделать какие-нибудь действия с файлами, которые будут
перетащены и брошены на мой виджет.

from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QWidget, QVBoxLayout


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle('Drag & Drop')

        main_layout = QVBoxLayout()
        main_layout.addWidget(QLabel('Drag and drop the file:'))
        main_layout.addStretch()

        central_widget = QWidget()
        central_widget.setLayout(main_layout)

        self.setCentralWidget(central_widget)


if __name__ == '__main__':
    app = QApplication([])

    mw = MainWindow()
    mw.resize(500, 350)
    mw.show()

    app.exec()

    


Ответы

Ответ 1



Как вариант: from PyQt5.QtWidgets import (QTreeView, QFileSystemModel, QApplication, QMainWindow, QLabel, QWidget, QVBoxLayout, QListWidget) from PyQt5.QtCore import QDir class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle('Drag & Drop') self.setGeometry(500, 100, 500, 400) # Даем разрешение на Drop self.setAcceptDrops(True) self.list_files = QListWidget() self.label_total_files = QLabel() model = QFileSystemModel() model.setRootPath(QDir.currentPath()) model.setReadOnly(False) self.tree = QTreeView() self.tree.setModel(model) self.tree.setRootIndex(model.index(QDir.currentPath())) self.tree.setSelectionMode(QTreeView.SingleSelection) self.tree.setDragDropMode(QTreeView.InternalMove) main_layout = QVBoxLayout() main_layout.addWidget(self.tree) main_layout.addWidget(QLabel('Перетащите файл:')) main_layout.addWidget(self.list_files) main_layout.addWidget(self.label_total_files) central_widget = QWidget() central_widget.setLayout(main_layout) self.setCentralWidget(central_widget) self._update_states() def _update_states(self): self.label_total_files.setText('Files: {}'.format(self.list_files.count())) def dragEnterEvent(self, event): # Тут выполняются проверки и дается (или нет) разрешение на Drop mime = event.mimeData() # Если перемещаются ссылки if mime.hasUrls(): # Разрешаем event.acceptProposedAction() def dropEvent(self, event): # Обработка события Drop for url in event.mimeData().urls(): file_name = url.toLocalFile() self.list_files.addItem(file_name) self._update_states() return super().dropEvent(event) if __name__ == '__main__': import sys app = QApplication(sys.argv) w = MainWindow() w.show() sys.exit(app.exec_())

Ответ 2



Минимальная реализация Drag&Drop потребует следующих шагов: Вызов метода setAcceptDrops и передача ему True разрешает виджету обрабатывать события Drop. Переопределение метода-события dragEnterEvent позволит принимать объекты Drag и, при нужде, фильтровать их по какому-либо признаку. Переопределение метода-события dropEvent позволит обработать сброшенные объекты. В этом примере виджет будет принимать на себя папки и файлы, и добавлять их в свой список. Код: from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QWidget, QVBoxLayout, QListWidget class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle('Drag & Drop') # Даем разрешение на Drop self.setAcceptDrops(True) self.list_files = QListWidget() self.label_total_files = QLabel() main_layout = QVBoxLayout() main_layout.addWidget(QLabel('Drag and drop the file:')) main_layout.addWidget(self.list_files) main_layout.addWidget(self.label_total_files) central_widget = QWidget() central_widget.setLayout(main_layout) self.setCentralWidget(central_widget) self._update_states() def _update_states(self): self.label_total_files.setText('Files: {}'.format(self.list_files.count())) def dragEnterEvent(self, event): # Тут выполняются проверки и дается (или нет) разрешение на Drop mime = event.mimeData() # Если перемещаются ссылки if mime.hasUrls(): # Разрешаем event.acceptProposedAction() def dropEvent(self, event): # Обработка события Drop for url in event.mimeData().urls(): file_name = url.toLocalFile() self.list_files.addItem(file_name) self._update_states() return super().dropEvent(event) if __name__ == '__main__': app = QApplication([]) mw = MainWindow() mw.resize(500, 350) mw.show() app.exec() Скриншот: PS. если интересно, тут есть пример Drag&Drop, в котором обрабатывается строго 1 файл и после сброса подсчитывается его md5-хеш.

Комментариев нет:

Отправить комментарий