BeeWare 峰器 中文文档 - 教程 2 - 让它变得有趣

在教程 1中,我们生成了一个能够运行的存根项目,但我们自己没有编写任何代码。让我们看看为我们生成了什么。

产生了什么
在src/helloworld目录中,您应该看到 3 个文件__init__.py: __main__.py和app.py.

__init__.py将目录标记helloworld为可导入的 Python 模块。它是一个空文件;它存在的事实告诉 Python 解释器该helloworld目录定义了一个模块。

__main__.py将模块标记helloworld为一种特殊的模块 - 可执行模块。如果您尝试使用 运行helloworld模块 ,则该文件是 Python 将开始执行的位置。的内容比较简单:python -m helloworld__main__.py__main__.py

from helloworld.app import main

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


也就是说 - 它main从 helloworld 应用程序中导入方法;如果它作为入口点执行,则调用 main() 方法,并启动应用程序的主循环。主循环是 GUI 应用程序监听用户输入(如鼠标点击和键盘按下)的方式。

更有趣的文件是app.py- 它包含创建我们的应用程序窗口的逻辑:

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()


让我们逐行浏览:

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


首先,我们导入toga小部件工具包,以及一些与样式相关的实用程序类和常量。我们的代码还没有使用这些——但我们很快就会使用它们。

然后,我们定义一个类:

class HelloWorld(toga.App):


每个 Toga 应用程序都有一个toga.App实例,代表应用程序的运行实体。该应用程序最终可能会管理多个窗口;但对于简单的应用程序,将只有一个主窗口。

接下来,我们定义一个startup()方法:

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


启动方法做的第一件事是定义一个主框。Toga 的布局方案的行为类似于 HTML。您可以通过构建一组盒子来构建应用程序,每个盒子都包含其他盒子或实际的小部件。然后将样式应用于这些框以定义它们将如何使用可用窗口空间。

在这个应用程序中,我们定义了一个盒子,但我们没有往里面放任何东西。

接下来,我们定义一个窗口,我们可以将这个空框放入其中:

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


这将创建一个 a 的实例,该实例toga.MainWindow将具有与应用程序名称匹配的标题。主窗口是 Toga 中一种特殊的窗口——它是一个与应用程序的生命周期密切相关的窗口。当主窗口关闭时,应用程序退出。主窗口也是具有应用程序菜单的窗口(如果您在像 Windows 这样的平台上,其中菜单栏是窗口的一部分)

然后我们添加我们的空框作为主窗口的内容,并指示应用程序显示我们的窗口:

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


最后,我们定义了一个main()方法。这就是创建我们应用程序实例的原因:

def main():
    return HelloWorld()


此main()方法是由 导入和调用的方法 __main__.py。HelloWorld 它创建并返回我们应用程序的一个实例。

这是最简单的 Toga 应用程序。让我们把我们自己的一些内容放到应用程序中,让应用程序做一些有趣的事情。

添加一些我们自己的内容
在里面修改你的HelloWorld类src/helloworld/app.py,使它看起来像这样:

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)


笔记

不要删除文件顶部或main()底部的导入。您只需要更新HelloWorld类。

让我们详细看看发生了什么变化。

我们仍在创建一个主盒子;但是,我们现在正在应用一种样式:

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


Toga 的内置布局系统称为“Pack”。它的行为很像 CSS。您在层次结构中定义对象 - 在 HTML 中,对象是<div>、<span>和其他 DOM 元素;在 Toga 中,它们是小部件和盒子。然后,您可以将样式分配给各个元素。在这种情况下,我们表示这是一个COLUMN盒子——也就是说,它是一个会消耗所有可用宽度的盒子,并且会随着内容的添加而扩大其高度,但它会尽量短。

接下来,我们定义几个小部件:

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

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


在这里,我们定义了一个 Label 和一个 TextInput。两个小部件都有与之关联的样式;标签将在其左右两侧有 5px 的填充,并且在顶部和底部没有填充。TextInput 被标记为灵活的——也就是说,它将吸收其布局轴上的所有可用空间。

TextInput 被分配为类的实例变量。这使我们可以轻松访问小部件实例——我们稍后将使用它。

接下来,我们定义一个盒子来容纳这两个小部件:

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


和主name_box盒子一样是一个盒子;然而,这一次,它是一个 ROW盒子。这意味着内容将水平添加,并且会尝试使其宽度尽可能窄。盒子也有一些内边距——四面都是 5px。

现在我们定义一个按钮:

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


该按钮的所有边也有 5px 的填充。我们还定义了一个处理程序- 按下按钮时调用的方法。

然后,我们将名称框和按钮添加到主框:

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


这样就完成了我们的布局;启动方法的其余部分和以前一样 - 定义一个 MainWindow,并将主框指定为窗口的内容:

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)


该方法的主体是一个简单的打印语句 - 但是,它将询问名称输入的当前值,并将该内容用作打印的文本。

现在我们已经进行了这些更改,我们可以通过再次启动应用程序来查看它们的外观。和以前一样,我们将使用开发者模式:

苹果系统

(beeware-venv) $ briefcase dev

[helloworld] Starting in dev mode...

Linux

(beeware-venv) $ briefcase dev

[helloworld] Starting in dev mode...

视窗

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

[helloworld] Starting in dev mode...


您会注意到这一次,它没有安装依赖项。公文包可以检测到应用程序之前已经运行过,并且为了节省时间,只会运行该应用程序。-d如果您将新的依赖项添加到您的应用程序,您可以通过在运行时传入一个选项 来确保它们已安装。briefcase dev

这应该会打开一个 GUI 窗口:

苹果系统

macOS 上的 Hello World 教程 2 窗口

 

Linux

Hello World 教程 2 窗口,在 Linux 上

视窗

Hello World 教程 2 窗口,在 Windows 上

 


macOS 上的 Hello World 教程 2 窗口
如果您在文本框中输入名称,然后按 GUI 按钮,您应该会在启动应用程序的控制台中看到输出。

 

下一步
我们现在有一个应用程序可以做一些更有趣的事情。但它只在我们自己的电脑上运行。让我们打包这个应用程序以进行分发。在教程 3中,我们将把我们的应用程序打包成一个独立的安装程序,我们可以将它发送给朋友、客户或上传到 App Store。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值