BeeWare peaker Chinese document - Tutorial 2 - make it interesting

Posted by elie on Tue, 18 Jan 2022 14:05:11 +0100

In tutorial 1, we generated a working stub project, but we didn't write any code ourselves. Let's see what's generated for us.

What happened
In the src/helloworld directory, you should see three files__ init__.py: __ main__.py and app py.

__ init__.py marks the directory helloworld as an importable Python module. It is an empty file; The fact that it exists tells the Python interpreter that the helloworld directory defines a module.

__ main__.py marks the module helloworld as a special module - executable module. If you try to run the helloworld module using, this file is where Python will start executing. The content is relatively simple: python -m helloworld__main__.py__main__.py

from helloworld.app import main

if __name__ == '__main__':
    main().main_loop()


That is - it mainly imports methods from the helloworld application; If it is executed as an entry point, the main() method is called and the main loop of the application is started. The main loop is the way the GUI application listens for user input, such as mouse clicks and keyboard presses.

The more interesting file is app Py - it contains the logic to create our application window:

import toga
from toga.style import Pack
from toga.style.pack import COLUMN, ROW

class HelloWorld(toga.App):
    def startup(self):
        main_box = toga.Box()

        self.main_window = toga.MainWindow(title=self.formal_name)
        self.main_window.content = main_box
        self.main_window.show()

def main():
    return HelloWorld()


Let's browse line by line:

import toga
from toga.style import Pack
from toga.style.pack import COLUMN, ROW


First, we import the toga widget toolkit, as well as some style related utility classes and constants. Our code hasn't used these yet -- but we'll use them soon.

Then, we define a class:

class HelloWorld(toga.App):


Each Toga application has a Toga App instance, representing the running entity of the application. The application may eventually manage multiple windows; But for a simple application, there will be only one main window.

Next, we define a startup() method:

def startup(self):
    main_box = toga.Box()


The first thing the startup method does is define a main box. Toga's layout scheme behaves like HTML. You can build an application by building a set of boxes, each containing other boxes or actual widgets. Then apply styles to these boxes to define how they will use the available window space.

In this application, we defined a box, but we didn't put anything in it.

Next, we define a window in which we can put the empty box:

self.main_window = toga.MainWindow(title=self.formal_name)


This will create an instance of a, which is Toga MainWindow will have a title that matches the application name. The main window is a special window in Toga -- it is a window closely related to the life cycle of the application. When the main window closes, the application exits. The main window is also a window with an application menu (if you are on a platform like Windows, where the menu bar is part of the window)

Then we add our empty box as the content of the main window and instruct the application to display our window:

self.main_window.content = main_box
self.main_window.show()


Finally, we define a main() method. That's why we created our application instance:

def main():
    return HelloWorld()


This main() method is a method that is imported and called by__ main__.py. HelloWorld, which creates and returns an instance of our application.

This is the simplest Toga application. Let's put some of our own content into the application and let the application do something interesting.

Add some of our own content
Modify your HelloWorld class Src / HelloWorld / APP Py to make it look like this:

class HelloWorld(toga.App):
    def startup(self):
        main_box = toga.Box(style=Pack(direction=COLUMN))

        name_label = toga.Label(
            'Your name: ',
            style=Pack(padding=(0, 5))
        )
        self.name_input = toga.TextInput(style=Pack(flex=1))

        name_box = toga.Box(style=Pack(direction=ROW, padding=5))
        name_box.add(name_label)
        name_box.add(self.name_input)

        button = toga.Button(
            'Say Hello!',
            on_press=self.say_hello,
            style=Pack(padding=5)
        )

        main_box.add(name_box)
        main_box.add(button)

        self.main_window = toga.MainWindow(title=self.formal_name)
        self.main_window.content = main_box
        self.main_window.show()

    def say_hello(self, widget):
        print("Hello", self.name_input.value)


note

Do not delete the import at the top of the file or at the bottom of main(). You only need to update the HelloWorld class.

Let's take a closer look at what has changed.

We are still creating a main box; However, we are now applying a style:

main_box = toga.Box(style=Pack(direction=COLUMN))


Toga's built-in layout system is called "Pack". It behaves much like CSS. You define objects in the hierarchy - in HTML, objects are < div >, < span > and other DOM elements; In toga, they are widgets and boxes. You can then assign styles to individual elements. In this case, we mean that this is a COLUMN box -- that is, it is a box that consumes all available widths and expands its height as content is added, but it will be as short as possible.

Next, we define several widgets:

name_label = toga.Label(
    'Your name: ',
    style=Pack(padding=(0, 5))
)

self.name_input = toga.TextInput(style=Pack(flex=1))


Here, we define a Label and a TextInput. Both widgets have styles associated with them; The Label will have 5px padding on its left and right sides and no padding at the top and bottom. TextInput is marked flexible -- that is, it will absorb all available space on its layout axis.

TextInput is assigned as an instance variable of the class. This gives us easy access to the widget instance -- we'll use it later.

Next, we define a box to hold the two widgets:

name_box = toga.Box(style=Pack(direction=ROW, padding=5))
name_box.add(name_label)
name_box.add(self.name_input)


And primary name_box is a box like a box; However, this time, it is a ROW box. This means that the content will be added horizontally and will try to make it as narrow as possible. The box also has some inner margins - 5px on all sides.

Now let's define a button:

button = toga.Button(
    'Say Hello!',
    on_press=self.say_hello,
    style=Pack(padding=5)
)


All edges of the button are also filled with 5px. We also define a handler - a method called when a button is pressed.

Then we add the name box and button to the main box:

main_box.add(name_box)
main_box.add(button)


This completes our layout; The rest of the startup method is the same as before - define a MainWindow and specify the main box as the content of the window:

self.main_window = toga.MainWindow(title=self.formal_name)
self.main_window.content = main_box
self.main_window.show()


The last thing we need to do is define the handler for the button. The handler can be any method, generator, or asynchronous coroutine; It takes the widget that generated the event as a parameter and calls when the button is pressed:

def say_hello(self, widget):
    print("Hello, ", self.name_input.value)


The body of this method is a simple print statement - however, it asks for the current value of the name input and uses that content as printed text.

Now that we have made these changes, we can see how they look by launching the application again. As before, we will use the developer mode:

Apple system

(beeware-venv) $ briefcase dev

[helloworld] Starting in dev mode...

Linux

(beeware-venv) $ briefcase dev

[helloworld] Starting in dev mode...

window

(beeware-venv) C:\...>briefcase dev

[helloworld] Starting in dev mode...


You'll notice that this time, it doesn't have dependencies installed. Briefcase can detect that the application has been run before, and only the application will be run to save time- d if you add new dependencies to your application, you can ensure that they are installed by passing in an option at run time. briefcase dev

This should open a GUI window:

Apple system

 

Linux

window

 


Hello World tutorial 2 window on macOS
If you enter a name in the text box and then press the GUI button, you should see the output in the console that launches the application.

 

next step
We now have an application that can do something more interesting. But it only runs on our own computers. Let's package the application for distribution. In tutorial 3, we will package our application into a separate installer, which we can send to friends, customers or upload to the App Store.

Topics: Python Back-end