Шаг 237.
Библиотека PyQt5.
Графическая сцена. Обработка событий. Обработка перетаскивания и сброса

    На этом шаге мы рассмотрим алгоритм реализации сбрасывания и переноса, а также основные методы классов, участвующие с этом.

    Прежде чем обрабатывать перетаскивание и сброс, необходимо сообщить системе, что графический объект может их обработать. Для этого следует вызвать метод setAcceptDrops() класса QGraphicsItem и передать ему значение True.

    Обработка перетаскивания и сброса в графическом объекте выполняется следующим образом:

    Обработать события, возникающие при перетаскивании и сбрасывании объектов, позволяют следующие методы:

    Класс QGraphicsSceneDragDropEvent наследует все методы классов QGraphicsSceneEvent и QEvent и добавляет поддержку методов:

    В заключение рассмотрим небольшой пример (источник: http://python-3.ru/page/pyqt5-drag-drop): реализуем перетаскивание текста из строки и поместим его на кнопку. В результате надпись на кнопке изменится.

    Вот текст приложения:

import sys
from PyQt5.QtWidgets import QPushButton, QWidget, QLineEdit, QApplication
 
class Button(QPushButton):
  
    def __init__(self, title, parent):
        super().__init__(title, parent)
        self.setAcceptDrops(True)
        
    def dragEnterEvent(self, e):
        if e.mimeData().hasFormat('text/plain'):
            e.accept()
        else:
            e.ignore() 
    def dropEvent(self, e):
        self.setText(e.mimeData().text()) 
 
class Example(QWidget):
  
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):
        edit = QLineEdit('', self)
        edit.setDragEnabled(True)
        edit.move(30, 65)
        button = Button("Button", self)
        button.move(190, 65)
        
        self.setWindowTitle('Пример drag & drop')
        self.setGeometry(300, 300, 300, 150)
 
app = QApplication(sys.argv)
ex = Example()
ex.show()
app.exec_()
Архив с файлом можно взять здесь.

    Результат работы приложения:


Рис.1. Результат работы приложения

    Прокомментируем приведенный текст программы.

    Для того, чтобы перетащить текст на кнопку (виджет) QPushButton, мы должны переопределить несколько методов. Для этого создаём наш собственный класс Button, который будет наследовать класс QPushButton:

class Button(QPushButton):
  
    def __init__(self, title, parent):
        super().__init__(title, parent)
        self.setAcceptDrops(True)
    .    .   .    .

    Делаем возможными события перетаскивания для виджета:

        self.setAcceptDrops(True)

    Сначала переопределяем метод dragEnterEvent(), сообщая о типе данных, который разрешаем перетаскивать. В нашем случае, это обычный текст:

    def dragEnterEvent(self, e):
        if e.mimeData().hasFormat('text/plain'):
            e.accept()
        else:
            e.ignore() 

    Путём переопределения метода dropEvent(), определяем, что нужно делать после события перетаскивания. Здесь меняем надпись на кнопке:

    def dropEvent(self, e):
        self.setText(e.mimeData().text()) 

    Виджет QLineEdit имеет встроенную поддержку операций перетаскивания. Все, что нужно сделать, - это вызвать метод setDragEnabled(), чтобы активировать её:

        edit = QLineEdit('', self)
        edit.setDragEnabled(True)

    На следующем шаге мы рассмотрим фильтрацию событий.




Предыдущий шаг Содержание Следующий шаг