Пример Использования Wxpython Для Создания Интерфейса Узла. Часть 4. Реализация Drag&Drop

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

Этот туториал предназначен для тех, кто уже начал изучать эту библиотеку и хочет увидеть что-то более сложное и целостное, чем самые простые примеры (хотя начнётся всё с относительно простых вещей).



Пример использования WxPython для создания интерфейса узла.
</p><p>
 Часть 4. Реализация Drag&Drop

В этой части мы добавим в наше приложение поддержку Drag&Drop и научим его создавать таким образом новые узлы.

Часть 1: Учимся рисовать Часть 2. Обработка событий мыши Часть 3. Продолжаем добавлять функции + обработку клавиатуры Часть 4. Реализация Drag&Drop Часть 5: Соединение узлов Кому интересно, добро пожаловать под кат.



9. Добавьте поддержку Drag&Drop.

Поддержка Drag&Drop — штука полезная и популярная, но здесь мы не будем использовать ее по прямому назначению.

Вот как мы будем создавать новые узлы.

Работает эта штука довольно просто.

Нам нужно создать объект класса «wx.TextDropTarget» и передать его методу «SetDropTarget» класса «wx.Window», от которого унаследован наш холст. Соответственно, в момент дропа будет вызван метод «wx.TextDropTarget.OnDropText», который нам и нужно будет реализовать.

Для теста реализация этого класса будет выглядеть так:

  
  
  
  
  
  
  
  
   

class TextDropTarget(wx.TextDropTarget): def __init__(self): wx.TextDropTarget.__init__(self) def OnDropText(self, x, y, data): print x, y, data

Теперь когда вы кидаете текст в окно, в консоли будет печататься сообщение с позицией и сам текст. Как вы уже догадались, для приема файлов существует аналогичный класс «wx.FileDropTarget», который работает аналогичным образом, или класс «wx.PyDropTarget», который может принимать все и вся.



10. Создавайте узлы с помощью Drag&Drop

Просто набирать текст не очень полезно, поэтому мы используем полученный текст для создания с его помощью узлов.

Но сначала нам нужно немного изменить архитектуру и добавить фабрику узлов (это нам пригодится в будущем).

На данный момент это будет очень простая фабрика:

class NodesFactory(object): def __init__(self): pass def CreateNodeFromDescription(self, nodeDescription): return SimpleTextBoxNode(text=nodeDescription)

который просто создает экземпляр SimpleTextBoxNode, который является немного продвинутым потомком SimpleBoxNode:

class SimpleTextBoxNode(SimpleBoxNode): def __init__(self, **kwargs): super(SimpleTextBoxNode, self).

__init__(**kwargs) self.text = kwargs.get("text", "No text") def Render(self, gc): super(SimpleTextBoxNode, self).

Render(gc) gc.DrawText(self.text, self.position[0]+10, self.position[1]+10)

который, в свою очередь, отображает данный текст поверх прямоугольного узла.

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

def CreateNodeFromDescriptionAtPosition(self, nodeDescription, pos): node = self._nodesFactory.CreateNodeFromDescription(nodeDescription) if node: node.position = pos self._canvasObjects.append(node) self.Render()

И немного модернизируем TextDropTarget, чтобы он вызывал этот метод при поступлении текста:

class TextDropTarget(wx.TextDropTarget): def __init__(self, canvas): wx.TextDropTarget.__init__(self) self._canvas = canvas def OnDropText(self, x, y, data): print x, y, data self._canvas.CreateNodeFromDescriptionAtPosition(data, [x, y])

И теперь мы можем создавать новые текстовые узлы, просто выбрасывая на холст фрагменты текста.

Все это выглядит следующим образом: Код, как всегда, можно найти в соответствующем зафиксировать на GitHub .



11. Клонируйте узлы с помощью Drag&Drop

Но помимо создания узлов с помощью Drag&Drop можно также организовать копирование узлов, причем очень легко.

Если пользователь удерживает Ctrl при перетаскивании узла, нам просто нужно инициировать запуск Drag&Drop и дать описание узла.

А код создания узла сделает за нас остальную работу.

Чтобы инициировать перетаскивание, мы добавим следующий код в обработчик щелчка левой кнопкой мыши:

if evt.ControlDown() and self._objectUnderCursor.clonable: text = self._objectUnderCursor.GetCloningNodeDescription() data = wx.TextDataObject(text) dropSource = wx.DropSource(self) dropSource.SetData(data) dropSource.DoDragDrop(wx.Drag_AllowMove)

Здесь мы создаем источник Drag&Drop и передаем ему описание, полученное от узла.

Остается только реализовать на узле метод «GetCloningNodeDescription» и все будет готово.

Но сначала давайте реализуем интерфейс:

class ClonableObject(CanvasObject): def __init__(self, **kwargs): super(ClonableObject, self).

__init__(**kwargs) self.clonable = True def GetCloningNodeDescription(self): """ GetNodeDescription should return a dictionary that contains all information required for cloning this node at another position """ raise NotImplementedError()

А теперь реализация метода на узле:

def GetCloningNodeDescription(self): return self.text

который просто выдает ее текст. Текущая версия кода живет здесь .



12. Узлы масштабирования

Что ж, прежде чем завершить четвертую часть, давайте добавим еще одну оборочку.

Давайте масштабируем узлы в соответствии с размером текста.

Для этого немного изменим метод отрисовки текстового узла:

def Render(self, gc): textDimensions = gc.GetTextExtent(self.text) self.boundingBoxDimensions = [textDimensions[0]+20, textDimensions[1]+20] super(SimpleTextBoxNode, self).

Render(gc) gc.DrawText(self.text, self.position[0]+10, self.position[1]+10)

Метод GetTextExtent в этом случае возвращает размер прямоугольника, который занимает текст. Соответственно, перед рендерингом узла мы обновляем его размеры так, чтобы он был на 10 пикселей больше текста с каждой стороны.

Вот как сейчас выглядит весь процесс: Код живет в этом зафиксировать на GitHub .

PS: Пожалуйста, пишите мне об опечатках.

Теги: #ui #framework #interface #wxpython #python #drag-and-drop #разработка веб-сайтов #python #программирование

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.