Как использовать Drag and Drop? — wxPython #21

Большинство современных пользователей применяют перетаскивание практически инстинктивно. Я уверен, что вы хотя бы раз перетаскивали файл из одной папки в другую на этой неделе. К счастью, набор инструментов интерфейса wxPython обладает встроенным перетаскиванием. В данной статье я расскажу вам о том, как применить его в комбинации со своими приложениями.

Приступая к работе

wxPython содержит несколько разных видов перетаскивания. Вы можете выбрать один из следующих типов:

  • FileDropTarget
  • TextDropTarget
  • PyDropTarget

Первые два имеют весьма говорящие названия. Последний, wx.PyDropTarget на самом деле просто создаёт область вокруг самой wx.DropTarget и захватывает её. Он также добавляет несколько дополнительных методов, которые вы не можете встретить в простом wx.DropTarget. Мы начнём с примера использования wx.FileDropTarget.

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Создаём FileDropTarget

Как использовать Drag and Drop? - wxPython #21

Набор инструментов wxPython делает создание FileDropTarget невероятно простым. Вам требуется освоить метод, прежде чем вы сможете это, но, по правде говоря, он весьма прямолинеен. Давайте сначала взглянем на пример кода, а потом я потрачу несколько минут на его объяснение.

Не так уж и плохо, неправда ли? Первое, что нужно сделать – превратить наш wx.FileDropTarget в подкласс класса MyFileDropTarget. Внутри мы встретимся с предопределённым методом OnDropFiles. Он принимает координаты позиции курсора и адреса перетянутых файлов, а затем вписывает эти данные в текстовый контроль.

Для того, чтобы притянуть цель перетаскивания к текстовому контролю, вам стоит взглянуть на класс DnDPanel, в котором мы вызываем метод текстового контроля SetDropTarget и задаём инстанцию класса нашей цели перетаскивания. У нас есть ещё 2 метода в нашем панельном классе, которые делают так, что класс цели перетаскивания вызывает текстовый контроль: SetInsertionPointEnd и updateText.

Учтите, что, если мы используем объект панели в качестве цели перетаскивания, мы можем называть эти методы как нам угодно. Если целью перетаскивания является ваш TextCtrl, мы должны будем пойти другим путём, который рассматривается в следующем примере!

Создаём TextDropTarget

Как использовать Drag and Drop? - wxPython #21

wx.TextDropTarget используется, когда вам нужно перетянуть выбранный текст в текстовый контроль. Пожалуй, самым распространённым примером будет перетягивание ссылки из адресной строки браузера в окно чата в социальной сети или мессенджере. Давайте потратим немного времени и научимся как помещать подобную функцию в ваши приложения с помощью wxPython!

Снова же нам нужно превратить в подкласс наш класс цели перетаскивания. В данном случае, мы называем это MyTextDropTarget. В данном классе, нам нужно разобраться с OnDropText и OnDragOver. Я не нашёл достойной или хотя бы подходящей документации о втором, но мне кажется, что он просто возвращает копию перемещённых данных. Метод OnDropText вводит текст в текстовый контроль.

Учтите, что с тех пор как мы привязали цель перетаскивания напрямую к текстовому контролю (смотрите панельный класс), мы ОБЯЗАНЫ использовать метод, который называется WriteText, чтобы обновлять текстовый контроль. Если вы измените это, то получите сообщение с ошибкой.

Обычное перетаскивание с PyDropTarget

Как использовать Drag and Drop? - wxPython #21

Если вы вдруг ещё не догадались, то два предыдущих примера были сильно модифицированными версиями демо перетаскивания, которые я взял с официального демо-пакета wxPython. Мы будем использовать код, основанный на демо-версии URLDragAnd-Drop для объяснения PyDropTarget. Интересны факт о данном демо: вы можете не только создавать виджет, который принимает перетянутый текст, но и можете перетаскивать текст из этого виджета в свой браузер! Давайте взглянем!

Первый класс – класс нашей цели перетаскивания. Здесь мы создаём wx.URLDataObject, который служит хранилищем для нашей URL-информации. Затем в методе OnData мы извлекаем ссылку и присоединяем её к текстовому контролю. В панельном классе мы цепляем цель перетаскивания также, как мы сделали это в двух других примерах, так что я не буду повторятся и сразу пойду навстречу к неизведанному.

Второй текстовый контроль определённо стоит нашего внимания. Здесь мы ищем движения курсора, используя EVT_MOTION. В хэндлере событий, отвечающем за передвижения курсора, который называется OnStartDrag, мы проводим проверку, чтобы убедится, что пользователь действительно пытается перетащить объект.

Если это действительно так, то мы захватываем значение из текстового бокса и добавляем его в только что созданный URLDataObject. Затем мы создаём инстанцию из DropSource, и пропускаем его через наш второй текстовый контроль, так как он и ЕСТЬ источник.

Мы задаём данные источника в URLDataObject. Наконец-то, мы вызываем DoDragDrop в нашем источнике перетаскивания (текстовом контроле, если вдруг кто-то забыл), который ответит посредством движения, копирования, отмены или неудачи. Если вы перетащили ссылку в адресную строку вашего браузера, он скопирует её. В других случаях, он, скорее всего, работать не будет. Теперь, давайте соберём всё, что мы усвоили и сделаем что-то оригинальное!

Примечание: Некоторые браузеры могут не работать с этим кодом. К примеру, на Linux, он не работал в Google Chrome, но отлично работал в Mozilla Firefox.

Создаём обычное приложение с перетаскиванием

Как использовать Drag and Drop? - wxPython #21

Я решил, что было бы забавно взять демо цели перетаскивания и превратить его в что-то с применением виджета ObjectListView (враппер для ListCtrl), которое сможет сообщить нам определённую информацию о перетаскиваемом файле, которые мы в него вставляем. Он будет отображать следующую информацию: имя файла, дата создания, дата редактирования и размер файла. Вот сам код:

Большую часть приёмов из этого кода вы уже видели. У нас есть подкласс FileDropTarget, мы присоединяем к нему панель и, немного позже, виджет ObjectListView в качестве инстанции цели перетаскивания. У нас также есть общий класс, содержащий данные, связанные с файлами. Если вы запускаете эту программу и перетаскиваете в неё папки, вы не получите правильного размера папки.

Скорее всего вам нужно дополнить код следующим образом: заставить программу проверить каждый файл в папке и затем суммировать их размеры. Так что, не стесняйтесь настраивать его так, как вам удобно. Как бы то ни было «гвоздём» программы является метод updateDisplay. Здесь мы захватываем виртуальную статистику файла и конвертируем её в более читабельные форматы, так как все нормальные люди не исчисляют время в секундах с полуночи 1 января 1970 года. Сразу же после трансформации данных, мы их отображаем. Ну разве не круто?

Итоги

Сейчас вы уже должны освоить как минимум три разных метода перетаскивания wxPython. Надеюсь, что вы воспользуетесь новой информацией со всей ответственностью и в ближайшее время создадите несколько свежих приложений с открытым исходным кодом. Удачи!