赞
踩
用 Python 编写安卓 APK ,简单几步搞定
beeware详解(一): 搭建环境
beeware教程: 二 静态部件类(上) + 写一个登录页面
BeeWare官方教程中文版
如果想使用Python语言编写图形界面程序,那么有不少的框架可以提供支持,比如Tkinter、Qt for Python、WxPython等。不过这些框架都是只能创建桌面图形界面程序,比如Windows、Linux和macOS。如果我们想要创建IOS或Android等平台的移动应用APP,它们就无能为力了。
那么Python能不能写移动应用APP呢?实际上是可以的。据了解,Kivy和BeeWare都宣称"一次编写,处处部署",基于这些个框架编写的图形界面程序,都能够打包为全平台的应用程序,比如:Windows、Linux、macOS、Android、IOS。
BeeWare官方文档
BeeWare是一个基于Python构建的跨平台应用开发框架。
根据BeeWare的文档说明,在Windows上使用,我们首先需要安装Git和WiX Toolset,根据给出的网址,下载安装即可。
一、安装依赖
(1)Windows电脑
(2)3.5至3.8版本的python
(3)git
(4)WIX工具集
(5)Pycharm(可选)
(1)windows电脑
(2)conda安装的python
CMD>conda env list
CMD>conda create -n python38 python=3.8
CMD>conda activate python38
CMD>conda deactivate
(3)git
git官网下载地址
安装位置D:\Program Files\Git。
(4)WIX工具集
WIX工具集官网地址
WIX工具集Github下载地址
安装位置C:\Program Files (x86)\WiX Toolset v3.11。
二、安装BeeWare
使用pip工具安装BeeWare
CMD>conda activate python38
CMD>pip install briefcase
CMD>pip install beeware
CMD>pip list
beeware主要的三部分:
(1)briefcase beeware的命令行工具-公文包
(2)toga beeware的GUI开发工具
(3)cricket beeware调试工具
BeeWare安装完成之后,我们就可以通过briefcase命令在命令行终端进行 BeeWare应用的管理,比如新建、运行、构建、打包等。
可以切换到其它文件目录创建新项目。
CMD>d:
CMD>cd BeewareProject
CMD>briefcase new
命令输入之后,会让我们输入「应用的正式名称」、「应用程序名称」、「域名」、「项目名称」等信息。
punctuation:标点符号 capitalization:用大写 underscores:下划线 一、Formal Name [Hello World]: demo-01正式名称 二、App Name [demo01]:应用名称 三、Bundle Identifier [com.example]:域 四、Project Name [demo-01]:项目名称 五、Description [My first application]:描述 六、Author [Jane Developer]:作者 七、Author Email [jane@example.com]:作者邮件地址 八、Application URL [https://example.com/demo01]:应用程序登陆页面的URL 九、What license do you want to use for this project code?许可证 Select one of the following: [1] BSD license [2] MIT license [3] Apache Software License [4] GNU General Public License v2 (GPLv2) [5] GNU General Public License v2 or later (GPLv2+) [6] GNU General Public License v3 (GPLv3) [7] GNU General Public License v3 or later (GPLv3+) [8] Proprietary [9] Other Project License [1]: 2 十、What GUI toolkit do you want to use for this project?GUI框架 Select one of the following: [1] Toga [2] PySide2 (does not support iOS/Android deployment) [3] PySide6 (does not support iOS/Android deployment) [4] PursuedPyBear (does not support iOS/Android deployment) [5] None GUI Framework [1]: 输入完成之后,BeeWare会开始创建应用,创建完成之后,会有如下提示: Generating a new application demo-01 Using existing template (sha 5ec6b6fbcef0686e22e0a13be0e57dbc303a36ec, updated Mon Feb 28 11:36:44 2022) Application demo-01 has been generated. To run your application, type: cd demo01 briefcase dev
以开发者模式运行应用程序。
同时目录下多出了一个与应用程序名称同名的目录:
我们的程序的主要代码都将在app.py里面编写,默认app.py文件内已经有一个demo代码,我们可以直接运行项目:
cd demo01
briefcase dev
在命令行输入上述命令,会生成一个如下图所示的窗口:
briefcase create windows
briefcase build windows
briefcase run windows
briefcase package windows
(1)创建应用的脚手架
cd demo01
briefcase create
运行命令,将会生成一些预配置文件,然后下载依赖的包。
完成之后,项目目录下会生成一个Windows的目录,如下图所示:
(2)构建应用
briefcase build
(3)运行构建的应用
briefcase run
(4)打包应用
briefcase package
打包完成后,./Windows目录下会生成一个.msi的二进制安装文件:
双击安装即可。
briefcase create android
briefcase build android
briefcase run android
briefcase package android
一、创建应用的安卓脚手架
cd demo01
briefcase create android
Downloading OpenJDK8U-jdk_x64_windows_hotspot_8u242b08.zip
Downloading sdk-tools-windows-4333796.zip
Downloading Python-3.8-Android-support.b3.zip
二、构建安卓应用
briefcase build android Downloading https://services.gradle.org/distributions/gradle-7.2-all.zip 安装到了下面的目录中 C:\Users\gift4zb2018\.gradle\wrapper\dists\gradle-7.2-all\260hg96vuh6ex27h9vo47iv4d\gradle-7.2\bin (1)Checking the license for package Android SDK Tools C:\Users\gift4zb2018\AppData\Local\BeeWare\briefcase\ Cache\tools\android_sdk\licenses (2)Install Android SDK Tools (revision: 26.1.1) C:\Users\gift4zb2018\AppData\Local\BeeWare\briefcase\ Cache\tools\android_sdk\tools (3)Installing Android SDK Build-Tools 30.0.2 C:\Users\gift4zb2018\AppData\Local\BeeWare\briefcase\ Cache\tools\android_sdk\build-tools\30.0.2 (4)Installing Android SDK Platform 33 C:\Users\gift4zb2018\AppData\Local\BeeWare\briefcase\ Cache\tools\android_sdk\platforms\android-33 Chaquopy: Installing for arm64-v8a Chaquopy: Installing for armeabi-v7a Chaquopy: Installing for x86_64
三、运行构建好的安卓应用
briefcase run android
Downloading the Android emulator and system image
在这里会让我们选择设备,
可以选择BeeWare提供的安卓虚拟机或者是在电脑上连接自己的手机,
在这里我们选择安卓虚拟机:
输入1
Emulator name [beePhone]:
四、打包安卓应用
briefcase package android
打包完成之后,
(1)可以在D:\BeewareProject\helloworld\build\
helloworld\android\gradle\app\build\outputs\apk\debug
找到打包好的.apk文件。
(2)可以在D:\BeewareProject\helloworld\dist
找到打包好的.aab文件
BeeWare提供了两种打包好的文件,一种是用于上架Google Play的.aab格式文件,一种是用于调试.apk文件。
①打包之后修改代码使用briefcase dev可使修改生效,若使用briefcase run修改无效。
②使用briefcase update为现存的应用程序包更新代码;
使用 briefcase build命令重新编译app,
使用briefcase run 命令运行升级后的app,
使用 briefcase package 命令重新打包app以便分发。
③若想一步更改代码,更新app,迅速重新运行你的app,使用briefcase run -u 命令。
④如果你修改了app代码并想快速打包,可以使用briefcase package -u命令。
⑤对大多数日常开发,briefcase dev命令更便捷。
在src/demo2目录中,看到 3 个文件:
(1)__init__.py
将目录demo02标记为可导入的Python模块。
它是一个空文件,用于告诉Python解释器该demo2目录定义了一个模块。
将模块demo02标记为一种特殊的模块(可执行模块)。
如果您尝试运行demo02模块,则该文件是Python将开始执行的位置。
from demo02.app import main
if __name__ == '__main__':
main().main_loop()
也就是说__main__.py从demo02应用程序中导入方法;
如果它作为入口点执行,则调用main()方法,并启动应用程序的主循环。
主循环是GUI应用程序监听用户输入(如鼠标点击和键盘按下)的方式。
#包含创建我们的应用程序窗口的逻辑
import toga
from toga.style import Pack
from toga.style.pack import COLUMN, ROW
class demo02(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 demo02()
代码含义如下:
# 一、首先导入toga小部件工具包 # 一些与样式相关的实用程序类和常量 import toga from toga.style import Pack from toga.style.pack import COLUMN, ROW # 二、然后定义一个类 # 每个Toga应用程序都有一个toga.App实例,代表应用程序的运行实体。 # 该应用程序最终可能会管理多个窗口; # 但对于简单的应用程序,将只有一个主窗口。 class demo02(toga.App): # 三、接下来定义一个startup()方法 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() # 四、最后定义一个main()方法 # 这就是创建应用程序实例的原因 # 此main()方法是由__main__.py导入和调用的方法。 def main(): return demo02()
三、接下来定义一个startup()方法
(1)启动方法做的第一件事是定义一个主框。
Toga的布局方案的行为类似于HTML,可以通过构建一组盒子来构建应用程序,每个盒子都包含其他盒子或实际的小部件。然后将样式应用于这些框以定义它们将如何使用可用的窗口空间。
在这个应用程序中,定义了一个盒子,但没有往里面放任何东西。
def startup(self):
main_box = toga.Box()
(2)定义一个主窗口
该实例toga.MainWindow将具有与应用程序名称匹配的标题。主窗口是Toga中一种特殊的窗口,它是一个与应用程序的生命周期密切相关的窗口。当主窗口关闭时,应用程序退出。主窗口也是具有应用程序菜单的窗口(如果您在像Windows这样的平台上,其中菜单栏是窗口的一部分)。
self.main_window = toga.MainWindow(title=self.formal_name)
(3)添加空框作为主窗口的内容,并指示应用程序显示窗口
self.main_window.content = main_box
self.main_window.show()
修改demo02类src/demo02/app.py,使它看起来像这样:
import toga from toga.style import Pack from toga.style.pack import COLUMN, ROW class demo02(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) def main(): return demo02()
一、应用一种样式创建一个主盒子
Toga的内置布局系统称为Pack,它的行为很像CSS。在HTML中,对象是div、span和其他DOM元素;在Toga中,它们是小部件和盒子,可以将样式分配给各个元素。
在当前情况下,表示这是一个COLUMN盒子,也就是说,它是一个会消耗所有可用宽度的盒子,并且会随着内容的添加而扩大其高度,但它会尽量短。
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))
在这里定义了一个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)
和主盒子一样是一个盒子;然而,这一次,它是一个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)
该方法的主体是一个简单的打印语句,但是,它将询问名称输入的当前值,并将该内容用作打印的文本。
软件首页toga
软件文档toga
Toga是一个Python原生的GUI工具包。
Toga是一项正在进行中的工作,可能无法在所有平台上保持一致。
# Widgets 'ActivityIndicator',显示一个圆形的loading提示符号 'Box',盒子 'Button',按钮 'Canvas',画布 'DetailedList',明细表 'Divider', 'Window', 'Widget', 'ImageView', 'Label', 'DatePicker', 'TimePicker', 'MultilineTextInput', 'NumberInput', 'OptionContainer', 'PasswordInput', 'ProgressBar', 'ScrollContainer', 'Selection', 'Slider', 'SplitContainer', 'Switch', 'Table', 'TextInput', 'Tree', 'WebView'
toga.Button(label, 按钮上的文字
id=None, 按钮ID标识
style=None, 按钮风格
on_press=None, 按钮回调
enabled=True, 是否激活
factory=None) 通常不用
Button可以被视作一个沙箱,支持add方法。
语法如下:
import toga
def my_callback(button):
# handle event
pass
button = toga.Button('Click me', on_press=my_callback)
举例如下:
import toga def button_handler(widget): print("hello") def build(app): box = toga.Box() button = toga.Button('Hello world',on_press=button_handler) button.style.padding = 50 button.style.flex = 1 box.add(button) return box def main(): return toga.App('First App', 'org.beeware.helloworld', startup=build) if __name__ == '__main__': main().main_loop()
一、设置了一个处理程序,它是一个包装行为,我们希望在按下按钮时激活它。处理程序只是一个函数。该函数将激活的小部件作为第一个参数;根据正在处理的事件类型,还可以提供其他参数。但是,在简单按下按钮的情况下,没有额外的参数。
def button_handler(widget):
print("hello")
二、当app被实例化时(在main()中,如下所述),Toga将创建一个带有菜单的窗口。我们需要提供一种方法,告诉Toga在窗口中显示什么内容。该方法可以命名为任何名称,它只需要接受一个app实例:
def build(app):
box = toga.Box()
button = toga.Button('Hello world',
on_press=button_handler)
button.style.padding = 50
button.style.flex = 1
box.add(button)
return box
(1)我们想在窗口上挂一个按钮。然而,除非我们想让按钮填满整个app窗口,否则我们不能只将按钮放入app窗口。相反,我们需要创建一个box,并将按钮放入box中。
box是一个对象,可以用来容纳多个小部件,并定义小部件周围的填充。因此,我们定义了一个box:
box = toga.Box()
(2)然后我们可以定义一个按钮。当我们创建按钮时,我们可以设置按钮文本,我们还可以设置按下按钮时要调用的行为,引用我们之前定义的处理程序:
button = toga.Button('Hello world',
on_press=button_handler)
(3)现在我们必须定义按钮在窗口中的显示方式。默认情况下,Toga使用名为Pack的样式算法,有点像“CSS-lite”。我们可以设置按钮的样式属性:
button.style.padding = 50
button.style.flex = 1
我们在这里所做的是说,按钮的所有侧面都有50个像素的填充。如果我们想在按钮顶部定义20像素的填充,我们可以定义padding_top=20,或者指定padding=(20,50,50,50)。
现在,我们将使按钮占据所有可用宽度:flex属性指定一个元素相对于其方向上的其他元素的大小。默认方向是行(水平),因为按钮是这里唯一的元素,它将占据整个宽度。
(4)下一步是将按钮添加到框中:
box.add(button)
按钮具有默认高度,由底层平台绘制按钮的方式定义。因此,这意味着我们将在app窗口中看到一个按钮,它可以延伸到屏幕的宽度,但周围有50个像素的空间。
现在我们已经设置好这个box,我们返回包含所有UI内容的外部框。此box将是应用程序主窗口的内容:
return box
三、最后,我们实例化应用程序本身。应用程序是表示可执行文件的高级容器。该应用程序有一个名称和唯一标识符。在注册任何特定于应用程序的系统资源时使用该标识符。按照惯例,标识符是一个“反向域名”。该应用程序还接受我们定义主窗口内容的方法。我们将这个创建过程包装到一个名为main()的方法中,该方法返回应用程序的一个新实例:
def main():
return toga.App('First App',
'org.beeware.helloworld',
startup=build)
四、然后,项目的入口点需要实例化该入口点并启动主应用程序循环。对main_loop()的调用是一个阻塞调用;在你退出主应用程序之前,它不会返回:
if __name__ == '__main__':
main().main_loop()
TextInput(id=None, style=None, factory=None, initial=None, placeholder=None, readonly=False, on_change=None, on_gain_focus=None, on_lose_focus=None, validators=None) id: 输入框ID标识 style: 输入框风格 factory: 通常不用 initial: 默认文字 placeholder: 提示文字 readonly: 是否采用只读 on_change: 回调,输入框中的文本更改时调用的方法 on_gain_focus: 回调,获得焦点时执行的函数 on_lose_focus: 回调,失去焦点时执行的函数 validators: 文本验证器,通常不用
大多数应用程序需要的不仅仅是页面上的一个按钮。让我们构建一个稍微复杂一点的例子——华氏温度到摄氏温度的转换器:
import toga from toga.style.pack import COLUMN, LEFT, RIGHT, ROW, Pack def build(app): c_box = toga.Box() f_box = toga.Box() box = toga.Box() c_input = toga.TextInput(readonly=True) f_input = toga.TextInput() c_label = toga.Label('Celsius', style=Pack(text_align=LEFT)) f_label = toga.Label('Fahrenheit', style=Pack(text_align=LEFT)) join_label = toga.Label('is equivalent to', style=Pack(text_align=RIGHT)) def calculate(widget): try: c_input.value = (float(f_input.value) - 32.0) * 5.0 / 9.0 except ValueError: c_input.value = '???' button = toga.Button('Calculate', on_press=calculate) f_box.add(f_input) f_box.add(f_label) c_box.add(join_label) c_box.add(c_input) c_box.add(c_label) box.add(f_box) box.add(c_box) box.add(button) box.style.update(direction=COLUMN, padding_top=10) f_box.style.update(direction=ROW, padding=5) c_box.style.update(direction=ROW, padding=5) c_input.style.update(flex=1) f_input.style.update(flex=1, padding_left=160) c_label.style.update(width=100, padding_left=10) f_label.style.update(width=100, padding_left=10) join_label.style.update(width=150, padding_right=10) button.style.update(padding=15, flex=1) return box def main(): return toga.App('Temperature Converter', 'org.beeware.f_to_c', startup=build) if __name__ == '__main__': main().main_loop()
这个例子展示了Toga的Pack风格引擎的更多功能。在这个示例应用程序中,我们设置了一个垂直堆叠的外盒;在那个盒子里,我们放了两个水平的盒子和一个按钮。
由于水平框上没有宽度样式,因此它们会尝试将包含的小部件放入可用空间。TextInput小部件的样式为flex=1,但标签小部件的宽度是固定的;因此,TextInput小部件将被拉伸以适应可用的水平空间。然后,边距和填充确保小部件垂直和水平对齐。
toga.Box(id=None, Box的唯一标识,str类型。
style=None, Box的风格。
children=None, Box中的组件。
factory=None) 通常不用。
Box.add支持添加多个组件。
例子
import toga
box = toga.Box('box1')
button = toga.Button('Hello world', on_press=button_handler)
box.add(button)
toga.Label(text,
id=None,
style=None,
factory=None)
text: 文本
id: 文本ID标识
style: 文本风格
factory: 通常不用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。