- почем опиум для народа?
(с) Остап Бендер
Write once run anywhere
• GUI приложение с нуля
• Сопровождение легаси кода
• Портирование легаси
Применимость доклада
В рамках работы:
Вне работы:
• Персональные проекты
• Быстрая разработка
• Компактность кода
• Мультиплатформенность
• Зрелая экосистема
Преимущества
разработки на Python
• Медленный runtime у Python
Отрицательные стороны
разработки на Python
Пример сложного десктопного
приложения на Python
Основные десктопные системы
MacOS
Windows
Linux
• Небольшой размер
• Нетребовательность к
ресурсам
• Нативный вид
• Системная интеграция
ТРЕБОВАНИЯ
К КРОССПЛАТФОРМЕННОМУ
GUI ПРИЛОЖЕНИЮ
Виджетсеты платформ
Carbon/Cocoa
WinAPI
Gtk+/Qt
Биндинги к Python
PyObjC
pywin32
PyGtk
PyQt/PyKDE
Python
как основа для
кроссплатформенных
приложений
Три независимых проекта, использующих
платформенно-специфические биндинги:
• на Windows - pywin32
• на MacOS X - PyObjC
• на Linux - PyGtk
Самый надежный путь,
но при этом самый затратный
Казалось бы, что может быть проще?
Правильно выбранный тулкит и
мультиплатформенное приложение готово!
• Tkinter
• PyQt
• PyGtk
• wxpython
МУЛЬТИПЛАТФОРМЕННЫЕ ТУЛКИТЫ
Tkinter
PyQt
PyGtk
wxpython
Look & Feel
для Tkinter
на Linux платформе
"Что делать?" (с)
и кто виноват :)
WX 3.0
WX 3.0
WX 2.8
WX 3.0 WX 3.0 WX 2.8
Получившаяся архитектура sK1
Приложение sK1
Widgetset Abstraction
Layer (WAL)
Код на WAL
Код на wxpython
panel = wx.Panel()
vbox = wx.BoxSizer(wx.VERTICAL)
btn = wx.Button(panel, -1, "click Me")
vbox.Add(btn, 0, wx.ALIGN_CENTER)
btn.Bind(wx.EVT_BUTTON, self.OnClicked)
panel = wal.VPanel()
btn = wal.Button(panel, "click Me",
onclick=self.on_clicked)
panel.pack(btn)
Код класса wal.Button
class Button(wx.Button, WidgetMixin):
callback = None
def __init__(self, parent, text, size=DEF_SIZE,
onclick=None, tooltip='', default=False, pid=wx.ID_ANY):
wx.Button.__init__(self, parent, pid, text, size=size)
if default: self.SetDefault()
if onclick:
self.callback = onclick
self.Bind(wx.EVT_BUTTON, self.on_click, self)
if tooltip: self.SetToolTipString(tooltip)
def set_default(self):
self.SetDefault()
def on_click(self, event):
if self.callback: self.callback()
• Кроссплатформенность
• Кроссвиджетсетность и
кроссверсионность
• Код приложения не завязан на UI
• Сокращение объема кода
• Стиль кода по PEP-8
• Улучшение читабельности кода
Преимущества паттерна WAL
Паттерн WAL в
контексте поддержки
легаси кода
PyGtk 2.8
КОД
ПРИЛОЖЕНИЯ
PyGtk 2.8
КОД
ПРИЛОЖЕНИЯ
PyGtk 2.8
КОД
ПРИЛОЖЕНИЯ
WAL
Gtk 3
КОД
ПРИЛОЖЕНИЯ
WAL
PyGtk 2.8
КОД
ПРИЛОЖЕНИЯ
WAL
Qt 5
КОД
ПРИЛОЖЕНИЯ
WAL
PyGtk 2.8
КОД
ПРИЛОЖЕНИЯ
WAL
PyGtk
Логика приложения
Widgetset Abstraction
Layer (WAL)
TkinterTkinter
Упрощенный вариант
мультиплатформенного приложения
PyObjC pywin32 PyGtk
Вариант создания полноценного
мультиплатформенного приложения
Логика приложения
Widgetset Abstraction
Layer (WAL)
Разработка
унифицированных
абстракционных
слоев для всех
платформ
Спасибо за внимание!
И какие есть вопросы?

«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr