当前位置:   article > 正文

Python移动APP开发之Kivy(二)——第一个APP_python kivy

python kivy

目录

一、APP代码书写

(一)单独在py中构建

(二)结合kv构建

二、Kivy打包

(一)、大致概述

(二)、Kivy打包Android的方式

(三)、开始打包

(四)、buildozer.spec详解

三、结语


之前简要介绍了Python的移动app开发框架Kivy的核心成员及主要原理和应用。从本篇开始会不定期发布Kivy开发代码和原理讲解。

依照开发界的惯例,先来个简单的Hello world起个好头。

一、APP代码书写

首先创建一个main.py文件,至于为什么命名为main是因为打包的时候Kivy框架会以main.py文件为核心进行打包而不是其他命名的文件。

(一)单独在py中构建

如果想直接在py文件中完成全部代码构成可以按照如下方式写代码:

  1. from kivy.app import App # 引入App库,App库是Kivy开发的核心,必须引入
  2. from kivy.uix.button import Button # 引入Button(按钮)控件
  3. from kivy.uix.boxlayout import BoxLayout # 引入布局
  4. class IndexPage(BoxLayout): # 自定义根布局名称,并继承对应类型的布局
  5. def __init__(self, **kwargs):
  6. super().__init__(**kwargs)
  7. button = Button(text="Hello world") # 实例化Button控件,并修改text属性
  8. self.add_widget(button) # 通过add_widget函数将Button控件引入布局中
  9. class TestApp(App): # 单独构建App导入框架
  10. def build(self):
  11. return IndexPage() # 返回布局,相当于在软件中绘制布局及其中内容
  12. TestApp().run() # 运行软件

(二)结合kv构建

当然我们也可以把根布局下的所有控件写在单独的.kv文件中,首先 还是创建一个main.py文件。

这次与之前有所不同了,我们只需要在py文件中声明清楚根布局就可以了,其余的都可以在kv文件内完成。在py中的代码如下:

  1. from kivy.app import App
  2. from kivy.uix.button import Button
  3. from kivy.uix.boxlayout import BoxLayout
  4. class IndexPage(BoxLayout):
  5. def __init__(self, **kwargs):
  6. super().__init__(**kwargs)
  7. class TestApp(App):
  8. def build(self):
  9. return IndexPage()
  10. TestApp().run()

 接下来创建一个kv文件,注意kv文件的命名要与引入App的类本身的名称当中,App之前的字段相对应,但Kivy会自动小写化App之前的字段,如:以上代码中引入App库的类名称为TestApp,那么在命名kv文件的时候就要命名为test.kv。固我们需要创建一个test.kv文件,并在其中编写如下代码(注:Kivy本身具备kv语言,与Python有所不同但同样语法简单易懂):

  1. <IndexPage>:
  2. Button:
  3. text: 'Hello world'

注意:kv文件中要先确定父布局再在其下代码块中构建代码,其中根布局的声明较为特殊,如上代码中根布局名称为IndexPage便在kv文件中以<IndexPage>:的形式声明根布局,另外根布局的名称是由py文件中引入布局的类名称决定的,如:以上py文件中引入BoxLayout布局的类名称为IndexPage则在kv文件中声明根布局也必须是<IndexPage>否则Kivy无法找到对应的声明无法绘制出布局图形。py文件中不管引入什么布局,在kv文件中根布局的名称均由py文件中引入布局的类名称决定。

完成以上操作并运行就可以得到如图一个具备反馈按钮的窗口。

 到这里算是写完一个最基础的App啦,接下来就是在Andorid手机上运行啦。

二、Kivy打包

在手机上运行有很多种方式,其中最简单的就是在谷歌应用市场下载Kivy Luncher软件在手机上直接运行App,但是想想在国内还想访问国外网站除非有企业通道不然别想,想了也很危险,况且,如果你真的用Kivy做出了一个APP项目到了发布的时候不可让别人再下载一个单独的软件来运行你的项目对吧?所以呢,我们就得通过打包的方法将我们写的代码打包成一个独立的APP。

(一)、大致概述

通过Kivy,我们可以打包Python代码为Windows、Andoid、IOS的可执行文件。当然我主要是针对Android打包,如果想了解其他的可以去看看官方文档

(二)、Kivy打包Android的方式

Kivy打包Python代码主要有两种方式:通过Buildozer或者p4a(python-for-android),各有千秋,请自行决定,我这里主要是通过Buildozer完成打包,毕竟自动化环境搭建真的香。buildozer的虚拟机镜像已经给各位读者准备好啦(都是别人给搭建好的,咱拿来直接用,root密码:kivydev)

天翼云盘(不限速):https://cloud.189.cn/t/yqyQ3ueQBZVr (访问码:zbl4)

百度网盘:https://pan.baidu.com/s/1oycJ7Kn2NChq_5gSH8IXew?pwd=y5n9 提取码:y5n9

下载好后直接解压就行,点击001后缀进入之后解压.ova后缀文件就行。解压之后自行导入ova虚拟机镜像进入VirtualBox,不会的可以点击这里。VirtualBox不会安装的可以点击这里

(三)、开始打包

进入打包镜像,当然啦,第一步还是要挂载共享文件夹,如此可以更方便的将你写的Python代码移动到虚拟机镜像中。挂载不会的点击这里

在任意目录下创建一个项目打包文件夹,建议不要创建在系统自身的文件夹中(亲身试过,崩了QAQ)我是在/home/kivydev/下创建的PackFolder,同样,挂载文件也可以创建在这里。接下来,把通过共享文件夹分享过来的Python文件及kv文件复制进PackFolder。如图:

 打开终端,通过cd进入到PackFolder中,执行kdpp go(等同于buildozer android debug)进行打包(kdpp是一个API工具用于对buildozer指令的集成),通过该指令可以生成一个debug版本APP以及一个buildozer.spec文件,kdpp还有如下指令:

  1. kdpp clean # 清理打包环境,等同于buildozer android clean
  2. kdpp release # 执行打包命令,生成release版本APP等同于buildozer android release
  3. kdpp go # 执行打包命令,生成debug版本APP等同于buildozer android debug

debug版本与release版本的区别在于,debug会生成日志而release类似于发行版,虽然可以通过修改buildozer.spec文件来生成日志,后续会讲。

打包完成在Terminal会产生如图反馈:

通过kdpp生成了一个位于bin的apk文件,如图:

 然后就可以通过共享文件夹,将打包好的APK传送到Windows再传给手机就可以安装运行啦,效果如图:

(四)、buildozer.spec详解

通过kdpp go可以生成buildozer.spec文件,该文件是针对打包的一个集成声明文件,具体含义及其内容如下:

  1. [app]
  2. # (str) app应用名
  3. title = My Application
  4. # (str) 包名结尾
  5. package.name = myapp
  6. # (str) 包名开头,如果打包release apk必须把test改成其他任意字符串
  7. package.domain = org.test
  8. # (str) main.py所在目录,默认是spec所在目录
  9. source.dir = .
  10. # (list) 打包进apk的文件
  11. source.include_exts = py,png,jpg,kv,atlas
  12. # (list) 打包进apk的文件
  13. #source.include_patterns = assets/*,images/*.png
  14. # (list) 不打包进apk的文件
  15. #source.exclude_exts = spec
  16. # (list) 不打包进apk的目录,默认是tests和bin
  17. #source.exclude_dirs = tests, bin
  18. # (list) 不打包进apk的文件
  19. #source.exclude_patterns = license,images/*/*.jpg
  20. # (str) app版本
  21. version = 0.1
  22. # (str) Application versioning (method 2)
  23. # version.regex = __version__ = ['"](.*)['"]
  24. # version.filename = %(source.dir)s/main.py
  25. # (list) 通称 requirements,打包第三方库时必须添加到这里
  26. # comma separated e.g. requirements = sqlite3,kivy
  27. requirements = python3,kivy
  28. # (str) 第三方库源代码所在目录,如果指定了,打包时就会直接使用这个源代码,不会再去下载。
  29. # Sets custom source for any requirements with recipes
  30. # requirements.source.kivy = ../../kivy
  31. # (list) Garden requirements,如果你用到kivy.graden的库就需要添加到这里
  32. #garden_requirements =
  33. # (str) app启动时的画面图片(闪屏)路径,默认是kivy图标
  34. #presplash.filename = %(source.dir)s/data/presplash.png
  35. # (str) app图标路径
  36. #icon.filename = %(source.dir)s/data/icon.png
  37. # (str) app显示方向,默认是竖屏 (one of landscape, sensorLandscape, portrait or all)
  38. orientation = portrait
  39. # (list) service服务列表
  40. #services = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY
  41. #
  42. # OSX Specific
  43. #
  44. #
  45. # author = © Copyright Info
  46. # change the major version of python used by the app
  47. osx.python_version = 3
  48. # Kivy version to use
  49. osx.kivy_version = 1.9.1
  50. #
  51. # Android specific
  52. #
  53. # (bool) app是否全屏,默认否
  54. fullscreen = 0
  55. # (string) 闪屏的背景色
  56. # Supported formats are: #RRGGBB #AARRGGBB or one of the following names:
  57. # red, blue, green, black, white, gray, cyan, magenta, yellow, lightgray,
  58. # darkgray, grey, lightgrey, darkgrey, aqua, fuchsia, lime, maroon, navy,
  59. # olive, purple, silver, teal.
  60. #android.presplash_color = #FFFFFF
  61. # (list) Permissions app权限配置
  62. #android.permissions = INTERNET
  63. # (int) Target Android API, 目标api level
  64. android.api = 27
  65. # (int) Minimum API ,app能支持的最低api level
  66. android.minapi = 21
  67. # (int) Android SDK 版本
  68. #android.sdk = 27
  69. # (str) Android NDK 版本
  70. android.ndk = 19c
  71. # (int) Android NDK API to use. This is the minimum API your app will support, it should usually match android.minapi.
  72. android.ndk_api = 21
  73. # (bool) Use --private data storage (True) or --dir public storage (False)
  74. #android.private_storage = True
  75. # (str) Android NDK 路径
  76. android.ndk_path = /home/kivydev/andr/android-ndk-r19c
  77. # (str) Android SDK 路径
  78. android.sdk_path = /home/kivydev/andr/android-sdk-linux
  79. # (str) ANT directory 路径
  80. android.ant_path = /home/kivydev/andr/apache-ant-1.9.4
  81. # (bool) 是否跳过Android sdk 升级,默认否
  82. # android.skip_update = False
  83. # (bool) 升级sdk过程中会询问同意接受sdk license,默认是提示你选择,改为True则是默认同意接受
  84. # android.accept_sdk_license = False
  85. # (str) app 入口类,一般不修改
  86. #android.entrypoint = org.renpy.android.PythonActivity
  87. # (str) app主题类型,一般不修改
  88. # android.apptheme = "@android:style/Theme.NoTitleBar"
  89. # (list) 白名单
  90. #android.whitelist =
  91. # (str) 白名单文件路径
  92. #android.whitelist_src =
  93. # (str) 黑名单文件路径
  94. #android.blacklist_src =
  95. # (list) 自定义jar添加到这里,供jnius调用,支持通配符
  96. # OUYA-ODK/libs/*.jar
  97. #android.add_jars = foo.jar,bar.jar,path/to/more/*.jar
  98. # (list) 自定义java文件添加到这里
  99. #android.add_src =
  100. # (list) aar文件添加到这里
  101. #android.add_aars =
  102. # (list) Gradle dependencies to add (currently works only with sdl2_gradle
  103. # bootstrap)
  104. #android.gradle_dependencies =
  105. # (list) add java compile options
  106. # this can for example be necessary when importing certain java libraries using the 'android.gradle_dependencies' option
  107. # see https://developer.android.com/studio/write/java8-support for further information
  108. # android.add_compile_options = "sourceCompatibility = 1.8", "targetCompatibility = 1.8"
  109. # (list) Gradle repositories to add {can be necessary for some android.gradle_dependencies}
  110. # please enclose in double quotes
  111. # e.g. android.gradle_repositories = "maven { url 'https://kotlin.bintray.com/ktor' }"
  112. #android.add_gradle_repositories =
  113. # (list) packaging options to add
  114. # see https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html
  115. # can be necessary to solve conflicts in gradle_dependencies
  116. # please enclose in double quotes
  117. # e.g. android.add_packaging_options = "exclude 'META-INF/common.kotlin_module'", "exclude 'META-INF/*.kotlin_module'"
  118. #android.add_gradle_repositories =
  119. # (list) 增加java activity到manifest
  120. #android.add_activites = com.example.ExampleActivity
  121. # (str) OUYA Console category. Should be one of GAME or APP
  122. # If you leave this blank, OUYA support will not be enabled
  123. #android.ouya.category = GAME
  124. # (str) Filename of OUYA Console icon. It must be a 732x412 png image.
  125. #android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png
  126. # (str) XML file to include as an intent filters in <activity> tag
  127. #android.manifest.intent_filters =
  128. # (str) launchMode to set for the main activity
  129. #android.manifest.launch_mode = standard
  130. # (list) Android additional libraries to copy into libs/armeabi
  131. #android.add_libs_armeabi = libs/android/*.so
  132. #android.add_libs_armeabi_v7a = libs/android-v7/*.so
  133. #android.add_libs_arm64_v8a = libs/android-v8/*.so
  134. #android.add_libs_x86 = libs/android-x86/*.so
  135. #android.add_libs_mips = libs/android-mips/*.so
  136. # (bool) Indicate whether the screen should stay on
  137. # Don't forget to add the WAKE_LOCK permission if you set this to True
  138. #android.wakelock = False
  139. # (list) Android application meta-data to set (key=value format)
  140. #android.meta_data =
  141. # (list) Android library project to add (will be added in the
  142. # project.properties automatically.)
  143. #android.library_references =
  144. # (list) Android shared libraries which will be added to AndroidManifest.xml using <uses-library> tag
  145. #android.uses_library =
  146. # (str) Android logcat filters to use
  147. #android.logcat_filters = *:S python:D
  148. # (bool) Copy library instead of making a libpymodules.so
  149. #android.copy_libs = 1
  150. # (str) app架构,支持: armeabi-v7a, arm64-v8a, x86, x86_64
  151. android.arch = armeabi-v7a
  152. #
  153. # Python for android (p4a) specific
  154. #
  155. # (str) python-for-android fork to use, defaults to upstream (kivy)
  156. #p4a.fork = kivy
  157. # (str) 使用的p4a分支
  158. #p4a.branch = master
  159. # (str) p4a源代码路径,默认从网络下载
  160. #p4a.source_dir =
  161. # (str) recipes路径
  162. #p4a.local_recipes =
  163. # (str) Filename to the hook for p4a
  164. #p4a.hook =
  165. # (str) Bootstrap to use for android builds
  166. # p4a.bootstrap = sdl2
  167. # (int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask)
  168. #p4a.port =
  169. #
  170. # iOS specific
  171. #
  172. # (str) Path to a custom kivy-ios folder
  173. #ios.kivy_ios_dir = ../kivy-ios
  174. # Alternately, specify the URL and branch of a git checkout:
  175. ios.kivy_ios_url = https://github.com/kivy/kivy-ios
  176. ios.kivy_ios_branch = master
  177. # Another platform dependency: ios-deploy
  178. # Uncomment to use a custom checkout
  179. #ios.ios_deploy_dir = ../ios_deploy
  180. # Or specify URL and branch
  181. ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
  182. ios.ios_deploy_branch = 1.7.0
  183. # (str) Name of the certificate to use for signing the debug version
  184. # Get a list of available identities: buildozer ios list_identities
  185. #ios.codesign.debug = "iPhone Developer: <lastname> <firstname> (<hexstring>)"
  186. # (str) Name of the certificate to use for signing the release version
  187. #ios.codesign.release = %(ios.codesign.debug)s
  188. [buildozer]
  189. # (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
  190. log_level = 2
  191. # (int) Display warning if buildozer is run as root (0 = False, 1 = True)
  192. warn_on_root = 1
  193. # (str) .buildozer文件路径
  194. build_dir = /home/kivydev/test/.buildozer
  195. # (str) Path to build output (i.e. .apk, .ipa) storage
  196. # bin_dir = ./bin
  197. # -----------------------------------------------------------------------------
  198. # List as sections
  199. #
  200. # You can define all the "list" as [section:key].
  201. # Each line will be considered as a option to the list.
  202. # Let's take [app] / source.exclude_patterns.
  203. # Instead of doing:
  204. #
  205. #[app]
  206. #source.exclude_patterns = license,data/audio/*.wav,data/images/original/*
  207. #
  208. # This can be translated into:
  209. #
  210. #[app:source.exclude_patterns]
  211. #license
  212. #data/audio/*.wav
  213. #data/images/original/*
  214. #
  215. # -----------------------------------------------------------------------------
  216. # Profiles
  217. #
  218. # You can extend section / key with a profile
  219. # For example, you want to deploy a demo version of your application without
  220. # HD content. You could first change the title to add "(demo)" in the name
  221. # and extend the excluded directories to remove the HD content.
  222. #
  223. #[app@demo]
  224. #title = My Application (demo)
  225. #
  226. #[app:source.exclude_patterns@demo]
  227. #images/hd/*
  228. #
  229. # Then, invoke the command line with the "demo" profile:
  230. #
  231. #buildozer --profile demo android debug

三、结语

上面就是关于Python运用Kivy开发基础APP以及打包的全过程,后面大部分的教程中提到的Kivy构建的代码打包也可以参考这个打包方法,后期可能会针对打包过程及软件运行过程产生的问题及解决方法进行整合。

温馨提示:建议不要随便乱动镜像中的任何配置,会崩,崩了我也不会修,听镜像作者说当初搭建这玩意废了老大的劲儿,所以不要修改已有配置。

感谢大家的阅读,祝大家心想事成,步步高升哈!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/471514
推荐阅读
相关标签
  

闽ICP备14008679号