Salam untuk semuanya! Begitu asap dari diskusi yang memanas dalam komentar di artikel saya,
Kivy adalah kerangka kerja keledai untuk pengembangan lintas-platform No. 1 , dan di antara yang lain
komentar yang patut diperhatikan , kami (
Mirimon ,
SeOd ) berpikir akan menarik bagi kami dan pembaca untuk membandingkan Kivy, Xamarin.Bentuk dan Bereaksi Asli, menulis aplikasi yang sama pada mereka, menemaninya dengan artikel yang sesuai tentang Habré,
lobak pada GitHub dan dengan jujur memberi tahu Anda siapa yang menghadapi kesulitan apa selama implementasi. Setelah berkumpul di Telegram dan mendiskusikan detailnya, kami mulai bekerja.
Untuk perbandingan ini, kami memutuskan untuk menulis penjadwal tugas sederhana dengan tiga layar. Untuk memotong keadaan ketiga platform ini saat ini, menggunakan contoh sesuatu yang lebih produktif daripada contoh yang kami pilih, karena semua orang sibuk dalam proyek mereka / di tempat kerja / di rumah, terlalu lama. Terlepas dari kesederhanaan aplikasi kami, ini akan memungkinkan Anda untuk dengan jelas menunjukkan prinsip-prinsip pengembangan aplikasi di setiap lingkungan, bekerja dengan data, UI, dll.
Tiga kerangka kerja - satu percobaan. Xamarin. Bentuk. Bagian 2Tiga kerangka kerja - satu percobaan. Bereaksi Asli. Bagian 3Artikel ini adalah yang pertama dalam siklus, jadi saya ingin memulai dengan ToR, yang kami buat sketsa untuk diri kami sendiri, sehingga hasilnya sama.
Opsi TK:
- Catatan harus disusun oleh proyek.
- Catatan dapat ditambahkan oleh orang yang berbeda, sehingga penulis catatan harus ditunjukkan
- Catatan di dalam proyek harus ditambahkan / dihapus / diedit.
- Catatan harus berukuran konten, tetapi tidak lebih dari 150 piksel
- Menghapus catatan harus melalui menu konteks catatan itu sendiri dan melalui gesek
Contoh UI akan terlihat seperti ini:

Sebelum Anda mulai, sedikit bantuan pada Kivy:Kivy adalah kerangka kerja grafis lintas platform yang ditulis dalam bahasa pemrograman Python / Cython, berdasarkan OpenGL ES 2, yang bertujuan untuk menciptakan antarmuka pengguna modern, lebih fokus untuk bekerja dengan perangkat sentuh. Aplikasi Kivy berjalan pada platform seperti Linux, OS X, Windows, Android, iOS, dan Rapberry Pi. Dalam pengembangan, Anda memiliki akses ke berbagai pustaka Python mulai dari Permintaan hingga NumPy dan OpenCV. Kivy memiliki akses ke hampir semua API seluler asli (GPS, Kamera, Akselerometer, Google API untuk Android), melalui PyJNIus (Android) dan PyOBJus (iOS), yang secara otomatis membungkus kode Java / Objective-C dengan Python .
Kivy cepat. Ini berlaku untuk pengembangan aplikasi dan kecepatan eksekusi aplikasi. Semua fungsi kritis diimplementasikan pada level C. Kivy juga menggunakan GPU di mana pun itu masuk akal. GPU melakukan sebagian besar pekerjaan, sangat meningkatkan kinerja.
Kivy sangat fleksibel. Ini berarti bahwa pengembangan Kivy yang serba cepat memungkinkan Anda untuk langsung beradaptasi dengan teknologi baru. Pengembang Kivy telah berulang kali menambahkan dukungan untuk perangkat eksternal dan protokol perangkat lunak baru, kadang-kadang bahkan sebelum dirilis. Kivy dapat digunakan bersama dengan banyak solusi pihak ketiga yang berbeda. Misalnya, pada Windows, Kivy mendukung WM_TOUCH, yang berarti perangkat apa pun dengan driver Windows 7 Pen & Touch akan berfungsi dengan Kivy. Pada OS X, Anda dapat menggunakan perangkat Apple dengan dukungan Multi-Touch, seperti trackpad dan mouse. Di Linux, Anda dapat menggunakan acara input input HID. Selain itu, Kivy mendukung TUIO (Objek Antarmuka Pengguna Berwujud) dan sejumlah sumber input lainnya.
Anda dapat menulis aplikasi sederhana dengan beberapa baris kode. Program Kivy dibuat menggunakan bahasa pemrograman Python, yang sangat fleksibel dan kuat, tetapi mudah digunakan. Selain itu, pengembang Kivy telah membuat bahasa markah GUI mereka sendiri untuk membuat GUI khusus yang canggih. Bahasa ini memungkinkan Anda untuk dengan cepat mengkonfigurasi, menghubungkan, dan mengatur elemen-elemen aplikasi.
Dan, ya, Kivy benar-benar gratis. Anda bisa menggunakannya di mana saja! Dalam produk komersial atau dalam Sumber Terbuka. Saya akan memberikan semua kode aplikasi dan menunjukkan dengan cukup detail bagaimana elemen-elemen ini atau elemen-elemen tersebut diimplementasikan ketika berkembang untuk platform mobile. Sebagai IDE, saya selalu menggunakan
PyCharm , yang secara sempurna mendukung sintaks
Bahasa Kv - bahasa DSL khusus tempat representasi UI aplikasi Anda ditulis. Kerangka aplikasi dibuat menggunakan utilitas konsol
CreatorKivyProject , yang menyediakan layar dasar menggunakan templat MVVM.
Folder
baseclass berisi logika widget dan kontrol yang diterapkan dalam bahasa pemrograman Python, dalam file deskripsi antarmuka
kv dalam
Bahasa Kv . Direktori
applibs digunakan untuk perpustakaan pihak ketiga, di folder
data ada konten media, database, dan data lainnya. File
main.py adalah titik masuk aplikasi. Dia tidak melakukan apa-apa selain meluncurkan UI
TodoList (). Jalankan () render, tangkap kesalahan jika terjadi dan tampilkan jendela untuk mengirim laporan bug, yang dibuat secara otomatis oleh utilitas
CreatorKivyProject , tidak ada hubungannya dengan menulis aplikasi kita, dan karenanya tidak dipertimbangkan.
File
todolist.py dengan kode program mengimplementasikan kelas
TodoList , yang memuat tata letak antarmuka, menginisialisasi
instansnya , memantau kejadian tombol keras perangkat dan mengembalikan layar pertama kami, yang tercantum dalam Manajer aktivitas. Setelah
TodoList (). Run () , fungsi
build dipanggil dan mengembalikan widget yang akan ditampilkan di layar.
Misalnya, kode untuk program sederhana yang menampilkan satu layar dengan gambar akan terlihat seperti ini:
Dan inilah diagram kelas aplikasi kita:
Aplikasi kami hanya terdiri dari tiga
Kegiatan , manajer layar (
ScreenMenager ), yang kami kembalikan ke fungsi
pembuatan , bertanggung jawab untuk
beralih :
#:import ListProjectsActivity libs.uix.baseclass.ListProjectsActivity.ListProjectsActivity #:import ListNotesActivity libs.uix.baseclass.ListNotesActivity.ListNotesActivity #:import AddNewNoteActivity libs.uix.baseclass.AddNewNoteActivity.AddNewNoteActivity #:import ActivityManager libs.uix.baseclass.ActivityManager.ActivityManager <RootScreen@BoxLayout>: orientation: 'vertical' spacing: dp(2) ActivityManager: id: activityManager ListProjectsActivity: id: listProjectsActivity ListNotesActivity: id: listNotesActivity AddNewNoteActivity: id: addNewNoteActivity
Saat aplikasi dimulai, Activity yang ditentukan dalam ActivityManager akan diinstal terlebih dahulu. Dalam kasus kami, ini adalah
ListProjectsActivity . Dalam aplikasi untuk daftar proyek dan tugas, saya menggunakan
ScrollView . Meskipun itu lebih benar -
RecycleView . Karena yang pertama, jika ada lebih dari seratus pos dan proyek, tidak dapat melakukannya. Lebih tepatnya, akan sangat lama untuk membuat daftar.
RecycleView memungkinkan
Anda untuk menampilkan daftar panjang apa pun hampir secara instan. Tetapi karena bagaimanapun juga, dengan daftar besar, Anda harus menggunakan pemuatan data dinamis ke dalam daftar atau pagination, tetapi ini tidak dibahas dalam TOR, saya menggunakan
ScrollView . Alasan kedua adalah bahwa saya terlalu malas untuk mengulang daftar di bawah
RecycleView (dan pada
dasarnya berbeda dalam penggunaannya dari
ScrollView ), dan tidak ada banyak waktu, karena seluruh aplikasi ditulis dalam empat jam dalam penghentian asap dan coffee break.
Layar mulai dengan daftar proyek (ListProjectsActivity.kv dan ListProjectsActivity.py) terlihat seperti ini:
Karena tata letak layar ListProjectsActivity sudah ditampilkan di layar, saya akan menunjukkan bagaimana kelas kontrolnya terlihat:
# -*- coding: utf-8 -*- from kivy.app import App from kivy.uix.screenmanager import Screen as Activity from libs.uix.baseclass.InputDialog import InputDialog from . ProjectItem import ProjectItem class ListProjectsActivity(Activity): objApp = App.get_running_app() def setListProjects(self, objApp): for nameProject in objApp.dataProjects.keys(): self.ids.layoutContainer.add_widget(ProjectItem(projectName=nameProject)) def createNewProject(self, projectName): if projectName and not projectName.isspace(): self.ids.layoutContainer.add_widget(ProjectItem(projectName=projectName)) self.objApp.addProjectInBase(projectName) def deleteProject(self, instance): for projectName in self.objApp.dataProjects: if instance.projectName == projectName: self.objApp.deleteProjectFromBase(projectName) break def showDialogCreateProject(self, *args): InputDialog( title=' ', hintText=' ', textButtonCancel='', textTuttonOk='', eventsCallback=self.createNewProject).show()
Panggilan kotak dialog:
Dalam karya ini, memanggil jendela dan membuat proyek baru akan terlihat seperti ini:
Saya tidak akan membahas pertanyaan tentang data aplikasi, karena data merupakan kamus reguler dari formulir
{"Name Project": [{"pathToAvatar": "", "nameDate": "", "nameAuthor": "", "textNote": ""}]}
dan yang disimpan dalam direktori
data sebagai file json sederhana.
Mari kita lihat apa item dengan nama proyek itu dan bagaimana cara menggunakan Kivy untuk menghapus item dari daftar dengan menggesek? Untuk melakukan ini, kita harus mewarisi perilaku widget dalam daftar dari kelas
SwipeBehavior dari perpustakaan
SwipeToDelete :
ProjectItemActivity.py from kivy.properties import StringProperty from kivy.uix.boxlayout import BoxLayout from libs.applibs.swipetodelete import SwipeBehavior class ProjectItemActivity(SwipeBehavior, BoxLayout): projectName = StringProperty() def on_touch_down(self, touch): if self.collide_point(touch.x, touch.y): self.move_to = self.x, self.y return super(ProjectItemActivity, self).on_touch_down(touch) def on_touch_move(self, touch): if self.collide_point(touch.x, touch.y): self.reduce_opacity() return super(ProjectItemActivity, self).on_touch_move(touch) def on_touch_up(self, touch): if self.collide_point(touch.x, touch.y): self.check_for_left() self.check_for_right() return super(ProjectItemActivity, self).on_touch_up(touch)
Dan deskripsi item proyek di markup Kv:
ProjectItemActivity.kv <ProjectItemActivity>: swipe_rectangle: self.x, self.y , self.width, self.height swipe_timeout: 1000000 swipe_distance: 1 event_after_swipe: app.listActivity.deleteProject OneLineListItem: text: root.projectName on_press: app.listActivity.setNotesProject(root.projectName)
Secara umum, setiap widget di Kivy memiliki metode
on_touch yang dapat digunakan untuk menangkap semua peristiwa yang terjadi di layar. Berikut adalah sebagian kecil dari daftar acara yang tersedia:
['double_tap_time', 'grab_state', 'is_double_tap', 'is_mouse_scrolling', 'is_touch', 'is_triple_tap', 'move', 'push', 'push_attrs', 'push_attrs_stack', 'scale_for_screen', 'time_end', 'time_start', 'time_update', 'triple_tap_time', 'ungrab', 'update_time_end']
Menerapkan menu konteks untuk Android ...
Di sini juga tidak ada masalah, karena ini hanya widget DropDown standar. Berkat fakta bahwa Anda dapat menyesuaikan semua widget dan kontrol di Kivy sebanyak yang Anda bayangkan, saya dengan mudah mendapatkan menu yang cantik. Di sebelah kiri adalah basis DropDown, di sebelah kanan adalah milikku:
Tata letak daftar menu konteks:
ContextMenuAndroidActivity.kv #:import MDSeparator libs.applibs.kivymd.card.MDSeparator #:import MenuItem libs.applibs.animdropdown.MenuItem <ContextMenuAndroidActivity>: MenuItem: text: '' menu: root on_press: root.tapOnItem(self.text) MDSeparator: MenuItem: text: '' menu: root on_press: root.tapOnItem(self.text)
Bagian perangkat lunak dari menu konteks:
ContextMenuAndroidActivity.kv from kivy.app import App from kivy.clock import Clock from libs.applibs.animdropdown import AnimMenuDropDown class ContextMenuAndroidActivity(AnimMenuDropDown): def tapOnItem(self, textItem): objApp = App.get_running_app() if textItem == '': objApp.listActivity.deletePost() else: objApp.activityManager.current = 'add new note activity' Clock.schedule_once(objApp.addNewNoteActivity.editNote, .5)
Selanjutnya, kita mengimpor tombol
MenuDropDown dari perpustakaan
animdropdown , berikan objek menu konteks kita sebagai parameter, dan setelah itu kita tambahkan tombol ini ke layar yang kita butuhkan. Dalam aplikasi kami, ini adalah tombol di sebelah kanan di kartu catatan:
Catatan Kartu Aktivitas Markup:
NoteActivity kelas
dasar :
from kivy.app import App from kivy.properties import StringProperty from kivy.uix.boxlayout import BoxLayout from libs.applibs.animdropdown import MenuButton from libs.applibs.swipetodelete import SwipeBehavior from . ContextMenu import ContextMenu class NoteActivity(SwipeBehavior, BoxLayout): nameDate = StringProperty() textNote = StringProperty() pathToAvatar = StringProperty() def __init__(self, **kwargs): super(NoteActivity, self).__init__(**kwargs) self.objApp = App.get_running_app() menuButton = MenuButton( dropdown_cls=ContextMenu, icon='dots-vertical', _on_dropdown_fnc=self.setCurrentPost) self.ids.titleBox.add_widget(menuButton) def setCurrentPost(self, *args): self.objApp.listNotesActivity.checkCurentPost = self
Implementasi perangkat lunak
ListNotesActivity :
Bagaimana cara mengatur aktivitas aplikasi? Untuk beralih dari satu Kegiatan ke Kegiatan lainnya, kami harus menunjukkan kepada pengelola layar nama Kegiatan baru:
class ListNotesActivity(Activity): ... def addNewNote(self, *args): self.objApp.activityManager.current = 'add new note activity'
... di mana
'tambah aktivitas catatan baru' adalah nama Kegiatan untuk menambahkan catatan baru.
Layar dan tata letak
aktivitas AddNewNoteActivity :
Kelas dasar:
from kivy.app import App from kivy.animation import Animation from kivy.uix.screenmanager import Screen as Activity from kivy.metrics import dp from libs.uix.baseclass.NoteActivity import NoteActivity class AddNewNoteActivity(Activity): objApp = None edit = False oldTextNote = '' def animationButton(self): self.objApp = App.get_running_app() self.ids.toolBar.title = self.objApp.listNotesActivity.ids.toolBar.title Animation(size=(dp(56), dp(56)), d=.5, t='in_out_cubic').start(self.ids.floatingButton) def addNewNotes(self, textNote): if self.edit: nameProject = self.ids.toolBar.title self.objApp.addEditNoteInBase(nameProject, textNote, self.oldTextNote) self.objApp.activityManager.backActivity('list notes activity', self.ids.floatingButton) self.objApp.listNotesActivity.checkCurentPost.textNote = textNote self.edit = False return self.objApp.listNotesActivity.ids.layoutContainer.add_widget( NoteActivity( textNote=textNote, nameDate='%s\n%s' % ( self.objApp.nameAuthor, self.objApp.getDate()), pathToAvatar='data/images/avatar.png')) self.objApp.addNoteInBase(self.ids.toolBar.title, textNote, 'data/images/avatar.png') def editNote(self, interval): self.edit = True self.ids.textInput.text = self.objApp.listNotesActivity.checkCurentPost.textNote self.oldTextNote = self.ids.textInput.text
Untuk menghidupkan tombol, saya menggunakan acara
on_enter , yang dimunculkan ketika Activity diinstal pada layar:
Di markup:
<AddNewNoteActivity> on_enter: root.animationButton()
Dalam kode Python:
class AddNewNoteActivity(Activity): def animationButton(self): Animation(size=(dp(56), dp(56)), d=.5, t='in_out_cubic').start(self.ids.floatingButton)
Tidak seperti Xamarin. Bentuknya, UI di Kivy akan terlihat sama di mana-mana. Jadi, jika Anda menulis aplikasi untuk dua platform (Android dan iOS), Anda harus mempertimbangkan ini saat menandai antarmuka dan menentukan properti untuk widget. Atau lakukan dua markup untuk dua platform (logikanya tidak berubah). Ini adalah nilai tambah, karena rendering dan acara UI tidak tergantung pada fitur platform, Anda tidak menggunakan API asli untuk mengontrol tindakan ini, yang memungkinkan aplikasi Anda dieksekusi tanpa rasa sakit di hampir semua platform. Semua gambar ditampilkan menggunakan panggilan OpenGL dan SDL2 asli pada GPU, yang memungkinkan Anda untuk dengan cepat menggambar menu, tombol, dan daya tarik lain dari antarmuka grafis termasuk grafik 2D dan 3D.
Aplikasi ini menggunakan Android UI MaterialDesign. Sebagai contoh, proyek terakhir saya memiliki antarmuka adaptif:
Berikut ini adalah demonstrasi kemungkinan dalam gaya Desain Material:
Seperti yang saya katakan, Kivy tidak menggunakan API asli untuk rendering UI, oleh karena itu memungkinkan Anda untuk meniru berbagai model perangkat dan platform menggunakan modul
layar . Cukup menjalankan proyek Anda dengan parameter yang diperlukan sehingga jendela aplikasi yang diuji terbuka di komputer seolah-olah sedang berjalan pada perangkat nyata. Kedengarannya aneh, tetapi karena Kivy abstrak dari platform dalam merender UI, ini menghilangkan kebutuhan akan emulator berat dan lambat untuk pengujian. Ini hanya berlaku untuk UI. Sebagai contoh, aplikasi pengujian yang dijelaskan dalam artikel ini diuji dengan parameter
-m layar: droid2, portrait, scale = .75 yang berkorespondensi dengan perangkat asli saya.
Daftar lengkap parameter modul layar: Apa yang bisa dikatakan sebagai kesimpulan? Apakah Kivy baik? Tidak diragukan lagi bagus! Jika Anda tahu bahasa pemrograman Python yang luar biasa, Anda dapat dengan mudah membuat aplikasi untuk platform seluler (dan tidak hanya) dengan kerangka kerja Kivy yang tidak kalah indah.
Keuntungan mengembangkan aplikasi menggunakan kerangka kerja Kivy:- Karena kita berhadapan dengan Python, kecepatan pengembangan aplikasi beberapa kali lebih cepat daripada kecepatan pengembangan dalam bahasa atau kerangka kerja pemrograman lainnya.
- Megaton pustaka Python siap pakai yang dapat Anda gunakan dalam proyek Anda: OpenCV, Django, Flask, NumPy, ffmpeg, sqlite3, lxml dan ribuan lainnya.
- Karena Kivy menggunakan OpenGL dan GPU untuk rendering grafik, serta widget dan kontrolnya sendiri, kecepatan rendering UI sangat tinggi dan Anda benar-benar terbebas dari sakit kepala, yang hadir dalam kerangka kerja lain yang perlu masuk ke bagian asli untuk mengimplementasikan beberapa bagian antarmuka.
- Anda hanya menggunakan yang asli di mana Anda memerlukan akses ke fitur platform tertentu yang tidak bisa ada dalam kerangka kerja lintas platform yang benar-benar: misalnya, akses ke geolokasi, akses ke kamera, teknologi BlueTooth ...
Menerapkan akses ke API Android asli untuk mendapatkan IMEI dan model perangkat menggunakan PyJnius:
def _get_model_android(): from jnius import autoclass Build = autoclass('android.os.Build') return str(Build.DEVICE) def _get_imei_android(): from jnius import autoclass Service = autoclass('org.renpy.android.PythonActivity').mActivity Context = autoclass('android.content.Context') TelephonyManager = Service.getSystemService(Context.TELEPHONY_SERVICE) return str(TelephonyManager.getDeviceId())
Misalnya, implementasi perangkat IMEI penerima asli di Jawa:
import android.content.Context; import android.telephony.TelephonyManager; public class GetImeiAndroid { public String getImeiAndroid() { TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); String IMEINumber = tm.getDeviceId(); return IMEINumber; } }
- Anda bisa menggunakan pustaka jar pihak ketiga di proyek Anda ketika datang ke Android.
- Anda benar-benar memiliki semua peristiwa yang terjadi di layar: sentuhan, multitouch, geser, meninju, dan acara lainnya tanpa pergi ke aslinya, jadi ini merupakan bagian integral dari Kivy.
Fitur Kivy di perangkat Touch:
Terlepas dari semua kelebihannya, Kivy memiliki beberapa kelemahan:- Kecepatan "mulai dingin", yaitu, peluncuran pertama aplikasi sejak saat semua perpustakaan dikerahkan, cukup lama. Yang berikutnya adalah biasa, tetapi lebih lama dari aslinya, tergantung pada beban prosesor perangkat seluler.
- Bekerja dengan daftar. Anda dapat menampilkan daftar dengan ukuran 100.000 item dalam setengah detik (misalnya, kartu pengguna, showcase, kutipan), tetapi dengan satu syarat - semua kartu harus sama tingginya. Jika Anda menampilkan daftar, misalnya, kutipan, dengan jumlah teks yang tidak diketahui sebelumnya, tetapi secara keseluruhan, maka pada satu waktu lebih dari sepuluh poin tidak dapat ditampilkan, karena ini akan memakan waktu sekitar 10-15 detik. Dalam hal ini, Anda harus memuat 10-15 item masing-masing saat menggulir daftar.
- Tidak mungkin menampilkan teks yang melebihi 6500 karakter (3,5 halaman teks yang dicetak) - kami mendapatkan layar hitam. Ini dipecahkan dengan memecah teks dan kemudian menempelkannya bersama, yang tampaknya masih berupa tongkat penyangga. Namun, tidak jelas kepada siapa akan terlintas dalam pikiran untuk menampilkan jumlah teks pada suatu waktu. Terutama ketika datang ke platform mobile.
→
Lebih banyak artikel tentang KivyMesin virtual (pos pertama dari ZenCODE) dari pengembang Kivy siap dan dikonfigurasi untuk membangun proyek untuk kedua cabang Python.