Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Пример применения WxPython для создания нодового интерфейса. Часть 1: Учимся рисовать

Anna | 16.06.2014 | нет комментариев
В маленьком цикле статей будет описано применение WxPython для решения абсолютно определенной задачи по разработке пользовательского интерфейса, да еще и то, как сделать это решение универсальным. Туториал данный расчитан на тех, кто теснее начал постигать эту библиотеку и хочет увидеть что-то больше трудное и целостное, чем простейшие примеры (правда начнется все с касательно примитивных пророческой).

А начиналось все так: потребовалось мне для одного плана сделать UI, где нужно последовательность обработки сообщений редактировать. Что-то наподобии Simulink’а. Соответственно, полез искать готовые либы/фреймворки. Вначале подумал, что задачка знаменитая и кто-нибудь теснее сделал это велосипед, поискал, поискал и… не обнаружил. Вернее обнаружил много антикварных велосипедов, но кто же будет пользоваться чужим ветхим велосипедом, если дозволено сделать свой новейший. Но раз уж делать новейший велосипед, отчего бы не сделать его универсальным, немного ли, где еще сгодится.

Так что испробую в нескольких статья описать процесс разработки с нуля до работающего примера. Ну и Дабы было увлекательно, а ферймворк был универсален, первая задача для него будет не подобие Simulink’а, а софтина для рисования блок-схем а-ля Visio, но со своим блек-джеком и остальными участниками:)

Кому увлекательно, добродушно пожаловать под кат…

Небольшой комментарий: я буду применять английские имена в коде и Зачастую буду применять транслитерацию, т.е. взамен того, Дабы писать «canvas» либо «холст», я буду писать «канвас». Да, я знаю, что это может выглядеть нехорошо и не верно, но совершенного метода смешивать русский и английский не существует, у всех методов есть свои недочеты (мое личное суждение).

1. 1-й тест

Начнем с примитивных тривиальных пророческой. Раз это фреймворк, значит кто-то будет на его основе делать приложения либо части приложений, которые будут делать. Т.е. для простейшего теста, нам необходимо изготовить простейшее приложение. Не крепко длинно думая, я решил, что буду рисовать объединенные друг с ином прямоугольники и начал с такого кода (он будет жить в файле «ConnectedBoxes.py»):

import wx
from MoveMe.Canvas.Canvas import Canvas

class CanvasWindow(wx.Frame):
    def __init__(self, *args, **kw):
        wx.Frame.__init__(self, *args, **kw)
        s = wx.BoxSizer(wx.VERTICAL)
        s.Add(Canvas(self), 1, wx.EXPAND)
        self.SetSizer(s)

if __name__ == '__main__':
    app = wx.PySimpleApp()
    CanvasWindow(None).Show()
    app.MainLoop()

Здесь все довольно банально и видимо, помимо пары моментов: MoveMe — это имя нашего фреймворка, а Canvas — это основной класс нашего фреймворка, отвечающий за рендеринг каждого этого дела.

2. Учимся рисовать

Собственно с канваса и начинается наш фреймворк. Он отвечает за хранение объектов (будем называть их нодами), их рендеринг и обработку взаимодействия с пользователем. Соответственно, начнем с простенького рисования.

import wx

class Canvas(wx.PyScrolledWindow):
    """
    Canvas stores and renders all nodes and node connections.
    It also handles all user interaction.
    """
    def __init__(self, *args, **kw):
        super(Canvas, self).__init__(*args, **kw)
        self.scrollStep = kw.get("scrollStep", 10)
        self.canvasDimensions = kw.get("canvasDimensions", [800, 800])
        self.SetScrollbars(self.scrollStep, 
                           self.scrollStep, 
                           self.canvasDimensions[0]/self.scrollStep, 
                           self.canvasDimensions[1]/self.scrollStep)

        self._dcBuffer = wx.EmptyBitmap(*self.canvasDimensions)
        self.Render()
        self.Bind(wx.EVT_PAINT, 
                  lambda evt: wx.BufferedPaintDC(self, self._dcBuffer, wx.BUFFER_VIRTUAL_AREA)
                  )

    def Render(self):
        """Render all nodes and their connection in depth order."""
        cdc = wx.ClientDC(self)
        self.PrepareDC(cdc)
        dc = wx.BufferedDC(cdc, self._dcBuffer)
        dc.Clear()
        gc = wx.GraphicsContext.Create(dc)

        gc.SetPen(wx.Pen('#000000', 2, wx.SOLID))
        gc.DrawRoundedRectangle(12, 34, 56, 78, 10)
        gc.DrawRoundedRectangle(112, 134, 156, 178, 10)

Здесь все становится немножко увлекательнее:

  • Во-первых мы наследуем «wx.PyScrolledWindow» Дабы наше окно дозволено было скролить и задаем параметры скрола в «self.SetScrollbars».
  • Во-вторых, рисовать мы будем не напрямую, а в буфер, Дабы все это происходило стремительней и без мерцаний. Для этого применяется «wx.BufferedDC» и буфер, тот, что является битмэпой.
  • Ну и в-третьих, мы будем применять «wx.GraphicsContext» для комфортного сохранения состояния. Оно имеет способы «PushState» и «PopState», которые сберегают настройки кистей, шрифтов, итд итп, что исключительно пригодно, так ка

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB