ヘビの果実かフルーツのパイソン?

非聖書の物語





  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










All Articles