Kivy-さらに簡単で、よりネイティブ







Kivyフレームワークを使用したモバイルアプリケーションの開発に関する一連の記事を継続します。 本日は、Kivyフレームワークを使用して記述されたAndroid Material Designスタイルのネイティブインターフェイスを構築するための素晴らしいKivyMDライブラリについて説明します。 率直に言って、個人的には、Kivyアプリケーションで曲線、暗くて恐ろしいカスタムウィジェットをスカルプトおよび熟考する必要がないことを無限に嬉しく思っています。 プロジェクトでKivyMDライブラリと少しの想像力を使用すると、プログラムがJavaで作成されているか、KivyおよびPythonフレームワークを使用して作成されているかを視覚的に区別できる可能性はほとんどありません。







KivyMDをダウンロードして解凍し、解凍したアーカイブのルートディレクトリに移動して、インストールを実行します。







python setup.py install
      
      





次に、KivyMDの依存関係をインストールします。







 pip install kivy-garden garden install recycleview
      
      





ライブラリをインストールしたら、ダウンロードして解凍したアーカイブからテスト例を実行できます。







 python kitchen_sink.py
      
      





起動後、プロジェクトで使用できるネイティブのウィジェットとコントロールを示すアプリケーションが表示されます。









この記事では、ライブラリの特定のウィジェットについては説明しません(それらの作成とパラメーターは同じkitchen_sink.pyに完全に記述されています)が、KivyMDを使用して簡単なデモアプリケーション「Contacts」を作成します。 このアプリケーションは、連絡先とグループを作成し、作成した連絡先をそれらに追加できます。 さて、途中で、Kivyでアプリケーションインターフェースを作成するいくつかの側面について詳しく説明します。









Kivyでデフォルトプロジェクトを簡単に作成するには、 CreatorKivyProjectをお勧めします 。詳細については、 この記事で説明します 。 したがって、参照による記事の指示に従って、DemoKivyContactsプロジェクトが作成されます。 パスDemoKivyContacts / libs / uix / kv / startscreen.kvに沿ってファイルを開き、その内容をすべて無慈悲に削除し、アプリケーションの開始画面を「描画」しましょう。













Kivy-Languageでのこのインターフェイスのレイアウトは次のとおりです。







startscreen.kv
 #:kivy 1.9.1 #:import CreateContact libs.uix.createcontact.CreateContact #:import CallContact libs.uix.callcontact.CallContact #:import EmptyScreen libs.uix.emptyscreen.EmptyScreen #:import Toolbar kivymd.toolbar.Toolbar #:import MDTabbedPanel kivymd.tabs.MDTabbedPanel #:import MDTab kivymd.tabs.MDTab ############################################################################### # #   # ############################################################################### <StartScreen>: id: root.manager Screen: name: 'root_screen' BoxLayout: #canvas: # Rectangle: # pos: self.pos # size: self.size # source: 'data/images/background.jpg' orientation: 'vertical' #################################################################### # # ACTION BAR # #################################################################### Toolbar: #canvas.before: # Rectangle: # pos: self.pos # size: self.size # source: 'data/images/background_toolbar.jpg' id: action_bar #background_color: app.data.alpha background_color: app.theme_cls.primary_color title: app.data.string_lang_contacts left_action_items: [['menu', lambda x: app.nav_drawer.toggle()]] right_action_items: [['more-vert', lambda x: None]] #################################################################### # # TABBED PANEL # #################################################################### MDTabbedPanel: id: tabs tab_display_mode: 'text' #tab_color: app.data.alpha tab_text_color: app.data.tab_text_color tab_indicator_color: app.data.tab_indicator_color MDTab: name: 'contacts' text: app.data.string_lang_contacts on_tab_press: app.on_tab_press(self.name) ScreenManager: id: screen_manager_tab_contacts Screen: name: 'empty_contacts_list' EmptyScreen: image: 'data/images/contacts.png' text: app.data.string_lang_add_contacts callback: app.show_form_create_contact disabled: False Screen: name: 'create_contact' CreateContact: MDTab: name: 'groups' text: app.data.string_lang_groups on_tab_press: app.on_tab_press(self.name) ScreenManager: id: screen_manager_tab_groups Screen: name: 'empty_groups_list' EmptyScreen: image: 'data/images/contacts.png' text: app.data.string_lang_not_groups callback: lambda: app.create_group() disabled: False Screen: name: 'call_contact' CallContact:
      
      





ご覧のとおり、画面では以下を使用します。







ツールバー
  Toolbar: id: action_bar background_color: app.theme_cls.primary_color title: app.data.string_lang_contacts left_action_items: [['menu', lambda x: app.nav_drawer.toggle()]] right_action_items: [['more-vert', lambda x: None]]
      
      











およびMDTabタブ付きのMDTabbedPanel
  MDTabbedPanel: id: tabs tab_display_mode: 'text' tab_text_color: app.data.tab_text_color tab_indicator_color: app.data.tab_indicator_color MDTab: name: 'contacts' text: app.data.string_lang_contacts on_tab_press: app.on_tab_press(self.name) ScreenManager: id: screen_manager_tab_contacts Screen: name: 'empty_contacts_list' EmptyScreen: image: 'data/images/contacts.png' text: app.data.string_lang_add_contacts callback: app.show_form_create_contact disabled: False Screen: name: 'create_contact' CreateContact: MDTab: name: 'groups' text: app.data.string_lang_groups on_tab_press: app.on_tab_press(self.name) ScreenManager: id: screen_manager_tab_groups Screen: name: 'empty_groups_list' EmptyScreen: image: 'data/images/contacts.png' text: app.data.string_lang_not_groups callback: lambda: app.create_group
      
      











startscreen.kvマークアップファイルの最初にこれらのKivyMDライブラリウィジェットをインポートしました。







 #:import Toolbar kivymd.toolbar.Toolbar #:import MDTabbedPanel kivymd.tabs.MDTabbedPanel #:import MDTab kivymd.tabs.MDTab
      
      





Kivy-Languageのこれらの手順は、Pythonスクリプトでのインポートに似ています。







 from kivymd.toolbar import Toolbar from kivymd.tabs import MDTabbedPanel from kivymd.tabs import MDTab
      
      





ちなみに、たとえばインターフェースが複雑すぎる場合は、kvファイルに他のマークアップファイルを含めることができます。







 #:include your_kv_file.kv
      
      





MDTabbedPanelには、「連絡先」と「グループ」という2つのタブがあります。 最初の(「連絡先」)にはScreenManagerウィジェット(スクリーンマネージャー)が含まれます。このウィジェットには、Javaの言語であるアクティビティを2つ配置します。







連絡先タブ
  MDTab: name: 'contacts' text: app.data.string_lang_contacts on_tab_press: app.on_tab_press(self.name) ScreenManager: id: screen_manager_tab_contacts Screen: name: 'empty_contacts_list' EmptyScreen: image: 'data/images/contacts.png' text: app.data.string_lang_add_contacts callback: app.show_form_create_contact disabled: False Screen: name: 'create_contact' CreateContact:
      
      





お気づきかもしれませんが、ScreenManagerには、コンテンツ(アクティビティ)を含む1つ以上のScreenウィジェット(画面)を含める必要があります。 私たちの場合、これはEmptyScreen(空白の画面)およびCreateContact(新しい連絡先を作成するためのフォーム)です。













名前ごとにアクティビティデータを切り替えます。







  Screen: name: 'empty_contacts_list' … Screen: name: 'create_contact'
      
      





... ScreenManagerオブジェクトの使用...







  ScreenManager: id: screen_manager_tab_contacts
      
      





...作成したマークアップの識別子によるプログラムコード内:













...そして、新しい画面の名前を現在の属性に渡すことでアクティビティを切り替えます:







 self.manager_tab_contacts.current = 'create_contact'
      
      





次に、アクティビティ— EmptyScreen(空白の画面)とCreateContact(新しい連絡先を作成するためのフォーム)を描画します。 プロジェクトディレクトリDemoKivyContacts / libs / uix / kv emptyscreen.kvとcreatecontact.kvでインターフェースマークアップファイルを作成し、 DemoKivyContacts / libs / uixディレクトリに同じ名前のpythonスクリプトを作成して、作成されたEmptyScreenおよびCreateContactウィジェットにパラメーターを渡します。







emptyscreen.kv
 #:kivy 1.9.1 #:import MDLabel kivymd.label.MDLabel #:import MDFloatingActionButton kivymd.button.MDFloatingActionButton <EmptyScreen>: id: empty_screen Image: source: root.image pos_hint: {'center_x': .5, 'center_y': .6} opacity: .5 MDLabel: id: label font_style: 'Headline' theme_text_color: 'Primary' color: app.data.text_color text: root.text halign: 'center' MDFloatingActionButton: id: float_act_btn icon: 'plus' size_hint: None, None size: dp(56), dp(56) opposite_colors: True elevation_normal: 8 pos_hint: {'center_x': .9, 'center_y': .1} background_color: app.data.floating_button_color background_color_down: app.data.floating_button_down_color disabled: root.disabled on_release: root.callback()
      
      





createcontact.kv
 #:kivy 1.9.1 #:import SingleLineTextField kivymd.textfields.SingleLineTextField #:import MDIconButton kivymd.button.MDIconButton #:import MDFlatButton kivymd.button.MDFlatButton #:import MDFloatingActionButton kivymd.button.MDFloatingActionButton <CreateContact>: orientation: 'vertical' FloatLayout: size_hint: 1, .3 Image: id: avatar pos_hint: {'center_y': .5} source: 'data/images/avatar_empty.png' MDFloatingActionButton: icon: 'plus' size_hint: None, None size: dp(56), dp(56) opposite_colors: True elevation_normal: 8 pos_hint: {'center_x': .9, 'center_y': .20} background_color: app.data.floating_button_color background_color_down: app.data.floating_button_down_color on_release: app.choice_avatar_contact() BoxLayout: orientation: 'vertical' padding: 5, 5 size_hint: 1, .3 BoxLayout: MDIconButton: icon: 'account' disabled: True SingleLineTextField: id: name_field hint_text: '' BoxLayout: MDIconButton: icon: 'phone' disabled: True SingleLineTextField: id: number_field hint_text: '' BoxLayout: MDIconButton: icon: 'email' disabled: True SingleLineTextField: id: email_field hint_text: 'E-mail' Widget: size_hint: 1, .3 AnchorLayout: anchor_x: 'right' anchor_y: 'bottom' size_hint: 1, None height: dp(40) MDFlatButton: id: button_ok text: 'OK' on_release: app.save_info_contact()
      
      





emptyscreen.py







 from kivy.uix.floatlayout import FloatLayout from kivy.properties import StringProperty, ObjectProperty, BooleanProperty class EmptyScreen(FloatLayout): image = StringProperty() text = StringProperty() callback = ObjectProperty() disabled = BooleanProperty()
      
      





createcontact.py







 from kivy.uix.boxlayout import BoxLayout class CreateContact(BoxLayout): pass
      
      





EmptyScreenでは、KivyMDライブラリの別のウィジェットであるMDFloatingActionButtonを使用しました。これは説明する価値があります。 多くのユーザーがバタンと鳴らそうとする同じ迷惑なフライ:













  MDFloatingActionButton: id: float_act_btn icon: 'plus' size_hint: None, None size: dp(56), dp(56) opposite_colors: True #  /  elevation_normal: 8 #   pos_hint: {'center_x': .9, 'center_y': .1} #     ,     background_color: app.data.floating_button_color background_color_down: app.data.floating_button_down_color disabled: root.disabled on_release: root.callback()
      
      





CreateContactはKivyMDライブラリウィジェットを使用します。







MDIconButton:













MDIconButtonは、ベクトルアイコンのあるボタンです。 Googleの公式アイコンの完全なセットは、 リンクをご覧ください。 それらはすべてKivyMDで使用され、利用可能です。







SingleLineTextField:













MDFlatButton:













ユーザー入力を保存する機能を呼び出します:







  MDFlatButton: … on_release: app.save_info_contact()
      
      





前述の方法に従って、 テキスト属性からのidに従って、SingleLineTextFieldフィールドからユーザーが入力した情報を受け取ります。







DemoKivyContacts / libs / uix / kv / createcontact.kv













DemoKivyContacts / libs / programclass / showformcreatecontact.py







  def show_form_create_contact(self, *args): '''       .''' self.manager_tab_contacts.current = 'create_contact' # <class 'libs.uix.createcontact.CreateContact'> self._form_create_contact = \ self.manager_tab_contacts.current_screen.children[0] ... def save_info_contact(self): '''    .''' name_contact = self._form_create_contact.ids.name_field.text number_contact = self._form_create_contact.ids.number_field.text mail_contact = self._form_create_contact.ids.email_field.text ...
      
      





データを保存した後、プログラムは作成されていない場合は連絡先リストを作成するか、既存のリストに新しいリストを追加して画面に表示します。













show_contacts
  def show_contacts(self, info_contacts): ''' :type info_contacts: dict; :param info_contacts: { 'Name contact': ['Number contact\nMail contact', 'path/to/avatar'] }; ''' if not self._contacts_items: #   . self._contacts_list = ContactsList() self._contacts_items = Lists( dict_items=info_contacts, flag='three_list_custom_icon', right_icons=self.data.right_icons, events_callback=self._event_contact_item ) button_add_contact = Builder.template( 'ButtonAdd', disabled=False, events_callback=self.show_form_create_contact ) self._contacts_list.add_widget(self._contacts_items) self._contacts_list.add_widget(button_add_contact) self.add_screens( 'contact_list', self.manager_tab_contacts, self._contacts_list ) else: #      #     . self._add_contact_item(info_contacts) self.manager_tab_contacts.current = 'contact_list'
      
      





add_screens関数に注意してください -プログラムで新しいアクティビティを追加し、それを現在の画面として設定します。







DemoKivyContacts / program.py







  def add_screens(self, name_screen, screen_manager, new_screen): screen = Screen(name=name_screen) # c   screen.add_widget(new_screen) #  Activity    screen_manager.add_widget(screen) #      screen_manager.current = name_screen #    Activity,      
      
      





MDListリストを作成するための小さな(まだ不器用な)バインディングを作成しました-DemoKivyContacts / libs / uix / lists.py







必要なパラメーターを使用してListsクラスのインスタンスを作成することにより、左側にアイコンがあり、右側にベクトルアイコンがあるリストアイテムを簡単に作成できます。







  def show_contacts(self, info_contacts): ''' :type info_contacts: dict; :param info_contacts: { 'Name contact': ['Number contact\nMail contact', 'path/to/avatar'] }; '''self._contacts_items = Lists( dict_items=info_contacts, flag='three_list_custom_icon', right_icons=self.data.right_icons, events_callback=self._event_contact_item )
      
      











次に、self._contacts_itemsのリストを必要なウィジェットにドロップします。







リストアイテムを作成するときに、 events_callbackパラメーターに_event_contact_item関数を渡して、パスのイベントを処理しました。







  def _event_contact_item(self, *args): '''   .''' def end_call(): self.screen.current = 'root_screen' instanse_button = args[0] if type(instanse_button) == RightButton: name_contact, name_event = instanse_button.id.split(', ') if name_event == 'call': self.screen.current = 'call_contact' data_contact = self.info_contacts[name_contact] call_screen = self.screen.current_screen.children[0] call_screen.name_contact = name_contact call_screen.number_contact = data_contact[0].split('\n')[0] call_screen.avatar = data_contact[1] call_screen.callback = end_call elif name_event == 'groups': self._show_names_groups(name_contact) else: name_contact, name_event = args
      
      





イベントID「call」および「group」は、 right_iconsパラメーターで指定したアイコンの名前です。







DemoKivyContacts / libs / programdata.py







 … right_icons = ['data/images/call.png', 'data/images/groups.png']
      
      





通話アイコンをクリックすると、シミュレートされた発信通話画面が開きます。







  def _event_contact_item(self, *args): def end_call(): self.screen.current = 'root_screen'if name_event == 'call': self.screen.current = 'call_contact' call_screen = self.screen.current_screen.children[0] … call_screen.callback = end_call
      
      











その中のすべてのウィジェットはすでに説明されているため、このアクティビティのレイアウトレイアウトを指定するだけです。







show_contacts
 #:kivy 1.9.1 #:import MDIconButton kivymd.button.MDIconButton #:import MDFloatingActionButton kivymd.button.MDFloatingActionButton #:import MDLabel kivymd.label.MDLabel <CallContact>: id: call_contact Widget: id: title_line canvas: Color: rgba: app.theme_cls.primary_color Rectangle: size: self.size pos: self.pos size_hint_y: None height: root.height * 30 // 100 # 30%    pos: 0, call_contact.height - self.size[1] Widget: canvas: Ellipse: pos: self.pos size: 150, 150 source: root.avatar if root.avatar else 'data/logo/kivy-icon-128.png' pos: (call_contact.width // 2) - 75, call_contact.height * 61 // 100 BoxLayout: orientation: 'vertical' size_hint: 1, None height: 50 pos: self.pos[0], call_contact.height * 45 // 100 MDLabel: id: name_contact font_style: 'Headline' theme_text_color: 'Primary' color: app.data.text_color text: root.name_contact if root.name_contact else 'Abonent' halign: 'center' MDLabel: id: number_contact font_style: 'Subhead' theme_text_color: 'Primary' color: app.data.text_color text: root.number_contact if root.number_contact else '12345' halign: 'center' BoxLayout: size_hint: None, None height: 60 width: volume.width + dialpad.width + account.width + mic.width pos: (call_contact.width // 2) - (self.width // 2), call_contact.height * 18 // 100 MDIconButton: id: volume icon: 'volume-mute' MDIconButton: id: dialpad icon: 'dialpad' MDIconButton: id: account icon: 'account' MDIconButton: id: mic icon: 'mic' MDFloatingActionButton: id: phone_end icon: 'phone-end' size_hint: None, None size: dp(56), dp(56) opposite_colors: True #  /  elevation_normal: 8 #   pos_hint: {'center_x': .5, 'center_y': .1} background_color: app.data.floating_button_color_end_call background_color_down: app.data.floating_button_down_color_end_call on_release: root.callback()
      
      





FloatLayoutから継承されたCallContactウィジェット:







 from kivy.uix.floatlayout import FloatLayout from kivy.properties import StringProperty, ObjectProperty class CallContact(FloatLayout): callback = ObjectProperty(lambda: None) avatar = StringProperty(None) name_contact = StringProperty(None) number_contact = StringProperty(None)
      
      





これは、その中のすべてのウィジェットとコントロールが互いにオーバーラップすることを意味します。そのため、マークアップでは、メイン画面の高さに対する位置のパーセンテージ表示を使用しました。







 pos: self.pos[0], call_contact.height * 45 // 100
      
      





ScreenManagerの仕組みがわかったので、開始アクティビティのコントロールクラスをもう一度見てみましょう。







 from kivy.uix.screenmanager import ScreenManager from kivy.properties import ObjectProperty class StartScreen(ScreenManager): events_callback = ObjectProperty(lambda: None) '''   .'''
      
      





およびスケルトンマークアップ:







 <StartScreen>: Screen: name: 'root_screen'#    — MDTabbedPanel Screen: name: 'call_contact' CallContact:
      
      





つまり、連絡先リストのアイテムで呼び出しボタンを押すと、発信呼び出しをシミュレートするアクティビティが開き、終了ボタンをクリックすると閉じます。







  def _event_contact_item(self, *args): def end_call(): self.screen.current = 'root_screen'if name_event == 'call': self.screen.current = 'call_contact' call_screen = self.screen.current_screen.children[0] … call_screen.callback = end_call
      
      





グループを作成するプロセスは、新しい連絡先を作成するプロセスと似ているため、考慮しません。 NavigationDrawerウィジェットについて詳しく見てみましょう。













NavigationDrawerパネルを使用するには、NavigationDrawerから継承したマークアップとコントロールクラスを作成する必要があります。







nawdrawer.kv
 #:kivy 1.9.1 <NavDrawer>: NavigationDrawerIconButton: icon: 'settings' text: app.data.string_lang_settings on_release: app.events_program(self.text) NavigationDrawerIconButton: icon: 'view-module' text: app.data.string_lang_plugin on_release: app.events_program(self.text) NavigationDrawerIconButton: icon: 'info' text: app.data.string_lang_license on_release: app.events_program(self.text) NavigationDrawerIconButton: icon: 'collection-text' text: 'About' on_release: app.events_program(self.text) NavigationDrawerIconButton: icon: 'close-circle' text: app.data.string_lang_exit_key on_release: app.events_program(app.data.string_lang_exit_key)
      
      





DemoKivyContacts / program.py







 from kivy.app import App from kivy.properties import ObjectProperty from kivymd.navigationdrawer import NavigationDrawer class NavDrawer(NavigationDrawer): events_callback = ObjectProperty() class Program(App): nav_drawer = ObjectProperty() def __init__(self, **kvargs): super(Program, self).__init__(**kvargs) def build(self): self.nav_drawer = NavDrawer(title=data.string_lang_menu)
      
      





今のところすべてです。 プロジェクトシナリオ全体をgithubで表示できます。







PS


間違いなく、KivyMDライブラリーはKivyフレームワークへの素晴らしい追加です! あなたがそれをマスターし、あなたのプロジェクトにそれを適用することを願っています。







Kivyを使用したモバイルアプリケーションの開発に関する記事の形式を変更する提案があります。Javaで記述された既製のネイティブAndroidアプリケーションを使用し、Kivyフレームワークを使用してPythonで記述された同様のアプリケーションを作成し、開発プロセス全体を最初からカバーします:ウィジェットとコントロールはKivyで作成され、動的クラスの使用方法、FloatLayoutとは何かなど










All Articles