PyCharmでKivyを使うメモ

[Kivy](https://kivy.org/#home) は [Python](https://www.python.org/) で GUI を扱うためのパッケージのひとつです。

「python gui」でぐぐったら2017年のおすすめが Kivy と書いてあるサイトがあったので使ってみようと思いました。
[【Python】GUIライブラリの比較・おすすめ | アルゴリズム雑記](https://algorithm.joho.info/programming/python/gui-library-py/)

環境は 

- PyCharm Community 2018.2
- win7 personal 64bit
- python 3.6

です。


#kivy が認識されない
最初は、 pip を使って次のサイトを参考にインストールしたのですが PyCharm では import kivy が Unresolved のままでした。
[Setting Up Kivy with various popular IDE's · kivy/kivy Wiki](https://github.com/kivy/kivy/wiki/Setting-Up-Kivy-with-various-popular-IDE's#setting-up-kivy-190-with-pycharm-45-eap-on-os-x-10103)

上記URLのコマンドを実行した結果次のパスにインストールされました。
c:\users\Username\appdata\local\programs\python\python36\lib\site-packages
しかし、PyCharm は別の場所を見ているようです。

#PyCharm にパッケージを追加する
[PyCharm](https://www.jetbrains.com/pycharm/) では pip などのコマンドラインを使わないで、パッケージをインストールすることができるようです。
次のQiitaを参考にしました。
[PyCharmによるパッケージの追加方法 - Qiita](https://qiita.com/yamaAtsu/items/34e2a04408695365d586)
インストールするものが kivy というだけで他は上記サイトの手順と同じです。

PyCharm でパッケージをインストールするには、メニュー[File]＞[Settings] で Settings ウィンドウを開きます。
開いた Settings ウィンドウの左のリストから[Project: プロジェクト名]＞[Project Interpreter] を選択します。

![PyCharmへのPackageのinstall手順1.png](https://qiita-image-store.s3.amazonaws.com/0/46088/c24c6f89-c112-f177-38a7-07c34a80e01f.png)

その後、 + ボタンを押して、Available Packages ウィンドウを開き、 kivy と検索します。

![PyCharmへのPackageのinstall手順2.png](https://qiita-image-store.s3.amazonaws.com/0/46088/c95f8ee5-a453-217f-36af-b899ab6da7ca.png)

その後、 kivy をリストの項目から選択して Install Package ボタンを押します。

![PyCharmへのPackageのinstall手順3.png](https://qiita-image-store.s3.amazonaws.com/0/46088/a3b66213-b478-47ec-549f-9534eecd8384.png)

無事に成功すると、パッケージのインストールが成功します。
Settings ウィンドウでもリストに kivy が追加され、スクリプトエディタでも kivy が解決されています。

![kivyがunresolvedから解決された.png](https://qiita-image-store.s3.amazonaws.com/0/46088/0d29871b-8b13-ef0b-b38e-ee3866160451.png)

kivy は venv/lib/site-packages フォルダの中にインストールされていました。
![2018-08-05_102131.png](https://qiita-image-store.s3.amazonaws.com/0/46088/5bb355ad-f316-9ec3-2965-874f70cba580.png)

**注意！**
PyCharm に kivy パッケージだけをインストールしても実行時エラーになりました。
同様になった方は[実行時エラーでウィンドウが表示できない](#実行時エラーでウィンドウが表示できない)を参考にして、pypiwin32, kivy.deps.sdl2, kivy.deps.glew, kivy.deps.gstreamer, kivy.deps.angle パッケージも追加してみてください。


# Kv ファイルは、 XxApp なら xx.kv を自動的に読み込んでくれる
python コードとして GUI を配置することもできるようですが、 Kv ファイルに GUI のレイアウトを記述したほうがロジックと GUI がわけられて使いやすいかもしれません。

サンプルを読むと

```Main.py
#-*- coding: utf-8 -*-
from kivy.app import App

class MyApp(App):
    pass

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

などと書いてあり、kv を読み込んでいる場所が見当らなくてとまどいました。

これは、 MyApp ならば my.kv を自動的に読み込んでくれるということのようです。
[Kv language(翻訳済み) — Kivy 1.10.0 ドキュメント](https://pyky.github.io/kivy-doc-ja/guide/lang.html)

#実行時エラーでウィンドウが表示できない
さっそく、次のようなウィンドウを表示させるだけの main.py と main.kv を作りました。
[FileChooser — Kivy 1.11.0.dev0 documentation](https://kivy.org/docs/api-kivy.uix.filechooser.html)を参考にしています。

```main.py
#-*- coding: utf-8 -*-

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.factory import Factory
from kivy.properties import ObjectProperty
from kivy.uix.popup import Popup

import os

class Root(FloatLayout):
    def on_button_loaddialog(self):
        print('on_button_loaddialog')

    def on_button_run(self):
        print('on_button_run')

class MainApp(App):
    pass

Factory.register('Root', cls=Root)


if __name__ == '__main__':
    MainApp().run()

```

main.kv は今作ろうとしているツールに必要なラベルとテキストとボタンをいれています。

```main.kv
#:kivy 1.10.1

Root:
    BoxLayout:
        orientation: 'vertical'

        BoxLayout:
            orientation: 'vertical'

            Label:
                text: 'choose sprite.xml'

            BoxLayout:
                orientation: 'horizontal'

                TextInput:
                    id: text_filepath_sprites_xml
                    text: ""

                Button:
                    text: 'Load'
                    on_release: root.on_button_loaddialog()

            Label:
                text: 'input png file name (ex. sprites.png)'

            TextInput:
                id: text_filename_sprites_png
                text: "sprites.png"

            Button:
                text: 'Run'
                on_release: root.on_button_run()

            Label:
                text: 'HSP code (copy & paste)'

            TextInput:
                id: text_hsp_code
                multiline: True
                text: ''

            TextInput:
                id: text_log
                multiline: True
                text: ''
```

しかし、次のようなエラーが発生しました。

```console
D:\space1\Python\ShoeBoxToHPS\venv\Scripts\python.exe D:\space1\Python\ShoeBoxToHPS\main.py
[INFO   ] [Logger      ] Record log in C:\Users\Username\.kivy\logs\kivy_18-08-05_41.txt
[INFO   ] [Kivy        ] v1.10.1
[INFO   ] [Python      ] v3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)]
[INFO   ] [Factory     ] 194 symbols loaded
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_gif (img_sdl2, img_pil, img_ffpyplayer ignored)
[CRITICAL] [Text        ] Unable to find any valuable Text provider.
sdl2 - ImportError: DLL load failed: 指定されたモジュールが見つかりません。
  File "D:\space1\Python\ShoeBoxToHPS\venv\lib\site-packages\kivy\core\__init__.py", line 59, in core_select_lib
    fromlist=[modulename], level=0)
  File "D:\space1\Python\ShoeBoxToHPS\venv\lib\site-packages\kivy\core\text\text_sdl2.py", line 12, in <module>
    from kivy.core.text._text_sdl2 import (_SurfaceContainer, _get_extents,

pil - ModuleNotFoundError: No module named 'PIL'
  File "D:\space1\Python\ShoeBoxToHPS\venv\lib\site-packages\kivy\core\__init__.py", line 59, in core_select_lib
    fromlist=[modulename], level=0)
  File "D:\space1\Python\ShoeBoxToHPS\venv\lib\site-packages\kivy\core\text\text_pil.py", line 7, in <module>
    from PIL import Image, ImageFont, ImageDraw

[CRITICAL] [App         ] Unable to get a Text provider, abort.

Process finished with exit code 1
```

ぐぐってみると pygame パッケージをいれろとか、いろいろ書いてありました。
しかし、いれてもだめでした。
sdl2 という項目が、最初に紹介した pip によるインストール方法([Setting Up Kivy with various popular IDE's · kivy/kivy Wiki](https://github.com/kivy/kivy/wiki/Setting-Up-Kivy-with-various-popular-IDE's#setting-up-kivy-190-with-pycharm-45-eap-on-os-x-10103))に書いてあったので、そこでインストールしていたパッケージをすべてさきほどの PyCharm の Settings ウィンドウの Project Interpreter から追加しました。
追加したパッケージは次のとおりです。

- pypiwin32
- kivy.deps.sdl2
- kivy.deps.glew
- kivy.deps.gstreamer
- kivy.deps.angle
- kivy_examples

docutils と pygments は最初からはいっていたのでここで追加はしませんでした。
kivy_examples はサンプルですが、何かと便利そうなので PyCharm で扱えるようにしておきました。

これらのパッケージをインストールして実行すると次のようにウィンドウがデザインはともかく表示されました。

![はじめて表示されたkivy製のウィンドウ.png](https://qiita-image-store.s3.amazonaws.com/0/46088/b17f50cf-9680-dbf8-f642-fb27f974a400.png)

# kivy の資料
[Kivy 1.11.0.dev0 documentation](https://kivy.org/docs/)に、サンプルなどがあるので、それを参考に使ってみようと思います。

#便利なkivy-garden(FileBrowser)をPyCharmで使う
[FileChooser — Kivy 1.11.0.dev0 documentation](https://kivy.org/docs/api-kivy.uix.filechooser.html)を参考にしてFileChooserListViewを表示してみたのですが、 windows では、ドライブ選択ができず実行ファイルのあるドライブの中しか選択できませんでした。

![kivyのFileChooser.png](https://qiita-image-store.s3.amazonaws.com/0/46088/4edd42c0-07c8-b0e2-769f-6a1407e62a1f.png)

これは良くわからないと思いますが D ドライブのルートのファイルやフォルダの一覧です。
上へ行くための項目はありません。

ドライブ選択をリストで追加する方法を紹介しているサイトがありました。
[Python kivy: how to use filechooser access files outside C drive - Stack Overflow](https://stackoverflow.com/questions/26028235/python-kivy-how-to-use-filechooser-access-files-outside-c-drive)

さらに調べると、 kivy-garden という kivy の拡張機能のようなライブラリがあり、 FileBrowser という FileChooser の強化版でドライブ選択もできるパッケージがありました。
[kivy-garden/garden.filebrowser: An advanced file browser.](https://github.com/kivy-garden/garden.filebrowser)

FileBrowser 以外にもさまざまな機能があり、それを紹介している Qiita もありました。
[Kivyの庭を歩く - Qiita](https://qiita.com/gotta_dive_into_python/items/4180a6601502486918d7)

さっそく、[kivy-garden/garden.filebrowser: An advanced file browser.](https://github.com/kivy-garden/garden.filebrowser)のテストコードを使ってみたのですが、FileBrowser が Unresolved でエラーになります。

```test.py
from os.path import sep, expanduser, isdir, dirname
import sys
from kivy.garden.filebrowser import FileBrowser

# https://github.com/kivy-garden/garden.filebrowser
class TestApp(App):

    def build(self):
        if sys.platform == 'win':
            user_path = dirname(expanduser('~')) + sep + 'Documents'
        else:
            user_path = expanduser('~') + sep + 'Documents'
        browser = FileBrowser(select_string='Select',
                              favorites=[(user_path, 'Documents')])
        browser.bind(
                    on_success=self._fbrowser_success,
                    on_canceled=self._fbrowser_canceled)
        return browser

    def _fbrowser_canceled(self, instance):
        print('cancelled, Close self.')

    def _fbrowser_success(self, instance):
        print(instance.selection)

if __name__ == '__main__':
    TestApp().run()

```

venv/lib/site-package/kivy/garden フォルダがありましたが、この中は空っぽでした。
そこで、[Kivyのmapviewを試してみた - Qiita](https://qiita.com/Ds110/items/95d9fcacb5c73ae63fef) を参考にしてまずは pip と garden コマンドで別の場所にパッケージをインストールしました。

```console
>pip install kivy-garden
...
>garden install filebrowser
...
Done! garden.filebrowser is installed at: C:\Users\Username\.kivy\garden\garden.filebrowser
```

これで、 C:\Users\Username\.kivy\garden フォルダに、 graden.filebrowser のフォルダができてパッケージがインストールされました。
これを先ほどの PyCharm のプロジェクトの venv/lib/site-package/kivy/garden の中にコピーしました。
フォルダ名は garden.filebrowser から filebrowser に変えました。
これで、 from kivy.garden.filebrowser import FileBrowser のパスが有効になり、先ほどの TestApp のコードが実行できるようになり、次のような FileBrowser のウィンドウが表示できました。

![kivy.garden.filebrowserのテスト.png](https://qiita-image-store.s3.amazonaws.com/0/46088/760d4a18-189b-845f-39cc-964bf51afc8f.png)

これで、複数ドライブにアクセスできて、デスクトップなどへのアクセスも簡単になりました。


# 参考リンク
- [Kivy](https://kivy.org/#home)
- [Python](https://www.python.org/)
- [【Python】GUIライブラリの比較・おすすめ | アルゴリズム雑記](https://algorithm.joho.info/programming/python/gui-library-py/)
- [Setting Up Kivy with various popular IDE's · kivy/kivy Wiki](https://github.com/kivy/kivy/wiki/Setting-Up-Kivy-with-various-popular-IDE's#setting-up-kivy-190-with-pycharm-45-eap-on-os-x-10103)
- [PyCharm](https://www.jetbrains.com/pycharm/)
- [PyCharmによるパッケージの追加方法 - Qiita](https://qiita.com/yamaAtsu/items/34e2a04408695365d586)
- [Kivy 1.11.0.dev0 documentation](https://kivy.org/docs/)
- [FileChooser — Kivy 1.11.0.dev0 documentation](https://kivy.org/docs/api-kivy.uix.filechooser.html)
- [Kv language(翻訳済み) — Kivy 1.10.0 ドキュメント](https://pyky.github.io/kivy-doc-ja/guide/lang.html)
- [Python kivy: how to use filechooser access files outside C drive - Stack Overflow](https://stackoverflow.com/questions/26028235/python-kivy-how-to-use-filechooser-access-files-outside-c-drive)
- [kivy-garden/garden.filebrowser: An advanced file browser.](https://github.com/kivy-garden/garden.filebrowser)
- [Kivyの庭を歩く - Qiita](https://qiita.com/gotta_dive_into_python/items/4180a6601502486918d7)
- [Kivyのmapviewを試してみた - Qiita](https://qiita.com/Ds110/items/95d9fcacb5c73ae63fef)