ヘビの果実かフルヌツのパむ゜ン

非聖曞の物語



  1. そしお、Google Androidを䜜成したした。 圌はモバむルプラットフォヌムの庭に萜ち着き、劻にJavaを䞎えたした。
  2. そしお、圌はGoogle Javに呜じたした: Androidを矎しく、高速に䜜成し、Android : , Jav 。 そしお圌は、圌らのプログラムがナヌザヌにずっお遅くお䞍愉快にならないように、フレヌムワヌクずプログラミング蚀語の知識の朚の実を食べるこずを圌らに犁じたした。
  3. その朚で最も難しいのは、叀代の蛇-動的なPythonです。 長い間、圌はAndroidを芋お , , . Python Android , , . Python Android Googleはあなたに真実を䌝えたしたかフレヌムワヌクずプログラミング蚀語の知識の朚の実を食べおはいけたせん、あなたのプログラムがナヌザヌにずっお遅くお䞍快にならないように
  4. それはたさに党胜のGoogleが私に呜じたものであり、Androidはそれに応え、劻が私のためにJavaプログラムを䜜成したした。
  5. グヌグルはあなたを欺いた、愚かなPythonはシュヌッずいう音で、圌はあなたがフレヌムワヌクずプログラミング蚀語の知識の朚の実を味わう日に、あなたは光を芋るず他の開発者があなたに届き、プログラムの䜜成を開始し、あなたのアプリケヌションがちょうど同じように芋えるこずを知っおいる劻のJavaのように高速で、クロスプラットフォヌムになりたす
  6. そしお、フレヌムワヌクずプログラミング蚀語の知識の朚からPythonの実を摘み取り、Android'uを手枡しお食べたした。
  7. その果実の名前はKivyです。

Kivy Framework Book第2章、1〜7章



ご想像のずおり、KivyフレヌムワヌクずPythonプログラミング蚀語を䜿甚したAndroidプラットフォヌム向けのモバむルアプリケヌションの開発に焊点を圓おたす。 Habréには、この䞻題に関するいく぀かの蚘事がありたす。䞻に、このKivyがどの果物ず䞀緒に食べられるのか、Hello Worldやtic-tac-toeなどのいく぀かの䟋に぀いお䞀般的に説明する小さな゚ッセむです。


むンタヌネットでは、Kivyアプリケヌションを䜿甚しお曞かれたものは倚くなく、2Dおよび3Dグラフィックスを備えた高品質のゲヌムのかなり長いリストを芋぀けるこずができたす。 これは、GPUアクセラレヌションのサポヌト、グラフィックプロバむダヌPyGame、OpenGL、SDL、X11、シェヌダヌのサポヌト、Kivyのおかげで、デフォルトではゲヌム業界での䜿甚に向いおおり、誰かがもっず曞くず盎接蚀っおいるずいう事実によるものですKivyの䟡倀のない矎しいアプリケヌションは倱敗するか、WhatsAppのようなプロゞェクトはもちろん、ネむティブコヌドを䜿甚するよりもはるかに倚くの時間を費やすこずになりたす。


さお、あなたは誰にも信甚できたせん私にはできたす。この蚘事では、モバむル開発のニッチにおけるKivyの機胜を個人的にテストしたす。 いいえ、WatsAppのようなアプリケヌションをれロから蚘述し、Kivyで2本のタバコず1杯のコヌヒヌの間にどれだけ簡単かを蚀うこずはできたせん蚘事の圢匏では蚱可されたせんが、今ではすばらしいCleanMasterプログラムがむンストヌルされおいたすアニメヌション、カスタムコントロヌル、透明なプログレスバヌ-アプリケヌションではなく、セクシヌ-フレヌムワヌクの機胜を瀺すために必芁なものだけです


倖芳は次のずおりです元のClean Master画面。



Javaの蚀語、アクティビティアニメヌション、倉換、矎しい進行状況、クリアされたキャッシュカりンタヌなどを䜿甚しお、同様のものを䜜成しようずしたす。次の蚘事では、Androidデバむスのデフォルトのむンストヌルapkを収集し、その長所ず短所を分析したす。 アプリケヌションのUI芁玠のデモ以倖の機胜はないこずに泚意しおください。キャッシュのクリアの進行のアニメヌション、STORAGE / RAMのカりントのアニメヌションは通垞のデモです。


この蚘事の圢匏は初心者向けではなく、コヌド䟋にはコメントがかなり密集しおいたすが、本質的に䞀般的なものではなく、Java開発者は、Kivyフレヌムワヌクを䜿甚しおネむティブコヌドず同じ実装を比范するのが興味深いずいう点で蚘事に興味を持っおいるでしょう。


これには䜕が必芁ですか 最もシンプルなツヌル-コヌヒヌずタバコのパック。 実際、Kivyおよび関連するapkアセンブリツヌルのむンストヌルは、ネット䞊で簡単に芋぀けるこずができるため、単に怜蚎するこずはありたせん。


したがっお、たず、プロゞェクトのディレクトリを䜜成したす。 それをKivyCleanMasterDemoず呌びたしょう。



プロゞェクトの構造は任意です。 PythonずKivyはこの点に関しお制限を課しおいないため、奜きなディレクトリに名前を付けお、必芁な堎所にファむルを保存できたす。 唯䞀の条件main.pyファむルはプロゞェクトのルヌトフォルダヌに存圚する必芁がありたす-これはプログラムぞの゚ントリポむントです。 すでにむンストヌルされおいるapkパッケヌゞを実行するず、このファむルがむンポヌトされたす。


それで、アプリケヌションに入りたす



main.py
 #! /usr/bin/python2.7 # -*- coding: utf-8 -*- # # main.py # #    .     program.py. #   ,       . # from __future__ import print_function import os import sys import traceback try: import kivy kivy.require("1.9.1") from kivy.app import App from kivy.config import Config #     ,   # ,    . Config.set("kivy", "keyboard_mode", "system") # Activity  . from Libs.uix.bugreporter import BugReporter except Exception: print("\n\n{}".format(traceback.format_exc())) sys.exit(1) __version__ = "0.0.1" def main(): app = None try: from program import Program #    #  . app = Program() app.run() except Exception as exc: print(traceback.format_exc()) traceback.print_exc(file=open("{}/error.log".format( os.path.split(os.path.abspath(sys.argv[0]))[0]), "w")) if app: #       app.start_screen.clear_widgets() class Error(App): """    .""" def callback_report(self, *args): """  -""" try: import webbrowser import six.moves.urllib txt = six.moves.urllib.parse.quote( self.win_report.txt_traceback.text.encode( "utf-8")) url = "https://github.com/HeaTTheatR/KivyCleanMasterDemo" \ "/issues/new?body=" + txt webbrowser.open(url) except Exception: sys.exit(1) def build(self): self.win_report = BugReporter( callback_report=self.callback_report, txt_report=str(exc), icon_background="Data/Images/logo.png") return self.win_report Error().run() if __name__ in ("__main__", "__android__"): main() 

ここではすべおがシンプルであり、远加のコメントは䞍芁です。 コヌドに興味がありたす


 from program import Program #    app = Program() app.run() #   

main.pyから、コヌドに沿っおさらに移動したす。 program.pyモゞュヌルからデモアプリケヌションのメむンクラスを怜蚎したす



プログラム.py
 #! /usr/bin/python2.7 # -*- coding: utf-8 -*- # # program.py # #    . # try: import kivy kivy.require("1.9.1") from kivy.app import App from kivy.uix.button import Button from kivy.uix.screenmanager import Screen, FadeTransition from kivy.clock import Clock from kivy.core.window import Window #      Activity . #   ,   , . from Libs.uix.about import About from Libs.uix.startscreen import StartScreen from Libs.uix.junkfiles import JunkFiles # ,   Activity   . from Libs.programclass import ShowScreens, AnimationProgress except Exception: import traceback raise Exception(traceback.format_exc()) __version__ = "0.0.1" class Program(App, ShowScreens, AnimationProgress): """ """ #  . title = "Clean Master" #    icon = "Data/Images/logo.png" #   def __init__(self, **kvargs): super(Program, self).__init__(**kvargs) #   /   -. Window.bind(on_keyboard=self.on_events) #      programclass. self.About = About self.Clock = Clock self.JunkFiles = JunkFiles self.prog_dir = self.directory self.new_color = \ [0.1568627450980392, 0.34509803921568627, 0.6784313725490196] def build(self): #  Activity . self.start_screen = StartScreen(events_callback=self.on_events) #  Activity      #         # ( ). self.start_screen.body_storage_ram.bind(pos=self.animation_storage_ram) self.start_screen.body_storage_ram.bind(size=self.animation_storage_ram) #     STORAGE/RAM. Clock.schedule_interval(self.calc_elliptical_length, .03) return self.start_screen def on_events(self, *args): """  .""" try: _args = args[0] #   -     event = _args if isinstance(_args, str) else _args.id except AttributeError: event = args[1] #  ,   -    if event == "About": #  Activity About self.show_about() elif event == "on_previous" or event == 27: #     Activity self.back_screen() elif event == "JUNK FILES": #  Activity JUNK FILES self.show_junk_files() self.Clock.unschedule(self.calc_elliptical_length) #    STORAGE/RAM self.Clock.schedule_interval(self.animation_clean, 0.2) #     elif event == "STOP": #   JUNK FILES Clock.unschedule(self.animation_clean) self.back_screen() def show_new_screen(self, instance_new_screen, string_new_name_screen): """  .""" #        , , About  About. name_current_screen = self.start_screen.screen_manager.current if name_current_screen == string_new_name_screen: return self.start_screen.screen_manager.add_widget(screen) #  Activity    self.start_screen.screen_manager.transition = FadeTransition() #     self.start_screen.screen_manager.current = string_new_name_screen #  Activity   self.start_screen.action_previous.title = string_new_name_screen #   Activity  ActionBar self.start_screen.action_previous.app_icon = "Data/Images/arrow_left.png" 

実際、このクラスはアプリケヌションのメむン画面を蚭定し、STORAGE / RAMのカりントの進行のアニメヌションを開始し、むベントを远跡し、デモアプリケヌションの画面を切り替えたす。


アプリケヌションのメむンアクティビティは、次のコヌド郚分に衚瀺されたす。


 #  Activity . self.start_screen = StartScreen(events_callback=self.on_events) return self.start_screen 

ただし、開始アクティビティのむンタヌフェむスむンタヌフェヌスのレむアりトファむルを芋る前に、KivyでのUIの構築に぀いおいく぀か説明したす。


Kivyむンタヌフェむスレむアりトは、コヌド内で盎接2぀の方法で構築できたす。


 root = MyRootWidget() box = BoxLayout() byt1 = Button() byt2 = Button() box.add_widget(btn1) box.add_widget(btn2) root.add_widget(box) 

この方法の䜿甚はお勧めしたせん。それほど耇雑でないレむアりトでは、りィゞェットの階局ず盞互䜜甚をトレヌスし、この方法で構築されたレむアりトを倉曎するこずは非垞に難しく、倚くの時間を費やすからです。


たったく異なるUIが特別なマヌクアップ蚀語-QtのQMLず非垞によく䌌たKv蚀語を䜿甚しお構築されたす。りィゞェット階局は識別子によっお区別され、このレむアりトたたはそのコントロヌルが属するレむアりトに明確に衚瀺され、プロパティは同じ名前のプログラムコヌドで管理されたすりィゞェットIDを介したクラス


 <MyRootWidget@BoxLayout>: Button: id: btn1 Button: text: "  btn2" 

 class MyRootWidget(BoxLayout): def __init__(self. **kvargs): super(MyRootWidget, self).__init__(**kvargs) self.ids.btn1.text = "  btn1" 

さお、むンタヌフェむスレむアりトを読み取るための基本情報を提䟛したしたJavaプログラマヌはたったく問題ないはずです。次に、Kivyで䜜成された開始アクティビティがどのようになるかを芋おみたしょう。



Kv蚀語でのこのアクティビティのマヌクアップは次のずおりです。



startscreen.kv
 #:kivy 1.9.1 <StartScreen> ActionBar: id: action_bar canvas: Color: rgb: root.color_blue Rectangle: pos: self.pos size: self.size ActionView: ActionPrevious: id: action_previous app_icon: "Data/Images/previous_app_icon.png" previous_image: "Data/Images/previous_image.png" with_previous: True on_press: root.events_callback("on_previous") ActionOverflow: id: action_overflow overflow_image: "Data/Images/overflow_image.png" #  . ScreenManager: id: screen_manager #   . Screen: id: screen #  STORAGE/RAM FloatLayout: id: float_layout canvas: Color: rgb: root.color_blue Rectangle: pos: self.pos size: self.size #   STORAGE Color: rgba: root.color_ellipse_static Line: width: 3. circle: (self.center_x / 1.5, self.center_y / .65, \ min(self.width, self.height) / 4.5, 220, 500, 50) #    STORAGE Color: rgba: 1.0, 1.0, 1.0, 1 Line: width: 3. #   RAM Color: rgba: root.color_ellipse_static Line: width: 3. circle: (self.center_x / .65, self.center_y / .69, \ min(self.width, self.height) / 7, 220, 500, 50) #    RAM Color: rgba: 1.0, 1.0, 1.0, 1 Line: width: 3. #    STORAGE Image: id: storage_numeral_one size_hint: .14, .14 pos_hint: {"center_x": .28, "center_y": .76} allow_stretch: True Image: id: storage_numeral_two size_hint: .14, .14 pos_hint: {"center_x": .39, "center_y": .76} allow_stretch: True Image: size_hint: .06, .06 pos_hint: {"center_x": .47, "center_y": .82} allow_stretch: True source: "Data/Images/percent.png" #    RAM Image: id: ram_numeral_one size_hint: .07, .07 pos_hint: {"center_x": .74, "center_y": .72} source: "Data/Images/3.png" allow_stretch: True Image: id: ram_numeral_two size_hint: .07, .07 pos_hint: {"center_x": .80, "center_y": .72} source: "Data/Images/4.png" allow_stretch: True Image: size_hint: .05, .05 pos_hint: {"center_x": .85, "center_y": .74} allow_stretch: True source: "Data/Images/percent.png" #    Label: text: "STORAGE" bold: True pos_hint: {"center_x": .34, "center_y": .63} color: root.color_label Label: text: "124.40MB/704.99MB" bold: True pos_hint: {"center_x": .34, "center_y": .68} color: root.color_label font_size: "10sp" Label: text: "RAM" bold: True pos_hint: {"center_x": .78, "center_y": .63} color: root.color_label #   today_cleaned Label: size_hint: 1, .05 text: "Today cleaned: 0.0B Total: 0.0B" pos_hint: {"top": .45} canvas: Color: rgba: 1.0, 1.0, 1.0, 0.3 Rectangle: pos: self.pos size: self.size #    "JUNK FILES", "MEMORY BOOST" # "APP MANAGER", "SECURITY & PRIVACY" GridLayout: id: body_buttons_menu size_hint: 1, .4 cols: 2 padding: 10 spacing: 5 #    canvas.before: Color: rgb: 1.0, 1.0, 1.0 Rectangle: pos: self.pos size: self.size # ,    Color: rgb: 0, 0, 0 Line: points: [0, self.size[1] / 1.9, self.size[0], self.size[1] / 1.9] width: 1 Line: points: [self.size[0] / 2, 0, self.size[0] / 2, self.size[1] / 1.001] width: 1 

ご芧のように、Kv蚀語はUI芁玠をマヌクするこずに加えお、kvファむルで蚈算を実行し、コヌルバックを取埗しおそれらにパラメヌタヌを枡し、暙準たたは倖郚のPythonモゞュヌルをむンポヌトしお䜿甚できるずいう意味で、ほがPythonです。


ここで、レむアりトを制埡するクラスを芋おみたしょう。すべおの芁玠がレむアりトファむルに䜜成されるわけではないのは明らかです。たずえば、ActionBarにはスピナヌがなく、メニュヌボタンの䞋にはルヌトボックスのみが䜜成されたす。



startscreen.py
 #! /usr/bin/python2.7 # -*- coding: utf-8 -*- # # startscreen.py # #   . # from kivy.uix.boxlayout import BoxLayout from kivy.uix.label import Label from kivy.uix.image import Image from kivy.uix.button import Button from kivy.uix.behaviors import ButtonBehavior from kivy.uix.actionbar import ActionItem from kivy.lang import Builder from kivy.properties import ObjectProperty, ListProperty class ImageButton(ButtonBehavior, Image): pass class MyOwnActionButton(Button, ActionItem): pass class StartScreen(BoxLayout): events_callback = ObjectProperty(None) """   .""" color_blue = ListProperty( [0.1607843137254902, 0.34901960784313724, 0.6784313725490196]) """ background . """ color_label= ListProperty( [0.6784313725490196, 0.7294117647058823, 0.8392156862745098, 1]) """   STORAGE/RAM. """ color_ellipse_static= ListProperty( [0.38823529411764707, 0.5254901960784314, 0.7764705882352941, 1]) """   STORAGE/RAM. """ Builder.load_file("Libs/uix/kv/startscreen.kv") """ """ def __init__(self, **kvargs): super(StartScreen, self).__init__(**kvargs) self.orientation = "vertical" #   . self.layouts = self.ids self.body_storage_ram = self.ids.float_layout self.screen_manager = self.ids.screen_manager self.action_previous = self.ids.action_previous self.background_action_bar = self.ids.action_bar.canvas.children[3] self.ellips_storage = self.body_storage_ram.canvas.children[8] self.ellips_ram = self.body_storage_ram.canvas.children[14] self._action_overflow = self.ids.action_overflow self.create_spinner_items() self.create_menu_buttons() def create_spinner_items(self): """      ActionBar.""" for item_name in ["Settings", "Update", "Like Us", "Feedback", "FAQ", "About"]: item_button = \ MyOwnActionButton( text=item_name, id=item_name, on_press=self.events_callback, color=[.1, .1, .1, 1], background_normal="Data/Images/background_action_item.png", background_down="Data/Images/background_down.png", on_release=lambda *args: self._action_overflow._dropdown.select( self.on_release_select_item_spinner())) self._action_overflow.add_widget(item_button) def create_menu_buttons(self): """    .""" name_path_buttons_menu = { "JUNK FILES": "Data/Images/clean_cache.png", "MEMORY BOOST": "Data/Images/clean_memory.png", "APP MANAGER": "Data/Images/clean_apk.png", "SECURITY & PRIVACY": "Data/Images/clean_privacy.png"} for name_button in name_path_buttons_menu.keys(): item_box = BoxLayout(orientation="vertical") item_label = Label(text=name_button, color=[.1, .1, .1, 1]) item_button = \ ImageButton(source=name_path_buttons_menu[name_button], id=name_button, on_press=self.events_callback) item_box.add_widget(item_button) item_box.add_widget(item_label) self.ids.body_buttons_menu.add_widget(item_box) def on_release_select_item_spinner(self): """  release    ActionBar.   ,     .""" pass 

このクラスには、ActionBarドロップダりンリスト甚のボタン、ボタン、およびメニュヌラベルを䜜成するずいうタスクが2぀しかありたせん。 クラスは、コヌドで埌で䜿甚するために属性を初期化したす。これは、startscreen.kvマヌクアップファむルから識別子によっお取埗されたりィゞェットです。


さらに䜜業を進めるには、カスタムボタンりィゞェットが必芁です...



...次の2぀のアクティビティで䜿甚されたす。 小さく、プロパティを操䜜するむンタヌフェむスマヌクアップずプログラムコヌドの盞互䜜甚をよりよく理解するのに圹立ちたす。



custombutton.kv


 #:kivy 1.9.1 <CustomButton@Button> #    Button . #   root -    CustomButton. id: root.id text: root.button_text background_normal: "Data/Images/background_action_item.png" background_down: "Data/Images/background_down.png" size_hint_y: None text_size: root.width - 150, root.height valign: "middle" height: root.button_height color: 0.1, 0.1, 0.1, 1 on_press: if callable(root.event_callback): root.event_callback(root.id) #     Image: source: root.icon size_hint_y: None height: root.icon_height pos: root.x - 25, root.y + self.height / 2 #     Image: source: root.icon_load size_hint_y: None pos: root.width / 2 - 25, root.y size: root.size 

custombutton.py


 #! /usr/bin/python2.7 # -*- coding: utf-8 -*- # # custombutton.py # from kivy.lang import Builder from kivy.uix.button import Button from kivy.properties import StringProperty, NumericProperty, ObjectProperty Builder.load_file("Libs/uix/kv/custombutton.kv") class CustomButton(Button): id = StringProperty("") button_height = NumericProperty(65) button_text = StringProperty("") icon = StringProperty("") icon_height = NumericProperty(30) icon_load = StringProperty("Data/Images/loading.gif") event_callback = ObjectProperty(None) 

さお、準備ができたスピナヌ、カスタムボタンりィゞェット、およびon_events関数のメむンクラスProgramには、「About」むベントの凊理がありたす...



...このアクティビティずそのコントロヌルクラスを䜜成したしょう。



about.kv
 #:kivy 1.9.1 <About>: orientation: "vertical" ScrollView: GridLayout: cols: 1 size_hint_y: None spacing: 10 padding: 10 height: self.minimum_height canvas: Color: rgb: root.about_background Rectangle: pos: self.pos size: self.size #   Image: source: "Data/Images/logo.png" size_hint_y: None #   Label: text: "Clean Master 5.4.0.1395" size_hint_y: None height: "10pt" color: 0.1, 0.1, 0.1, 1 italic: True #   share GridLayout: id: box_share cols: 1 size_hint_y: None height: self.minimum_height #   Label: text: root.text_license text_size: self.size font_size: dp(12) valign: "top" size_hint_y: None height: root.height / 2.5 color: 0.1, 0.1, 0.1, 1 #   BoxLayout: orientation: "vertical" size_hint: 1, .2 canvas: Color: rgb: root.about_background Rectangle: pos: self.pos size: self.size Color: rgb: 0.5843137254901961, 0.5843137254901961, 0.5843137254901961 Line: points: [0, self.size[1], self.size[0], self.size[1]] width: 1 Label: text: "Copyright 2016 Demo Clean Master\nby HeaTTheatR" halign: "center" color: 0.1, 0.1, 0.1, 1 

about.py
 #! /usr/bin/python2.7 # -*- coding: utf-8 -*- # # about.py # from kivy.uix.boxlayout import BoxLayout from kivy.lang import Builder from kivy.properties import ObjectProperty, StringProperty, ListProperty from .custombutton import CustomButton class About(BoxLayout): events_callback = ObjectProperty(None) """   .""" text_license = StringProperty("Clean Master") about_background = ListProperty( [0.7294117647058823, 0.7686274509803922, 0.8470588235294118]) Builder.load_file("Libs/uix/kv/about.kv") """ """ def __init__(self, **kvargs): super(About, self).__init__(**kvargs) self.create_button_share(self.ids.box_share) def create_button_share(self, box_share): """   share  . :type box_share: <'kivy.weakproxy.WeakProxy'> :param box_share: <'kivy.uix.gridlayout.GridLayout'> """ about_items_share = { "Share this app": "Data/Images/about_share.png", "Like us on Facebook": "Data/Images/about_facebook.png", "Join our beta testing group": "Data/Images/google_plus.png", "Help us with localization": "Data/Images/about_localization.png", "For Business Cooperation": "Data/Images/skype_icon.png"} for name_item in about_items_share.keys(): box_share.add_widget( CustomButton(icon_load="Data/Images/previous_image.png", icon=about_items_share[name_item], button_text=name_item, button_height=45, icon_height=25)) 

これで、ActionBarのドロップダりンリストを開き、[バヌゞョン情報]項目を遞択しお、遞択した画面に移動できたす。 「About」ずいうテキストに関しおいく぀かの自由を認め、GNU GPLラむセンスに眮き換えたしたが、これはデモには䞍可欠ではないず思いたす。



ActionBarの巊偎の矢印をクリックしお、スタヌト画面に戻るこずができたす。 startscreen.kvレむアりトにこのコヌルバックの呌び出しを蚘録したした。



そしお、on_events関数のメむンクラスProgramでそれをキャッチしたした。



show_aboutおよびback_screen関数に泚意しおください-これらは、on_eventsでゞャヌクする同じ名前のprogramclassパッケヌゞモゞュヌルのShowScreensクラスの関数です。 このクラスは、デモアプリケヌションの3぀のレむアりトを開き、それらを切り替えたす。



, , Program, , , , , .


ShowScreens.


ShowScreens
 #! /usr/bin/python2.7 # -*- coding: utf-8 -*- # # ShowScreens.py # class ShowScreens(object): """  .""" background_action_bar = \ [0.1568627450980392, 0.34509803921568627, 0.6784313725490196] def show_about(self): try: text_license = open("{}/LICENSE".format(self.prog_dir)).read() except Exception: text_license = "Clean Master" #   ,  About    "JUNK FILES". if self.start_screen.layouts.screen.manager.current == "JUNK FILES": self.Clock.unschedule(self.animation_clean) self.start_screen.background_action_bar.rgb = self.background_action_bar #       "Memory boost"  # "Cache junk". self.screen_junk.button_memory_bust.remove_widget( self.screen_junk.button_memory_bust_icon_state) self.screen_junk.button_cache_junk.remove_widget( self.screen_junk.button_cache_junk_icon_state) screen_about = \ self.About(events_callback=self.on_events, text_license=text_license) self.show_new_screen(screen_about, "About") def show_junk_files(self): self.set_default_tick_rgb() self.screen_junk = self.JunkFiles(events_callback=self.on_events) self.show_new_screen(self.screen_junk, "JUNK FILES") def back_screen(self): """   ActionPrevious  ActionBar.        .""" current_screen = self.start_screen.screen_manager.current if current_screen in ("About", "JUNK FILES"): #     ,  #  . if current_screen == "JUNK FILES": self.Clock.unschedule(self.animation_clean) #     ,   #  STORAGE/RAM. self.Clock.schedule_interval(self.calc_elliptical_length, .03) if len(self.start_screen.screen_manager.screens) != 1: self.start_screen.screen_manager.screens.pop() self.start_screen.screen_manager.current = \ self.start_screen.screen_manager.screen_names[-1] self.start_screen.action_previous.title = \ self.start_screen.screen_manager.current if current_screen in ("About", "JUNK FILES"): #    actionbar,      # About,    "JUNK FILES". self.start_screen.background_action_bar.rgb = self.new_color #  "",    actionbar. if self.start_screen.screen_manager.screen_names[-1] != \ "JUNK FILES" or current_screen == "": self.start_screen.background_action_bar.rgb = \ self.background_action_bar #   previous    actionbar. if self.start_screen.screen_manager.screens[-1].name != \ "JUNK FILES": self.start_screen.action_previous.app_icon = \ "Data/Images/previous_app_icon.png" 

だから , , , Activity JUNK FILES . Activity JUNK FILES :



junkfiles.py junkfiles.kv:



junkfiles.kv
 #:kivy 1.9.1 <JunkFiles> orientation: "vertical" FloatLayout: id: float_layout canvas: Color: rgb: 0.1607843137254902, 0.34901960784313724, 0.6784313725490196 Rectangle: pos: self.pos size: self.size #    BoxLayout: pos_hint: {"center_x": .5, "center_y": .75} size_hint: .7, 1 Image: id: storage_numeral_one size_hint: .52, .52 source: "Data/Images/6.png" Image: id: storage_numeral_two size_hint: .52, .52 source: "Data/Images/5.png" Image: id: point size_hint: .25, .25 pos_hint: {"center_y": .21} source: "Data/Images/dot.png" Image: id: numeral_float size_hint: .52, .52 source: "Data/Images/8.png" Image: size_hint: .22, .22 pos_hint: {"center_y": .48} source: "Data/Images/gb.png" #   ProgressLine: id: progress_line size_hint: 1, .1 pos_hint: {"center_y": .05} Label: id: progress_label text: "Scanning:" text_size: root.width - 20, root.height pos_hint: {"center_y": .05} valign: "middle" ScrollView: size_hint: 1, .6 canvas.before: Color: rgb: 1.0, 1.0, 1.0, Rectangle: pos: self.pos size: self.size GridLayout: id: grid_layout cols: 1 size_hint_y: None height: self.minimum_height BoxLayout: size_hint_y: None height: 80 padding: 10, 10 canvas.before: Color: rgb: 1.0, 1.0, 1.0, Rectangle: pos: self.pos size: self.size Button: id: button_stop text: "STOP" font_size: "19sp" bold: True markup: True background_normal: "Data/Images/stop_progress.png" background_down: "Data/Images/stop_progress_down.png" color: 0.1, 0.1, 0.1, 1 

junkfiles.py
 #! /usr/bin/python2.7 # -*- coding: utf-8 -*- # # junkfiles.py # #   . # from kivy.uix.boxlayout import BoxLayout from kivy.lang import Builder from kivy.properties import ObjectProperty from .progressline import ProgressLine from .custombutton import CustomButton class JunkFiles(BoxLayout): events_callback = ObjectProperty(None) """   .""" Builder.load_file("Libs/uix/kv/junkfikes.kv") """ """ def __init__(self, **kvargs): super(JunkFiles, self).__init__(**kvargs) self.create_custom_button() #   . self.layouts = self.ids self.button_memory_bust = self.layouts.grid_layout.children[0] self.button_cache_junk = self.layouts.grid_layout.children[1] self.button_memory_bust_icon_state = self.button_memory_bust.children[0] self.button_cache_junk_icon_state = self.button_cache_junk.children[0] self.progress_line = self.layouts.progress_line self.progress_label = self.layouts.progress_label self.button_stop = self.layouts.button_stop self.background = self.ids.float_layout.canvas.children[0] def create_custom_button(self): """        .""" junk_files_items = {"Memory boost": "Data/Images/memory_boost.png", "Cache junk": "Data/Images/cache_junk.png"} for action_clean in junk_files_items.keys(): path_to_icon_action = junk_files_items[action_clean] self.ids.grid_layout.add_widget( CustomButton(id=action_clean, icon=path_to_icon_action, button_text=action_clean, on_press=self.events_callback)) self.ids.button_stop.bind( on_press=lambda *args: self.events_callback("STOP")) 

ProgressLine junkfiles.kv:



junkfiles.py:



 #! /usr/bin/python2.7 # -*- coding: utf-8 -*- # # progressline.py # from kivy.uix.widget import Widget from kivy.utils import get_color_from_hex from kivy.graphics import Color, Line class ProgressLine(Widget): """ .""" bar_value_percent = 0 color = "#ffffff56" def __init__(self, **kwargs): super(ProgressLine, self).__init__(**kwargs) self.bind(pos=self.redraw) self.bind(size=self.redraw) def redraw(self, *args): """    .""" with self.canvas: self.canvas.clear() line_width = float(self.height) / 2 + 1 new_y = self.y + line_width new_x = self.x + self.width * self.bar_value_percent / 100 Color(*get_color_from_hex(self.color)) Line(points=[self.x, new_y, new_x, new_y], width=line_width, cap="none") 


, .



AnimationProgress.py
 #! /usr/bin/python2.7 # -*- coding: utf-8 -*- # # AnimationProgress.py # from random import randint class AnimationProgress(object): """  .""" def __init__(self): self.set_default_tick_rgb() self.scan_packages = range(100) def animation_storage_ram(self, *args): """   STORAGE/RAM.""" if isinstance(args[0], int): #    elliptical_length_storage = elliptical_length_ram = args[0] else: #      elliptical_length_storage = 317 elliptical_length_ram = 401 if self.tick <= 34: self.start_screen.ellips_storage.circle = \ ((self.start_screen.body_storage_ram.center_x / 1.5, self.start_screen.body_storage_ram.center_y / .65, min(self.start_screen.body_storage_ram.width, self.start_screen.body_storage_ram.height) / 4.5, 220, elliptical_length_storage, 50)) if self.tick <= 65: self.start_screen.ellips_ram.circle = \ ((self.start_screen.body_storage_ram.center_x / .65, self.start_screen.body_storage_ram.center_y / .69, min(self.start_screen.body_storage_ram.width, self.start_screen.body_storage_ram.height) / 7, 220, elliptical_length_ram, 50)) def animation_clean(self, interval): #       "Memory boost"  # "Cache junk"  -. if int(self.tick) == 50: self.screen_junk.button_memory_bust_icon_state.source = \ "Data/Images/app_uninatall.png" elif int(self.tick) == 99: self.screen_junk.button_cache_junk_icon_state.source = \ "Data/Images/app_uninatall.png" #      STOP. self.screen_junk.button_stop.background_normal = \ "Data/Images/done_progress.png" self.screen_junk.button_stop.text = \ "CLEAN JUNK {}MB".format(self.tick) self.screen_junk.button_stop.color = [1.0, 1.0, 1.0, 1] #   Activity. self.set_new_color() self.screen_junk.background.rgb = self.new_color self.start_screen.background_action_bar.rgb = self.new_color #     . value = (self.tick * 100) / 100 print value self.screen_junk.progress_line.bar_value_percent = value self.screen_junk.progress_line.redraw() self.screen_junk.progress_label.text = \ "Scanning: org.package {}".format(self.scan_packages[self.tick]) self.animation_percent( self.screen_junk.layouts, self.animation_clean, iteration=100) def animation_percent(self, layout, callback, iteration=65): """   . :type layout: <class 'Libs.uix.startscreen.StartScreen'> and <class 'Libs.uix.junkfiles.JunkFiles'>; :param callback: animation_clean and calc_elliptical_length; """ self.tick += 1 if self.tick == iteration: self.set_default_tick_rgb() self.Clock.unschedule(callback) return numeral_one, numeral_two = divmod(self.tick, 10) if self.tick <= 34 or iteration != 65: layout.storage_numeral_one.source = \ "Data/Images/{}.png".format(int(numeral_one)) layout.storage_numeral_two.source = \ "Data/Images/{}.png".format(int(numeral_two)) try: layout.numeral_float.source = \ "Data/Images/{}.png".format(randint(1, 9)) except AttributeError: pass try: if self.tick <= 65: layout.ram_numeral_one.source = \ "Data/Images/{}.png".format(int(numeral_one)) layout.ram_numeral_two.source = \ "Data/Images/{}.png".format(int(numeral_two)) except AttributeError: pass def calc_elliptical_length(self, interval): """     Activity.""" elliptical_length = ((self.tick * 500) // 178) + 222 self.animation_storage_ram(elliptical_length) self.animation_percent( self.start_screen.layouts, self.calc_elliptical_length) def set_default_tick_rgb(self): """      Activity JUNK FILES.""" self.tick = 9 self.R = 41. self.G = 89. self.B = 173. def set_new_color(self): """      Activity JUNK FILES.""" self.R += 2 self.G += 1 self.B -= 1 self.new_color = self.R / 255., self.R / 255., self.B / 255. 

:



KivyCleanMasterDemo githab — https://github.com/HeaTTheatR/KivyCleanMasterDemo




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


All Articles