Slide 1

Slide 1 text

5 STEPS TO BUILD PYTHON 5 STEPS TO BUILD PYTHON NATIVE GUI WIDGETS FOR NATIVE GUI WIDGETS FOR

Slide 2

Slide 2 text

BeeWare is CROSS-PLATFORM CROSS-PLATFORM NATIVE NATIVE APP DEVELOPMENT APP DEVELOPMENT WITH PYTHON WITH PYTHON and SIMPLE APP DEPLOYMENT SIMPLE APP DEPLOYMENT

Slide 3

Slide 3 text

TOGA TOGA BEEWARE'S GUI TOOLKIT BEEWARE'S GUI TOOLKIT

Slide 4

Slide 4 text

HELLO WORLD HELLO WORLD

Slide 5

Slide 5 text

import toga class HelloWorld(toga.App): def startup(self): self.main_window = toga.MainWindow(title=self.name) main_box = toga.Box() self.main_window.content = main_box self.main_window.show() def main(): return HelloWorld('Hello World', 'org.pybee.helloworld')

Slide 6

Slide 6 text

BACKGROUND BACKGROUND A widget is the controls and logic that a user interacts with when using a GUI A Canvas widget will be used as an example

Slide 7

Slide 7 text

TOGA BLACKBOX TOGA BLACKBOX

Slide 8

Slide 8 text

BRIDGE OR BRIDGE OR TRANSPILER TRANSPILER

Slide 9

Slide 9 text

TOGA WHITEBOX TOGA WHITEBOX

Slide 10

Slide 10 text

MORE TERMS MORE TERMS

Slide 11

Slide 11 text

TOGA_IMPL FACTORY TOGA_IMPL FACTORY PATTERN PATTERN

Slide 12

Slide 12 text

STEP 0 STEP 0 DEVELOPMENT PLATFORM DEVELOPMENT PLATFORM Normally pick the platform that you are most familiar with macOS and GTK are the most developed � Is this a mobile only widget (camera, GPS, etc)?

Slide 13

Slide 13 text

STEP 1 STEP 1 RESEARCH YOUR WIDGET RESEARCH YOUR WIDGET Abstraction requires knowledge of specific examples Create use cases or user stories Get feedback

Slide 14

Slide 14 text

RESEARCH YOUR WIDGET RESEARCH YOUR WIDGET Tkinter canvas = tk.Canvas() canvas.create_rectangle(10, 10, 100, 100, fill="red") canvas.pack()

Slide 15

Slide 15 text

RESEARCH YOUR WIDGET RESEARCH YOUR WIDGET GTK drawingarea = Gtk.DrawingArea() drawingarea.connect("draw", draw) def draw(da, ctx): ctx.set_source_rgb(200, 0, 0) ctx.rectangle(10, 10, 100, 100) ctx.fill()

Slide 16

Slide 16 text

RESEARCH YOUR WIDGET RESEARCH YOUR WIDGET Use Cases

Slide 17

Slide 17 text

STEP 2 STEP 2 WRITE DOCS WRITE DOCS Write your API documentation first The API provides the set of clearly defined methods of communication (layers) between the so�ware components Documentation Driven Development This is iterative with Step 1

Slide 18

Slide 18 text

WRITE DOCS WRITE DOCS The canvas is used for creating a blank widget that you can draw on. ## Usage An example of simple usage is to draw a colored rectangle on the screen using the `rect` drawing object: import toga canvas = toga.Canvas(style=Pack(flex=1)) with canvas.fill(color=rgb(200, 0, 0)) as fill: fill.rect(10, 10, 100, 100)

Slide 19

Slide 19 text

WRITE CODE OUTLINE / WRITE CODE OUTLINE / DOCSTRINGS DOCSTRINGS class Canvas(Widget): """Create new canvas. Args: id (str): An identifier for this widget. style (:obj:`Style`): An optional style object. factory (:obj:`module`): A python module that is capable to return a implementation of this class.

Slide 20

Slide 20 text

STEP 3 STEP 3 IMPLEMENT TOGA_CORE IMPLEMENT TOGA_CORE (WITH TDD) (WITH TDD) First write tests for Toga_core Then code the outline created in Step 2

Slide 21

Slide 21 text

WRITE TESTS FOR TOGA_CORE WRITE TESTS FOR TOGA_CORE def test_widget_created(): assertEqual(canvas._impl.interface, canvas) self.assertActionPerformed(canvas, "create Canvas")

Slide 22

Slide 22 text

WRITE TESTS FOR TOGA_CORE WRITE TESTS FOR TOGA_CORE def test_rect_modify(): rect = canvas.rect(-5, 5, 10, 15) rect.x = 5 rect.y = -5 rect.width = 0.5 rect.height = -0.5 canvas.redraw() self.assertActionPerformedWith( canvas, "rect", x=5, y=-5, width=0.5, height=-0.5 )

Slide 23

Slide 23 text

CODE TOGA_CORE CODE TOGA_CORE class Canvas(Widget): def __init__(self, id=None, style=None, factory=None): super().__init__(id=id, style=style, factory=factory) self._impl = self.factory.Canvas(interface=self) def rect(self, x, y, width, height): self.impl.rect( self.x, self.y, self.width, self.height )

Slide 24

Slide 24 text

STEP 4 STEP 4 IMPLEMENT TOGA_IMPL IMPLEMENT TOGA_IMPL DUMMY BACKEND DUMMY BACKEND Dummy is for automatic testing without a native platform Code the implementation layer API endpoint, create a method for each call of the API Check that all tests now pass

Slide 25

Slide 25 text

IMPLEMENT TOGA_IMPL IMPLEMENT TOGA_IMPL DUMMY BACKEND DUMMY BACKEND class Canvas(Widget): def create(self): self._action("create Canvas") def rect(self, x, y, width, height): self._action( "rect", x=x, y=y, width=width, height=height )

Slide 26

Slide 26 text

STEP 5 STEP 5 IMPLEMENT TOGA_IMPL IMPLEMENT TOGA_IMPL YOUR PLATFORM YOUR PLATFORM Copy toga_dummy and create a new endpoint for the platform you chose in Step 1 Make use of the native interface API for this widget on your platform

Slide 27

Slide 27 text

IMPLEMENT TOGA_IMPL IMPLEMENT TOGA_IMPL YOUR PLATFORM YOUR PLATFORM

Slide 28

Slide 28 text

class Canvas(Widget): def create(self): self.native = Gtk.DrawingArea() self.native.connect("draw", self.gtk_draw_callback) def gtk_draw_callback(self, canvas, gtk_context): self.interface._draw(self, draw_context=gtk_context) def rect(self, x, y, width, height, draw_context): draw_context.rectangle(x, y, width, height)

Slide 29

Slide 29 text

IMPLEMENT TOGA_IMPL IMPLEMENT TOGA_IMPL OTHER PLATFORMS OTHER PLATFORMS

Slide 30

Slide 30 text

class TogaCanvas(NSView): @objc_method def drawRect_(self, rect: NSRect) -> None: context = NSGraphicsContext.currentContext.graphicsPort() class Canvas(Widget): def create(self): self.native = TogaCanvas.alloc().init() def rect(self, x, y, width, height, draw_context, *args, **kwargs): rectangle = CGRectMake(x, y, width, height) core_graphics.CGContextAddRect(draw_context, rectangle

Slide 31

Slide 31 text

ITERATE ITERATE ITERATE THROUGH STEPS 1-5 TO ITERATE THROUGH STEPS 1-5 TO COMPLETE YOUR WIDGET COMPLETE YOUR WIDGET IMPLEMENTATION IMPLEMENTATION

Slide 32

Slide 32 text

SUBMIT A PULL REQUEST! SUBMIT A PULL REQUEST! ��� ���

Slide 33

Slide 33 text

SUMMARY SUMMARY 1. Research Your Widget 2. Write Docs 3. Toga_core 4. Toga_impl - Dummy Backend 5. Toga_impl - Your Platform

Slide 34

Slide 34 text

@danyeaw github.com/danyeaw dan.yeaw.me linkedin.com/in/danyeaw [email protected]