PythonのGUIライブラリKivyを使う

# はじめに
　Kivyは、PythonのGUIライブラリ。GUI部分をkv言語で、Pythonファイルと切り離して記述可能。本記事は、kivyの使い方を備忘録としてまとめる。
**Kivy https://kivy.org/**

# 目次
+ **[Kivy概要](#kivy概要)**
+ **[レイアウト](#レイアウト)**
+ **[ウィジェット](#ウィジェット)**
+ **[その他いろいろ作ってみた例](#その他いろいろ作ってみた例)**



# Kivy概要
　KivyはtkinterのようなPythonのGUIライブラリ。```pip3 install kivy```でライブラリをインストール可能。GUI部分をpythonファイルから切り離して .kv ファイルとして記述可能。Kivyの記述と起動方法は3種類ある。以降、本記事は「①kvファイル名とClass名を同じにする。」でまとめる。

### ①kvファイル名とClass名を同じにする。
.kvファイルとpython内に記述するClass名を同じにすることで紐づける(大文字は小文字に変換される)。 hello world の例は以下の通り。```.run()```で実行。
```Python:hello.py
from kivy.app import App

#class名称XXXをkvファイル(小文字でOK)にしてファイルをリンクさせる(gui_sample.kv)
class GUI_sample(App):
	title = 'GUI sample'

if __name__ == '__main__':
    GUI_sample().run()
```
```Python:gui_sample.kv
Label:
    text: "Hello World"
```

### ②任意のkvファイル名にする。
.kvファイルとpython内に記述するClass名を別名する場合は```Builder.load_file()```を使う。```.run()```でKivy実行時にclass内の```build()```関数が呼ばれる。```build()```のreturn値で、該当のファイル名を返信することで、kvファイルとclassが紐づく。

```Python:hello.py
from kivy.app import App
from kivy.lang import Builder

class GUI_sample(App):
	def build(self):
		self.title = 'GUI sample'
		return Builder.load_file('hello_test.kv')
	
if __name__ == '__main__':
    GUI_sample().run()
```
```Python:hello_test.kv
Label:
    text: "Hello World"
```

### ③pythonファイル内にkv記述する。
python内にkv記述し、1ファイルにする場合は```Builder.load_string()```を使う。②と同じく```.run()```でKivy実行時に、class内の```build()```関数が呼ばれる。```build()```のreturn値で```Builder.load_string()```を返信することでkv文字とclassが紐づく。
 
 
```Python:hello.py
from kivy.app import App
from kivy.lang import Builder

#kivy言語で記述
Layout = Builder.load_string('''
Label:
	text: "Hello World"
''')

class GUI_sample(App):
	def build(self):
		self.title = 'GUI sample'
		return Layout

if __name__ == '__main__':
    GUI_sample().run()
```
[戻る](#目次)

# レイアウト
　Kivyのレイアウトは、何種類か用意されている。本記事では```BoxLayout```、```GridLayout```についてボタンのレイアウトを例にしてまとめる。詳細や、その他のレイアウトは [[公式サイト:Getting Started » Layouts]](https://kivy.org/doc/stable/gettingstarted/layouts.html) を参照。

+ [BoxLayout](#boxlayout)
+ [GridLayout](#gridlayout)

[戻る](#目次)

## BoxLayout
　コンテナを垂直```vertical:```、水平```horizontal:```で指定してレイアウトする方法。```BoxLayout:``` を1ブロックのコンテナとして記述する。.kvファイル内に記述したコンテナは、Python内に同名のClassを定義することで紐づけられる。本例では、コンテナ名を```Root_Layout```として記述する。
　レイアウトは階層化することも可能。```BoxLayout:```コンテナの中に```BoxLayout:```を記載すれば階層化できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/5fe21ab9-db6b-bc0b-4fce-8ee88762943e.png)


<details><summary><b>👆の実行結果の.py/.kvファイルはこちら。</summary><div>

例内に使用している各コマンドの意味は以下の通り。
+  ```id:```は、各部品を識別するためのID。
+  ```background_color:```は、バックグランドの色を指定するコマンド。r(赤), g(緑), b(青) ,a(透明度)を有効値0～1で指定して使う。
+  ```size_hint_y:```コンテナサイズの垂直方向の割合を有効値0～1で指定して使う。水平方向の場合は ```size_hint_x:```で指定。



```Python:boxlayout.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout #boxのレイアウト


#.kvファイル内に記述したモジュール名と同じにする。
class Root_Layout(BoxLayout):
	pass

#class名称XXXをkvファイル(小文字でOK)にしてファイルをリンクさせる(gui_sample.kv)
class GUI_sample(App):
	title = 'GUI sample'

if __name__ == '__main__':
    GUI_sample().run()
```
```Python:gui_sample.kv
Root_Layout:
	#第一階層
	BoxLayout:
		orientation:'vertical'
		Button:
			id:button_R                # モジュールを識別するためのid
			background_color:(1,0,0,1) #「r(赤), g(緑), b(青) ,a(透明度)」有効値0～1
			size_hint_y:0.1            #「y軸のサイズ」有効値0～1
			text:'R'
		#第二階層
		BoxLayout:
			orientation:'horizontal'
			Button:
				id:button_G-1
				background_color:(0,1,0,1)
				text:'G-1'
			Button:
				id:button_G-2
				background_color:(0,1,0,1)
				text:'G-2'
			Button:
				id:label_G-3
				background_color:(0,1,0,1)
				text:'G-3'
		#第二階層
		BoxLayout:
			orientation:'vertical'
			Button:
				id:button_B-1
				background_color:(0,0,1,1)
				text:'B-1'
			Button:
				id:button_B-2
				background_color:(0,0,1,1)
				text:'B-2'
			Button:
				id:button_B-3
				background_color:(0,0,1,1)
				text:'B-3'
			Button:
				id:button_B-4
				background_color:(0,0,1,1)
				text:'B-4'
			Button:
				id:button_B-5
				background_color:(0,0,1,1)
				text:'B-5'
```
</div></details>


## GridLayout
　コンテナを行```rows:```、列```cols:```の数で指定してレイアウトする方法。```GridLayout:``` を1ブロックのコンテナとして記述する。BoxLayoutと同様にレイアウトの階層化も可能。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/6ea4aa68-0ffe-2ad0-b781-7048e9fd8f70.png)


<details><summary><b>👆の実行結果の.py/.kvファイルはこちら。</summary><div>
例内に使用している各コマンドの意味は以下の通り。

+  ```id:```　は、各部品を識別するためのID。
+  ```background_color:```は、バックグランドの色を指定するコマンド。r(赤), g(緑), b(青) ,a(透明度)を有効値0～1で指定して使う。
+  ```size: root.size```コンテナをルートのサイズに合わせる。これを実施しない場合、全体的に縮小されてしまう。



```Python:gridlayout.py
from kivy.app import App
from kivy.uix.gridlayout import GridLayout #gridlayoutのレイアウト


#.kvファイル内に記述したモジュール名と同じにする。
class Root_Layout(GridLayout):
	pass

#class名称XXXをkvファイル(小文字でOK)にしてファイルをリンクさせる(gui_sample.kv)
class GUI_sample(App):
	title = 'GUI sample'

if __name__ == '__main__':
    GUI_sample().run()
```
```Python:gui_sample.kv
Root_Layout:
	#第一階層
	GridLayout:
		rows: 2	#行
		cols: 1	#列
		size: root.size	#サイズをrootに合わせる
		
		#第二階層
		GridLayout:
			rows: 1	#行
			cols: 1	#列
			Button:
				id:button_R                # モジュールを識別するためのid
				background_color:(1,0,0,1) #「r(赤), g(緑), b(青) ,a(透明度)」有効値0～1
				text:'R'
		#第二階層
		GridLayout:
			rows: 1	#行
			cols: 2	#列
			
			#第三階層
			GridLayout:
				rows: 2	#行
				cols: 2	#列
				Button:
					id:button_G-1
					background_color:(0,1,0,1)
					text:'G-1'
				Button:
					id:button_G-2
					background_color:(0,1,0,1)
					text:'G-2'
				Button:
					id:label_G-3
					background_color:(0,1,0,1)
					text:'G-3'
				Button:
					id:label_G-4
					background_color:(0,1,0,1)
					text:'G-4'
			
			#第三階層
			GridLayout:
				rows: 5	#行
				cols: 1	#列
				Button:
					id:button_B-1
					background_color:(0,0,1,1)
					text:'B-1'
				Button:
					id:button_B-2
					background_color:(0,0,1,1)
					text:'B-2'
				Button:
					id:button_B-3
					background_color:(0,0,1,1)
					text:'B-3'
				Button:
					id:button_B-4
					background_color:(0,0,1,1)
					text:'B-4'
				Button:
					id:button_B-5
					background_color:(0,0,1,1)
					text:'B-5'
```
</div></details>

[戻る](#レイアウト)

# ウィジェット
ウィジェットは画面上に表示する部品。ここでは代表的なウィジェットを記述する。
+ [ラベル_Label](#ラベル_label) 
+ [テキストボックス_TextInput](#テキストボックス_textinput)
+ [ボタン_Button](#ボタン_button)
+ [チェックボックス_CheckBox](#チェックボックス_checkbox)
+ [スライダー_Slider](#スライダー_slider)
+ [スピナー_Spinner](#スピナー_spinner)
+ [ファイル選択_FileChooser](#ファイル選択_filechooser)
+ [タブ_TabbedPanel](#タブ_tabbedpanel)
+ **その他調査中**
+ [日本語化](#日本語化) 
+ [ウィジェットの使用例](#ウィジェットの使用例)

[戻る](#目次)

## ラベル_Label
　文字列を表示する。文字サイズは ```font_size:```。文字の色は```color:```。で設定可能。
```Python:Label
Label:
	id:label_A
    text: 'Hello World'
    font_size:20
    color:(1,0,0,1) #「r(赤), g(緑), b(青) ,a(透明度)」有効値0～1
```
[戻る](#ウィジェット)    

## テキストボックス_TextInput
　文字列を入力、出力する。文字サイズは、ラベル同様に設定可能。キーボードからの入力文字を直接テキストボックスへ出力するこができる。1行のテキストボックスの場合は```multiline:False```と記載する。また、ボタンなどのイベントの入出力として使用できる。入出力として使用する場合はidを指定する。 ```text_A.text='XXX'```とすれば、テキストボックスに'XXX'の文字列が出力される。
```Python:TextInput
TextInput:
	id:text_A
	text: ''
    font_size:15
```
[戻る](#ウィジェット)    

## ボタン_Button
　クリックでイベントを発生させる。ボタンの背景色は```background_color:```で設定可能。イベントは押したとき```on_press:```、離したとき```on_release:```それぞれで設定可能。.kvファイルに直接イベント発生時の処理を記載することもできるし、Pythonの関数コールにすることもできる。関数コールにする場合は、クラス内にイベントの関数を記述すること。```root.関数名```でコールする。
　ボタンを押す、離すのタイミングで、テキストボックスに文字列を表示する例を示す。
```Python:Button(.kvファイル)
#直接処理
Button:
	id:button_G-1
	background_color:(0,1,0,1)
	text:'G-1'
    on_press:text_A.text=text_A.text+'Push:G-1\n'
    on_release:text_A.text=text_A.text+'Release:G-1\n'
#関数処理
Button:
	id:button_G-2
	background_color:(0,1,0,1)
	text:'G-2'
	on_press:root.g2_push('G-2')
	on_release:root.g2_release('G-2')
```
```Python:Button(.pyファイル)
class Root_Layout(BoxLayout):
	def g2_push(self,indata):
		self.ids.text_A.text = self.ids.text_A.text + 'Push' + indata +'\n'
	def g2_release(self,indata):
		self.ids.text_A.text = self.ids.text_A.text  + 'Release'+ indata +'\n'
```
[戻る](#ウィジェット)  

## チェックボックス_CheckBox
　チェック状態を確認する。グループ化するとラジオボタンにもなる。```active:```0,1でチェック状態を設定する。チェックの状態は、チェックボックスのidを指定して、activeで確認する。グループ化させる場合は```group:```で同じ文字列を指定する。

```Python:CheckBox(.kvファイル)
CheckBox:
	id: Radio_1
	group:'radio_box'	#グループ化する場合設定。
	active:1
CheckBox:
	id: Radio_2
	group:'radio_box'	#グループ化する場合設定。
	active:0
CheckBox:
	id: Radio_3
	group:'radio_box'	#グループ化する場合設定。
	active:0
Button:
	id:button_radio
	text:'Radio_Set'
	on_press:root.radio()
```
```Python:CheckBox(.pyファイル)
class Root_Layout(BoxLayout):
	def radio(self):
		if(self.ids.Radio_1.active==1):
			self.ids.text_A.text = self.ids.text_A.text + 'Radio_1=ON\n'
		elif(self.ids.Radio_2.active==1):
			self.ids.text_A.text = self.ids.text_A.text + 'Radio_2=ON\n'
		elif(self.ids.Radio_3.active==1):
			self.ids.text_A.text = self.ids.text_A.text + 'Radio_3=ON\n'
```
[戻る](#ウィジェット)  


## スライダー_Slider
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/18b0da58-2dbb-baae-d4b6-237ab64be10f.png)

　スライダーでイベントを発生させる。```max: min:```スライダーの範囲を指定する。```cursor_width: cursor_height:```でスライダーのつまみのサイズを指定する。イベントは、押したとき```on_touch_up:```、スライドした時```on_touch_move:```それぞれで設定可能。.kvファイルに直接イベント発生時の処理を記載することもできるし、Pythonの関数コールにすることもできる。関数コールにする場合は、```Button:```と同様に、クラス内にイベントの関数を記述すること。root.関数名でコールする。スライダーの値は、スライダーのidを指定して、```value```で確認する。
　ボタンをスライドした時に値を、テキストボックスに文字列を表示する例を示す。
```Python:Slider(.kvファイル)
	Slider:
		id				:slider_1
		max				:100	#カーソルの最大値
		min				:0		#カーソルの最小値
		cursor_width	:16		#カーソルのサイズ(幅)
		cursor_height	:16		#カーソルのサイズ(高)
		on_touch_move	:root.slider_move()	#カーソルを動かしたときの動作
		on_touch_up  	:root.slider_move()	#カーソルをタッチした時の動作
```
```Python:Slider(.pyファイル)
class Root_Layout(BoxLayout):
	def slider_move(self):
			self.ids.slider_text_A.text = str(int(self.ids.slider_1.value))+'%'
```
[戻る](#ウィジェット)  

## スピナー_Spinner

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/0172f9aa-6975-dd10-cf4e-5bf4ae8a4e2a.png)



　スピナーはドロップダウンのボタンリストのウィジェット。```values:```はドロップダウンするボタンのリストを設定する。```text:```は初期値を設定する。イベントはButtonと同じく```on_press:```が使える。```on_text:```はボタンのリストから選択されたときのイベントを設定できる。```values```は動的に値を変更できる。また、```text```に現在選択されている値が格納される。
 
   
```Python:Spinner(.kvファイル)
	Spinner:
		id				:spinner_1
		size_hint_x		:0.8	#x軸のサイズ
		text:'spinner'					# Spinnerの初期値
		values: '1','2','3','4'			# Spinnerの選択できる値
		on_text:root.spinner_select()	# Spinnerからアイテムを選択されたとき
		on_press:root.spinner_push()	# Spinnerを押されたとき
```
```Python:Spinner(.pyファイル)
class Root_Layout(BoxLayout):
	def spinner_push(self):
		#Spnner押されるごとにインクリメントしたボタン追加
		self.ids.spinner_1.values.append( f'{len(self.ids.spinner_1.values)+1}' )
	def spinner_select(self):
		self.ids.slider_text_A.text = self.ids.spinner_1.text
```
[戻る](#ウィジェット)  

## タブ_TabbedPanel
```TabbedPanel```は、下図のようにTabボタンの押下で画面を切り替えたいときに使うウィジェット。```TabbedPanelItem:```の配下に画面に表示したいウィジェットを列挙する。```tab_pos:```はタブボタンの配置位置を決める。デフォルトのタブを指定したくない場合は```do_default_tab:False```とする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/4679aff7-2449-63ab-624c-2b5d7b96ce93.png)


```Python:TabbedPanel(.kvファイル)
Root_Layout:
	TabbedPanel:
		tab_pos: 'top_left'		#Tab選択ボタンの位置(top_left/top_right/bottom_left/bottom_right)
		do_default_tab: False	#DefaultのTab有り無し
		#Tab_A
		TabbedPanelItem:
			text:'Tab_A'
			Label:
				text:'Tab_A Hello!'
		#Tab_B
		TabbedPanelItem:
			text:'Tab_B'
			Label:
				text:'Tab_B Hello!'
```

[戻る](#ウィジェット) 

## ファイル選択_FileChooser
FileChooserIconLayout
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/e2d1bb4c-31de-0fb0-111d-d26f23f2be6d.png)
FileChooserListLayout
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/4daafad2-f0fb-4f02-5422-260557669932.png)

　FileChooserはファイル選択画面を表示する。図のようにアイコン形式```FileChooserIconLayout```と、リスト形式```FileChooserListLayout```の二種類が準備されている。表示する種類を```FileChooser```内に記述する。
```.view_mode```できる替えができる。
　ファイルファイアログの初期フォルダパスは```path:```で記述する。ファイルをフィルタしたい場合は```filters:```でフィルタ内容を記述する。
　現在のフォルダパスは```.path```。現在選択されているファイルは```.selection```から取得できる。selectionはリスト形式で取得する。ファイルはselection[0]に格納される。ファイルがないフォルダの場合は空のストになるので注意。
```Python:FileChooser(.kvファイル)
FileChooser:
    id          :FileCh
	path        :'./'     #カレントフォルダ指定
	filters     :['*.py'] #拡張子が.pyのファイル
	FileChooserIconLayout #Icon表示
	FileChooserListLayout #List表示

# FileChooser動作確認のためのボタン----------------
Button:
	id　:Btn_list
	text:'List'
	on_press:root.btn_list_on()
Button:
	id:Btn_icon
	text:'Icon'
    on_press:root.btn_icon_on()
Button:
	id:Btn_select
	text:'Select'
    # FileCh.path 現在のフォルダパス
    # FileCh.selection 現在選択されているファイル
	on_press:root.btn_select_on(FileCh.path, FileCh.selection)
TextInput:
	id:TextBox
	text: ''
```

```Python:FileChooser(.pyファイル)
class Root_Layout(BoxLayout):
	def btn_icon_on(self):
		self.ids.FileCh.view_mode = 'icon'	#アイコン表示にする。
		
	def btn_list_on(self):
		self.ids.FileCh.view_mode = 'list'	#リスト表示にする。
	
	def btn_select_on(self,path,selection):
		#パスを表示
        self.ids.TextBox.text = self.ids.TextBox.text + '[PATH]'+path+'\n'
		
        #現在選択しているファイルをリスト形式で取得する。ファイルはselection[0]に格納
		#ファイルがないと空のリストにアクセスしてエラーになるでlen()で確認してから処理。
		if len(selection):
			self.ids.TextBox.text = self.ids.TextBox.text + '[FILE]'+ selection[0] + '\n'  
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/f4a1ed6a-1312-d7ac-9f21-9e20c2a5ae7b.png)

<details><summary><b>👆の実行結果の.py/.kvファイルはこちら。</summary><div>

```Python:main.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout #boxのレイアウト

#.kvファイル内に記述したモジュール名と同じにする。
class Root_Layout(BoxLayout):
	def btn_icon_on(self):
		self.ids.FileCh.view_mode = 'icon'	#icon view
		
	def btn_list_on(self):
		self.ids.FileCh.view_mode = 'list'	#list view
	
	def btn_select_on(self,path,selection):
		self.ids.TextBox.text = self.ids.TextBox.text + '[PATH]'+path+'\n'
		#現在選択しているファイルをリスト形式で取得する。ファイルはselection[0]に格納
		#ファイルがないと空のリストにアクセスしてエラーになるでlen()で確認してから処理。
		if len(selection):
			self.ids.TextBox.text = self.ids.TextBox.text + '[FILE]'+ selection[0] + '\n'

		
#class名称XXXをkvファイル(小文字でOK)にしてファイルをリンクさせる(gui_sample.kv)
class GUI_sample(App):
	title = 'GUI sample'

if __name__ == '__main__':
    GUI_sample().run()
```

```Python:gui_sample.kv
Root_Layout:
	#第一階層
	BoxLayout:
		orientation:'vertical'
		#背景設定
		canvas:
			Color:
				rgba: 0.3,0.3,0.3,1
			Rectangle:
				size: self.size
				pos: self.pos
				
		orientation:'vertical'
		#Listボタン
		Button:
			id:Btn_list
			text:'List'
			font_size:20
			size_hint_y:0.1
			on_press:root.btn_list_on()
		#Iconボタン
		Button:
			id:Btn_icon
			text:'Icon'
			font_size:20
			size_hint_y:0.1
			on_press:root.btn_icon_on()
		#Selectボタン
		Button:
			id:Btn_select
			text:'Select'
			font_size:20
			size_hint_y:0.1
			on_press:root.btn_select_on(FileCh.path,FileCh.selection)
		#Text
		TextInput:
			id:TextBox
			text: ''
			font_size:20
			size_hint_y:1
		#ファイルダイアログ
		FileChooser:
			id:FileCh
			path:'./'
			filters:['*.py']
			FileChooserIconLayout
			FileChooserListLayout

```

</div></details>

[戻る](#ウィジェット)  

## 日本語化
Kivyで日本語使うと文字化けする。下記に日本語化するライブラリが公開されていました。便利。
https://github.com/momijiame/japanize-kivy

[戻る](#ウィジェット) 

## ウィジェットの使用例
　最後にウィジェットの使用例。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/a85ea857-78d9-ab3b-a1b6-799a7021c66b.png)


<details><summary><b>👆の実行結果の.py/.kvファイルはこちら。</summary><div>

```Python:widget.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout #boxのレイアウト
import japanize_kivy # https://github.com/momijiame/japanize-kivy 日本語化


#.kvファイル内に記述したモジュール名と同じにする。
class Root_Layout(BoxLayout):
	def g2_push(self,indata):
		self.ids.text_A.text = self.ids.text_A.text + 'Push' + indata +'\n'
	def g2_release(self,indata):
		self.ids.text_A.text = self.ids.text_A.text  + 'Release'+ indata +'\n'
	def reset(self):
		self.ids.text_A.text = ''
	def radio(self):
		if(self.ids.Radio_1.active==1):
			self.ids.text_A.text = self.ids.text_A.text + 'Radio_1=ON\n'
		elif(self.ids.Radio_2.active==1):
			self.ids.text_A.text = self.ids.text_A.text + 'Radio_2=ON\n'
		elif(self.ids.Radio_3.active==1):
			self.ids.text_A.text = self.ids.text_A.text + 'Radio_3=ON\n'
	def slider_move(self):
			self.ids.slider_text.text = str(int(self.ids.slider_1.value))+'%'
	def spinner_push(self):
		#Spnner押されるごとにインクリメントしたボタン追加
		self.ids.spinner_1.values.append( f'{len(self.ids.spinner_1.values)+1}' )
	def spinner_select(self):
		self.ids.spinner_text.text = self.ids.spinner_1.text

	def btn_icon_on(self):
		self.ids.FileCh.view_mode = 'icon'	#icon view
		
	def btn_list_on(self):
		self.ids.FileCh.view_mode = 'list'	#list view
	
	def btn_select_on(self,path,selection):
		self.ids.TextBox.text = self.ids.TextBox.text + '[PATH]'+path+'\n'
		#現在選択しているファイルをリスト形式で取得する。ファイルはselection[0]に格納
		#ファイルがないと空のリストにアクセスしてエラーになるでlen()で確認してから処理。
		if len(selection):
			self.ids.TextBox.text = self.ids.TextBox.text + '[FILE]'+ selection[0] + '\n'
			
		
#class名称XXXをkvファイル(小文字でOK)にしてファイルをリンクさせる(gui_sample.kv)
class GUI_sample(App):
	title = 'GUI sample'

if __name__ == '__main__':
    GUI_sample().run()
```

```Python:gui_sample.kv
Root_Layout:
	#第一階層
	TabbedPanel:
		tab_pos: 'bottom_left'
		do_default_tab: False
		
		#Tab_A=====================================
		TabbedPanelItem:
			text:'Tab_A'
			background_color:(1,0,0,1)
			#第二階層
			BoxLayout:
				orientation:'vertical'
				#背景設定
				canvas:
					Color:
						rgba: 0.3,0.3,0.3,1
					Rectangle:
						size: self.size
						pos: self.pos
				Label:
					id:label_A
					text: 'Hello World'
					font_size:20
					color:(1,0,0,1) #「r(赤), g(緑), b(青) ,a(透明度)」有効値0～1
					size_hint_y:0.2	#y軸のサイズ
				TextInput:
					id:text_A
					text: ''
					font_size:15
					size_hint_y:0.8	#y軸のサイズ
				#第三階層(G-1/G-2/G-3)
				BoxLayout:
					orientation:'horizontal'
					size_hint_y:0.2	#y軸のサイズ
					#直接処理
					Button:
						id:button_G-1
						background_color:(0,1,0,1)
						text:'G-1'
						on_press:text_A.text=text_A.text+'Push:G-1\n'
						on_release:text_A.text=text_A.text+'Release:G-1\n'
					#関数処理
					Button:
						id:button_G-2
						background_color:(0,1,0,1)
						text:'G-2'
						on_press:root.g2_push('G-2')
						on_release:root.g2_release('G-2')
					#関数処理
					Button:
						id:button_reset
						background_color:(0,1,0,1)
						text:'Reset'
						on_press:root.reset()
				#第三階層(RadioBox/Radio_Set)
				BoxLayout:
					orientation:'horizontal'
					size_hint_y:0.2	#y軸のサイズ
					#第四階層(RadioBox)
					BoxLayout:
						orientation:'vertical'
						BoxLayout:
							orientation:'horizontal'
							CheckBox:
								id: Radio_1
								group:'radio_box'
								active:1
								size_hint_x:0.2	#x軸のサイズ
							Label:
								text: 'radio_1'
						BoxLayout:
							orientation:'horizontal'
							CheckBox:
								id: Radio_2
								group:'radio_box'
								active:0
								size_hint_x:0.2	#x軸のサイズ
							Label:
								text: 'radio_2'
						BoxLayout:
							orientation:'horizontal'
							CheckBox:
								id: Radio_3
								group:'radio_box'
								active:0
								size_hint_x:0.2	#x軸のサイズ
							Label:
								text: 'radio_3'
					#第四階層(Radio_Set)
					Button:
						id:button_radio
						background_color:(0,0,1,1)
						text:'Radio_Set'
						on_press:root.radio()
				#第三階層(Slider)
				BoxLayout:
					orientation:'horizontal'
					size_hint_y:0.1	#y軸のサイズ
					#第四階層(Slider)
					Slider:
						id				:slider_1
						size_hint_x		:0.8	#x軸のサイズ
						max				:100	#カーソルの最大値
						min				:0		#カーソルの最小値
						cursor_width	:16		#カーソルのサイズ(幅)
						cursor_height	:16		#カーソルのサイズ(高)
						on_touch_move	:root.slider_move()	#カーソルを動かしたときの動作
						on_touch_up  	:root.slider_move()	#カーソルをタッチした時の動作
					#第四階層(Slider_text)
					TextInput:
						id:slider_text
						size_hint_x:0.2		#x軸のサイズ
						text: ''
						font_size:15
				#第三階層(Spinner)
				BoxLayout:
					orientation:'horizontal'
					size_hint_y:0.1	#y軸のサイズ
					#第四階層(Spinner)
					Spinner:
						id				:spinner_1
						size_hint_x		:0.8	#x軸のサイズ
						text:'spinner'					# Spinnerの初期値
						values: '1','2','3','4'			# Spinnerの選択できる値
						on_text:root.spinner_select()	# Spinnerからアイテムを選択されたとき
						on_press:root.spinner_push()	# Spinnerを押されたとき
					#第四階層(Spinner_text)
					TextInput:
						id:spinner_text
						size_hint_x:0.2		#x軸のサイズ
						text: ''
						font_size:15

		#Tab_B=====================================
		TabbedPanelItem:
			text:'Tab_B'
			background_color:(1,0,0,1)
			#第二階層
			BoxLayout:
				orientation:'vertical'
				#背景設定
				canvas:
					Color:
						rgba: 0.3,0.3,0.3,1
					Rectangle:
						size: self.size
						pos: self.pos
						
				orientation:'vertical'
				#Listボタン
				Button:
					id:Btn_list
					text:'List'
					font_size:20
					size_hint_y:0.1
					on_press:root.btn_list_on()
				#Iconボタン
				Button:
					id:Btn_icon
					text:'Icon'
					font_size:20
					size_hint_y:0.1
					on_press:root.btn_icon_on()
				#Selectボタン
				Button:
					id:Btn_select
					text:'Select'
					font_size:20
					size_hint_y:0.1
					on_press:root.btn_select_on(FileCh.path,FileCh.selection)
				#Text
				TextInput:
					id:TextBox
					text: ''
					font_size:20
					size_hint_y:1
				#ファイルダイアログ
				FileChooser:
					id:FileCh
					path:'./'
					filters:['*.py']
					FileChooserIconLayout
					FileChooserListLayout

```

</div></details>

[戻る](#ウィジェット) 

# その他いろいろ作ってみた例
https://qiita.com/tapitapi/items/f32560b1c8eec07c4837

https://qiita.com/tapitapi/items/51ddefc1dd8e810430c8

https://qiita.com/tapitapi/items/e611837559d511749a7a

https://qiita.com/tapitapi/items/876e728592165c83feed

https://qiita.com/tapitapi/items/7c41dab03089ef9852fb

その他作成したら追加

[戻る](#目次)