Kivy. بناء حزم لالروبوت وليس السحر


في مقالة Python بالأمس حول تطوير الأجهزة المحمولة ، والتي تحدثت عن مكتبة KivyMD (مجموعة من الأدوات المصممة على غرار تصميم المواد للاستخدام في إطار عمل Kivy عبر الأنظمة الأساسية) ، طُلب مني في التعليقات التحدث عن عملية بناء الحزمة لنظام Android الأساسي. بالنسبة للكثيرين ، كانت هذه العملية ، للأسف ، ولا تزال سلسلة من الشامانية السحرية وليست شأنًا للمبتدئين. حسنًا ، دعنا نعرف ذلك ، كل شيء معقد حقًا وهل أنا حقًا ساحر ومعالج ...



بالطبع يستطيع! لذلك ، كتبت الكود في Python و Kivy. ما الذي يتطلبه الأمر لتشغيله على أجهزة Android؟ انتقل إلى مستودع KivyMD وسترى أن هذه التعليمات قد حددت منذ فترة طويلة الخطوات التي تسمح لك بجمع حزمة APK:

  1. تنزيل XUbuntu 18.04

تثبيت Virtual Box على جهاز الكمبيوتر الخاص بك.
أنشئ جهازًا افتراضيًا جديدًا استنادًا إلى صورة XUbuntu تم تنزيلها
قم ببدء تشغيل الجهاز الظاهري XUbuntu ، وافتح مطرافًا وقم بتشغيل الأمر التالي:

wget https://github.com/HeaTTheatR/KivyMD-data/raw/master/install-kivy-buildozer-dependencies.sh 

 chmod +x install-kivy-buildozer-dependencies.sh 

 ./install-kivy-buildozer-dependencies.sh 

هذا كل شئ! لديك الآن جهاز افتراضي لإنشاء حزم APK لتطبيقات Kivy! ما التالي؟ دعونا فعلا بناء تطبيق الاختبار. قم بإنشاء دليل TestKivyMD في الدليل الرئيسي للجهاز الظاهري باستخدام ملف main.py الفارغ:


بعد ذلك ، افتح ملف main.py واكتب رمز تطبيق الاختبار الذي سيستخدم مكتبة KivyMD:

 from kivy.lang import Builder from kivymd.app import MDApp KV = """ Screen: MDToolbar: title: "My firt app" elevation: 10 md_bg_color: app.theme_cls.primary_color left_action_items: [["menu", lambda x: x]] pos_hint: {"top": 1} MDRaisedButton: text: "Hello World" pos_hint: {"center_x": .5, "center_y": .5} """ class HelloWorld(MDApp): def build(self): return Builder.load_string(KV) HelloWorld().run() 

احفظ ، افتح المحطة في الدليل باستخدام ملف main.py وقم بتثبيت مكتبة KivyMD:

 sudo pip3 install kivymd 

بعد التثبيت ، يمكنك اختبار الرمز الخاص بنا:

 python3 main.py 

ستكون نتيجة البرنامج النصي عبارة عن شاشة بها شريط الأدوات وزر واحد "Hello World":


بعد ذلك ، نحتاج إلى إنشاء ملف مواصفات buildozer.spec ، والذي يجب أن يكون موجودًا في نفس الدليل مثل ملف main.py:


إذا لم تغلق المحطة (إذا كانت المحطة مغلقة ، فافتحها في دليل TestKivyMD) ، أدخل الأمر:

 buildozer init 

سيقوم هذا الأمر بإنشاء ملف مواصفات افتراضي. فتحه وتعديل:

 [app] # (str) Title of your application title = KivyMDTest # (str) Package name package.name = kivymd_test # (str) Package domain (needed for android/ios packaging) package.domain = com.heattheatr # (str) Source code where the main.py live source.dir = . # (list) Source files to include (let empty to include all the files) source.include_exts = py,png,jpg,jpeg,ttf # (list) Application version version = 0.0.1 # (list) Application requirements # comma separated eg requirements = sqlite3,kivy requirements = python3,kivy==1.11.1,kivymd # (str) Supported orientation (one of landscape, sensorLandscape, portrait or all) orientation = portrait # (bool) Indicate if the application should be fullscreen or not fullscreen = 1 # (list) Permissions android.permissions = INTERNET,WRITE_EXTERNAL_STORAGE # (int) Target Android API, should be as high as possible. android.api = 28 # (int) Minimum API your APK will support. android.minapi = 21 # (str) Android NDK version to use android.ndk = 17c # (bool) If True, then skip trying to update the Android sdk # This can be useful to avoid excess Internet downloads or save time # when an update is due and you just want to test/build your package android.skip_update = False # (bool) If True, then automatically accept SDK license # agreements. This is intended for automation only. If set to False, # the default, you will be shown the license when first running # buildozer. android.accept_sdk_license = True # (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64 android.arch = armeabi-v7a [buildozer] # (int) Log level (0 = error only, 1 = info, 2 = debug (with command output)) log_level = 2 # (int) Display warning if buildozer is run as root (0 = False, 1 = True) warn_on_root = 0 # (str) Path to build artifact storage, absolute or relative to spec file build_dir = ./.buildozer # (str) Path to build output (ie .apk, .ipa) storage bin_dir = ./bin 

كل شيء واضح هنا ، لذلك ، تعليقات إضافية ليست ضرورية. اقرأ بعناية المواصفات الافتراضية ، حيث يمكنك تحديد المسار إلى الأيقونة ، وميض عند تحميل التطبيق وأكثر من ذلك بكثير. تركت فقط ما نحتاج إليه الآن لبناء حزمة الاختبار الخاصة بنا. وفي الواقع ، نبدأ عملية الإنشاء باستخدام الأمر الموجود في الجهاز الطرفي:

 buildozer android debug 

يمكنك الذهاب بأمان إلى المطبخ وصنع القهوة ، لأن عملية تحميل وتجميع المكتبات ستستغرق وقتًا طويلاً للمرة الأولى. جميع التجميعات اللاحقة تستغرق 10-20 ثانية.

القهوة في حالة سكر وحان الوقت للنظر إلى المحطة:


فويلا! تم بناء تطبيقنا! حان الوقت لإفلاته على هاتفك الذكي وتشغيله:


كل شيء يعمل! وليس كل شيء معقد كما بدا.

سألوني أيضا:


لا يوجد لدى Flutter أو React Native أي مزايا مقارنة بلغة Kivy Language الترميزية ، والتي تتيح لك إنشاء ووضع تخطيطات وأدوات مصغّرة مباشرة. بالنسبة لي ، فإن الطريقة التي تم بها بناء واجهة المستخدم في Flutter هي تحريف حقيقي. فقط شخص مريض يمكن أن يفكر في هذا. لكي لا تكون بلا أساس ، دعنا ننظر إلى رمز Flutter ورمز Kivy الخاص بالتطبيق البسيط ... سيبدو كما يلي:


أدناه ، أعطي الرمز من المقال حول Flutter ، باختصار: الأساسيات :

 import 'package:flutter/widgets.dart'; main() => runApp( Directionality( textDirection: TextDirection.ltr, child: Container( color: Color(0xFFFFFFFF), child: App(), ), ), ); class App extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: GestureDetector( //     onTap: () { //    GestureDetector //    ,      print('You pressed me'); }, child: Container( //     decoration: BoxDecoration( //   shape: BoxShape.circle, //     color: Color(0xFF17A2B8), //      ), width: 80.0, height: 80.0, ), ), ); } } class Counter extends StatefulWidget { //      ,     , //   createState() @override State<Counter> createState() => _CounterState(); //        State, //   State<> } class _CounterState extends State<Counter> { //    -    , //      . //   ,     int counter = 0; //     ,       //   ,      Stateless . @override Widget build(BuildContext context) { //          , //     —  : return Center( child: GestureDetector( onTap: () { //  ,   ,    //  counter. setState(() { // setState()   ,    //      ,    ++counter; }); }, child: Container( decoration: BoxDecoration( shape: BoxShape.circle, color: Color(0xFF17A2B8), ), width: 80.0, child: Center( child: Text( //    counter '$counter', //      style: TextStyle(fontSize: 30.0), ), ), ), ), ); } } 

وهنا هو نفسه تمامًا ، ولكن باستخدام Kivy و KivyMD:

 from kivy.lang import Builder from kivymd.app import MDApp KV = """ #:import get_color_from_hex kivy.utils.get_color_from_hex Screen: MDCard: MDLabel: value: 0 text: str(self.value) halign: "center" on_touch_down: self.value += 1 canvas.before: Color: rgba: get_color_from_hex("#4eaabe") Ellipse: pos: self.center[0] - dp(25), self.center[1] - dp(25) size: dp(50), dp(50) """ class HelloWorld(MDApp): def build(self): return Builder.load_string(KV) HelloWorld().run() 

في رأيي ، الاستنتاج واضح ولا يحتاج إلى تعليقي ...

آمل أن يكون مفيدا لك. سأترك استطلاعًا حول موضوع "هل تمكنت من إنشاء تطبيق لنظام Android".

Source: https://habr.com/ru/post/ar479236/


All Articles