Slide 1

Slide 1 text

Pythonでデスクトップ アプリを簡単に作る方法 2020年2月27日 オカザキ 1 PyCon miniShizuoka 発表用

Slide 2

Slide 2 text

お品書き 1. 一部 PythonのGUIについて 2. 二部 tkinterについて 3. 三部 PySimpleGUIについて 4. 四部 PySimpleGUIのアプリの例 2

Slide 3

Slide 3 text

自己紹介 • オカザキ(@dario_okazaki) • 所属:(株)スカラコミュニケーション ズ • 職業:サーバーサイドエンジニア • PyconJP2017 トーク「Kivyによるアプ リケーション開発のすすめ」 • 長野Python会 with NSEG(2018/7/28) 「PythonのGUI@2018」 3

Slide 4

Slide 4 text

会社紹介 • 株式会社スカラコミュニケーションズ • https://scala-com.jp/ • BtoB向けのシステム開発 • メインの開発はPHP, • Python,C#でも開発 • 所在地:渋谷ヒカリエ(1月~) • エンジニア募集中 4

Slide 5

Slide 5 text

問題提起 私はPythonで○○○がしたい。 だから○○○は○○○でいい 5

Slide 6

Slide 6 text

今日説明するデスクトップアプリについて 画面遷移が3枚程度の簡単なアプリを 想定しています 6

Slide 7

Slide 7 text

質問 • PythonのGUIライブラリってつかったことありますか? • つかった人はどんなライブラリを使われました? • You tube liveのコメントに書いてみてください 7

Slide 8

Slide 8 text

お品書き 1. 一部 PythonのGUIについて 2. 二部 tkinterについて 3. 三部 PySimpleGUIについて 4. 四部 PySimpleGUIのアプリの例 8

Slide 9

Slide 9 text

PythonでのGUIの立ち位置(1/2) 9 JET BRAINSのThe State of Developer Ecosystem 2019のPythonより

Slide 10

Slide 10 text

PythonでのGUIの立ち位置(2/2) JET BRAINSのThe State of Developer Ecosystem 2019のPythonより 10 • Pythonを使う上ではメジャーではない

Slide 11

Slide 11 text

PythonのGUIについて(1/3) • ライブラリの数は多いが決定的なものはない 11 • Tkinter • wxPython • PyQt5 ※QT系 • PySide2 ※QT系 • pySimplelGUI • PyGTK • PyFLTK • Kivy • Eel • flexx • REMI • Electron + Python※2 • React Native + Transcrypt(altJS)※2 • Pygame • Toga ※Qt系はそれぞれ開発元とライセンスが違います ※2はライブラリではなくて手法です

Slide 12

Slide 12 text

PythonのGUIについて(2/3) 12 • cefpython • PyGObject • Pyglet • PyGUI • libavg • Pyforms etc・・・

Slide 13

Slide 13 text

PythonのGUIについて(3/3) • その他(Android端末で動くもの) • QPython ※Andoridで動くIDE • Pydroid3 ※Andoridで動くIDE • LINE MessageAPI※Lineアプリ上で動くもの • IOSだとPythonistaというアプリがある 13

Slide 14

Slide 14 text

日本のPythonのGUIについて • 初心者向けの本でGUIだとPygameとtkinterを使う本が増えて きたように感じる • 日本だと機械学習、統計などのデータサイエンスの利用例が多 くGUIはメジャーではない 14

Slide 15

Slide 15 text

検証環境について • Windows10 • Python3.7.6 ※一部の機能についてはmacOS(Catalina)でも確認 15

Slide 16

Slide 16 text

サンプルコードについて • サンプルコードはGithubにおいてます • https://github.com/okajun35/for_pycon_shizu 16

Slide 17

Slide 17 text

お品書き 1. 一部 PythonのGUIについて 2. 二部 tkinterについて 3. 三部 PySimpleGUIについて 4. 四部 PySimpleGUIのアプリの例 17

Slide 18

Slide 18 text

tkinterについて(1/3) • Pythonの標準GUI • 環境構築が不要 • Pythonのインストール時に一緒にインストールされる • 公式リファレンスにドキュメントがある • Tk を用いたグラフィカルユーザインターフェイス 18

Slide 19

Slide 19 text

tkinterについて(2/3) • Pythonの標準IDEである「IDLE」にも使われている • Tcl/TkのTk部分を移植している • Tcl/TK自体は初リリースは1998年! 19

Slide 20

Slide 20 text

tkinterについて(3/3) パーソナルコンピュータの基本ソフトウェアとウィンドウ環境としては Windows, macOS, Linux/X-Window など複数のものが使われており、それぞれにウィンドウ の 描画などは異なった方法で行われます。これらの OS/ウィンドウ環境の差異を 吸収 し、共通に使える GUI 用のフレームワークとして Tcl/Tk があります。 tkinter はこの Tcl/Tk を Python から利用できるようにしたパッケージです 20 ~ 京都大学 プログラミング演習 Python 2019 Version2020_02_13_01.pdf から引用 ~

Slide 21

Slide 21 text

GUIの基本 GUI 型のアプリケーションでは、メニューやボタンなどによるさ まざまな操作を ユーザ自身が選択して利用します。そして、操作 に対してコンピュータが適切に応 答することを期待します。 このようなユーザの操作を「イベント」と呼びます。多くの GUI 型のアプリケーションは GUI 用の「フレームワーク」を利用しま す。 フレームワークはマウスやキーボードの操作を監視してイベントを 検出し、プロ グラマーによって設定されたイベント処理用のプロ グラムを呼び出します。 フレームワークを用いた GUI 型のアプリ ケーションではプログラマーは主として 以下のような部分のプロ グラミングを担います。 イベントが発生した際に行う処理の定義 このようなプログラミン グをイベントに対する応答を主に記述することからイベン ト駆動 型 (event-driven) プログラミングと呼びます。 21 ~ 京都大学 プログラミング演習 Python 2019 Version2020_02_13_01.pdf から引用 ~

Slide 22

Slide 22 text

tkinterの基本 import tkinter from tkinter import messagebox #ボタンがクリックされたら実行 def button_click(): input_value = input_box.get() messagebox.showinfo("クリックイベント",input_value + "が入力されまし た。") #ウインドウの作成 root = tkinter.Tk() root.title("Python GUI") root.geometry("360x240") #入力欄の作成 input_box = tkinter.Entry(width=40) input_box.place(x=10, y=100) #ラベルの作成 input_label = tkinter.Label(text="ラベル") input_label.place(x=10, y=70) #ボタンの作成 button = tkinter.Button(text="実行ボタン",command=button_click) button.place(x=10, y=130) #ウインドウの描画 root.mainloop() 22

Slide 23

Slide 23 text

tkinterの問題点(1/2) import tkinter from tkinter import messagebox ~~~省略~ #ウインドウの作成 root = tkinter.Tk() root.title("Python GUI") root.geometry("360x120") # 名前 input_name_label = tkinter.Label(text="名前") input_name_label.grid(row=1, column=1, padx=10,) # 入力欄の作成 input_name = tkinter.Entry(width=40) input_name.grid(row=1, column=2) # 住所 input_address_label = tkinter.Label(text="住所") input_address_label.grid(row=2, column=1, padx=10,) # 住所入力欄の作成 input_address = tkinter.Entry(width=40) input_address.grid(row=2, column=2) # 電話番号 input_phone_label = tkinter.Label(text="名前") input_phone_label.grid(row=3, column=1, padx=10,) # 電話番号入力欄の作成 input_phone = tkinter.Entry(width=40) input_phone.grid(row=3, column=2) 23

Slide 24

Slide 24 text

tkinterの問題点(2/2) • 書き方がPython的でない→忘れ る • レイアウトが縦、横のグリッド で指定するのでよくわからない root.geometry("360x240") # 入力欄の作成 input_name = tkinter.Entry(width=40) input_name.grid(row=1, column=2) # 住所 input_address_label = tkinter.Label(text="住所") input_address_label.grid(row=2, column=1, padx=10,) # 住所入力欄の作成 input_address = tkinter.Entry(width=40) input_address.grid(row=2, column=2) # 電話番号 input_phone_label = tkinter.Label(text="名前") input_phone_label.grid(row=3, column=1, padx=10,) # 電話番号入力欄の作成 input_phone = tkinter.Entry(width=40) input_phone.grid(row=3, column=2) 24

Slide 25

Slide 25 text

お品書き 1. 一部 PythonのGUIについて 2. 二部 tkinterについて 3. 三部 PySimpleGUIについて 4. 四部 PySimpleGUIのアプリの例 25

Slide 26

Slide 26 text

PySimpleGUIの紹介 • https://pysimplegui.readthedocs.io/en/latest/ • 2018年にできたライブラリー • TkinterのラッパーでPythonライクに書けるのが特徴 • 派生でwxPython、PyQtのラッパーライブラリーも存在 • 公式では元のライブラリで書くのに比べてコード量が1/2~1/10になると説明 • Githubでは3,000スター • ライセンスはLGPL-3.0 26

Slide 27

Slide 27 text

インストール • Pure Pythonなのでインストールは簡単 pip install pysimplegui or pip3 install pysimplegui 27

Slide 28

Slide 28 text

基本の形 (1/8) import PySimpleGUI as sg # セクション1 - オプションの設定と標準レイアウト sg.theme('Dark Blue 3') layout = [ [sg.Text('Python GUI')], [sg.Text('名前', size=(15, 1)), sg.InputText('○○〇×××')], [sg.Text('住所', size=(15, 1)), sg.InputText('△△△△村')], [sg.Text('電話番号', size=(15, 1)), sg.InputText('xxx-xxx-xxx')], [sg.Submit(button_text='実行ボタン')] ] # セクション 2 - ウィンドウの生成 window = sg.Window('住所を入力', layout) # セクション 3 - イベントループ while True: event, values = window.read() if event is None: print('exit') break if event == '実行ボタン': show_message = "名前:" + values[0] + 'が入力されました。¥n' show_message += "住所:" + values[1] + 'が入力されました。¥n' show_message += "電話番号:" + values[2] + "が入力されました。" print(show_message) # ポップアップ sg.popup(show_message) # セクション 4 - ウィンドウの破棄と終了 window.close() 28

Slide 29

Slide 29 text

基本の形 (2/8) 1.テーマ 2.レイアウト 3.ウィンドウの設定 4.イベント 29

Slide 30

Slide 30 text

基本の形(テーマ) (3/8) # セクション1 - オプションの設定と標準レイアウト sg.theme('Dark Blue 3') 30

Slide 31

Slide 31 text

基本の形(レイアウト) (4/8) • レイアウトはリストで記載できる layout = [ [sg.Text('Python GUI')], [sg.Text('名前', size=(15, 1)), sg.InputText('○○〇×××')], [sg.Text('住所', size=(15, 1)), sg.InputText('△△△△村')], [sg.Text('電話番号', size=(15, 1)), sg.InputText('xxx-xxx-xxx')], [sg.Submit(button_text='実行ボタン')] ] 31

Slide 32

Slide 32 text

基本の形(レイアウト)(5/8) • リストを入れ子にして作ることも可能 • 見やすい frame1 = sg.Frame('住所', [[sg.Text('郵便番号', size=(15, 1))], [sg.InputText(key='-POST-NUM-')], [sg.Text('都道府県', size=(15, 1), )], [sg.InputText(key='-PREFECTURES-')], [sg.Text('住所', size=(15, 1))], [sg.InputText(key='-ADDRESS-')], ], relief=sg.RELIEF_SUNKEN, tooltip='住所をいれてね!') layout = [ [sg.Text('Python GUI')], [sg.Text('名前', size=(15, 1)), sg.InputText( default_text='○○〇×××', key='-USER-NAME-')], [sg.Text('住所を入れてね', size=(15, 1)), frame1], # frame1のレイアウトを入れ 子にして入れている [sg.Text('電話番号', size=(15, 1)), sg.InputText( default_text='xxx-xxx-xxx', key='-PHONE-NUM-')], [sg.Submit('実行ボタン')] ] 32

Slide 33

Slide 33 text

基本の形(ウィンドウの設定)(6/8) # セクション 2 - ウィンドウの生成 window = sg.Window('住所を入力', layout) • ウィンドウ、フォントなどのサイズを指定しなくても 自動でサイズを調整してくれる • サイズを指定して変更も可能 • ウィンドウは透明度の設定も可能 # セクション 2 - ウィンドウの生成 window = sg.Window('住所を入力', size=(300, 200)) 33

Slide 34

Slide 34 text

基本の形(イベント)(7/8) • ボタンのタイトルをイベント名として取得できる • 各項目(widget※)の値はリストで取得可能 ※: GUI を構成するボタンなどの部品 layout = [ [sg.Text('Python GUI')], [sg.Text('名前', size=(15, 1)), sg.InputText('○○〇×××')], [sg.Text('住所', size=(15, 1)), sg.InputText('△△△△村')], [sg.Text('電話番号', size=(15, 1)), sg.InputText('xxx-xxx-xxx')], [sg.Submit(button_text='実行ボタン')] ] # セクション 3 - イベントループ while True: event, values = window.read() if event == '実行ボタン': show_message = "名前:" + values[0] + 'が入力されました。¥n' show_message += "住所:" + values[1] + 'が入力されました。¥n' show_message += "電話番号:" + values[2] + "が入力されました。" print(show_message) # ポップアップ sg.popup(show_message) 34

Slide 35

Slide 35 text

基本の形(イベント)(8/8) • 各パーツにKeyを設定して、 Keyを指定して値を取得する ことも可能 frame1 = sg.Frame('住所', [[sg.Text('郵便番号', size=(15, 1))], [sg.InputText(key='-POST-NUM-')], [sg.Text('都道府県', size=(15, 1), )], [sg.InputText(key='-PREFECTURES-')], [sg.Text('住所', size=(15, 1))], [sg.InputText(key='-ADDRESS-')], ], relief=sg.RELIEF_SUNKEN, tooltip='住所をいれてね!') layout = [ [sg.Text('Python GUI')], [sg.Text('名前', size=(15, 1)), sg.InputText( default_text='○○〇×××', key='-USER-NAME-')], [sg.Text('住所を入れてね', size=(15, 1)), frame1], [sg.Text('電話番号', size=(15, 1)), sg.InputText( default_text='xxx-xxx-xxx', key='-PHONE-NUM-')], [sg.Submit('実行ボタン')] ] # セクション 3 - イベントループ while True: event, values = window.read() if event == '実行ボタン': print(values) show_message = "名前:" + values['-USER-NAME-'] + 'が入力されました。¥n' show_message += "郵便番号:" + values['-POST-NUM-'] + 'が入力されました。¥n' show_message += "都道府県:" + values['-PREFECTURES-'] + 'が入力されました。¥n' show_message += "住所:" + values['-ADDRESS-'] + 'が入力されました。¥n' show_message += "電話番号:" + values['-PHONE-NUM-'] + "が入力されました。" 35 valuesの中身 { '-USER-NAME-': '○○〇×××’, '-POST-NUM-': '210’, '-PREFECTURES-': '東京都’, '-ADDRESS-': '渋谷区’, '-PHONE-NUM-': 'xxx-xxx-xxx’ }

Slide 36

Slide 36 text

答え合わせ 私はPythonで機械学習がしたい。 だからGUI(値の入出力、結果表示)は こだわらなくてでいい ※答えは一例です人の数ほど答えがあります PySimpleGUIでGUIを簡単に作ろう!! 36

Slide 37

Slide 37 text

exe化(1/2) • PyInstllerを使用する • 以下のエラーが出た場合は、--hidden-import tkinter をオプション に加える • PyInstllerを使用したEXE化はオプションがあって色々難しい • Onefileにはしない • 3rd Party Libraly(PiPでインストールするライブラリー)は最初はアプリに使用し ない(importしない)→標準ライブラリのみでアプリを作ってみる pip install PyInstaller pyinstaller -wF my_program.py ValueError: script '.......¥src¥tkinter' not found 37

Slide 38

Slide 38 text

exe化(2/2) • 公式でPyInstllerを組み合わせたGUIがある • PySimpleGUI-exemaker • https://github.com/PySimpleGUI/PySimpleGUI/tree/master/exema ker • 1個のexeファイルになる 38

Slide 39

Slide 39 text

お品書き 1. 一部 PythonのGUIについて 2. 二部 tkinterについて 3. 三部 PySimpleGUIについて 4. 四部 PySimpleGUIのアプリの例 39

Slide 40

Slide 40 text

アプリの例(グラフ) • PySimpleGUIだけでも簡単なグラフは作れる • リアルタイムグラフやアニメーションもできる • Matplotlibの連携もできる • https://qiita.com/dario_okazaki/items/dc72976987d7ef485df1 40

Slide 41

Slide 41 text

アプリの例(グラフ2) • 公式のサンプル( https://pysimplegui.trinket.io/demo- programs#/graph-element/visualizing-sorts ) • 棒グラフの値をバブルソートで並べ替えるアニメーションのグラフ です 41

Slide 42

Slide 42 text

アプリの例(グラフ3) • 公式のサンプル(https://github.com/PySimpleGUI/PySimpleGUI- Rainmeter-CPU- Cores/blob/master/PySimpleGUI_Rainmeter_CPU_Cores.py) • CPUの値を表示するグラフです。背景が半透明だったりタブを 非表示にしています 42

Slide 43

Slide 43 text

アプリの例(VBAの代わりとして) • VBAの代わりとして • ファイルダイアログやリスト、ログを出力できる • https://qiita.com/dario_okazaki/items/4ba70e8a7ee1a6b024 e8 43

Slide 44

Slide 44 text

アプリの例(画像処理の入力、確認) • 「アスキーアートを自動生成する - Pythonでいろいろやってみる」https://tat-pytone.hatenablog.com/entry/2020/02/26/202205 のコードをお借りしてUIをつけてみました。 • UIつける作業自体は2時間程度 • 公式のデモを参考 https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Img_Viewer.py https://github.com/PySimpleGUI/PySimpleGUI-Photo-Colorizer 44

Slide 45

Slide 45 text

アプリの例 • PySimpleGUIには公式でサンプルがたくさんある • https://github.com/PySimpleGUI/PySimpleGUI 配下のデモ • https://pysimplegui.trinket.io/demo-programs • PySimpleGUIのみで作られたものやほかのライブラリを組み合わせた ものまで様々 • OpenCVを使った画像処理や機械学習による物体検出の例もある 45

Slide 46

Slide 46 text

おまけ アンドロイドでの実行について • Pydroid3で実行できる • https://play.google.com/store/apps/details?id=ru.iiec.pydroid3&hl=ja • 公式デモ: https://github.com/PySimpleGUI/PySimpleGUI/tree/master/DemoPro grams/PyDroid3 46

Slide 47

Slide 47 text

Macでの動作環境について • tkinterを場合によってはインストールする必要あり • インストール設定が色々面倒 • Tkinter自体がMacではIME(全角文字が入力中の時の文字)が出ない • PySimpleGUIWx(wxPythonのラッパー)を使用する 47

Slide 48

Slide 48 text

GUIを勉強する意味 • Webだと実際の運用だとインフラの知識が必要 • GUIだと自分の環境であれば失敗しづらい • デモ見せるときに優位 • オフライン環境、ネットがつながらない環境でも動く • パケット気にしない 48

Slide 49

Slide 49 text

まとめ • PySimpleGUIを使うと簡単にデスクトップアプリが作れる • tkinterを直接使うよりも簡単 • 簡単なグラフだったりVBAの代わりになるものも作れる 49

Slide 50

Slide 50 text

参考:英語のドキュメントの読み方(1/3) • PythonのGUIライブラリは日本語の記事が少ないです • 公式ドキュメント(英語)を読む • 詳しい記事はたいてい英語 50

Slide 51

Slide 51 text

参考:英語のドキュメントの読み方(2/3) • 英語と日本語の翻訳(Google翻訳)を並べて読む 51

Slide 52

Slide 52 text

参考:英語のドキュメントの読み方(3/3) • 難しい単語は辞書を引く • 参考:Chrome拡張の高速な英語辞書ツールをつ くりました(Mouse Dictionary) • https://qiita.com/wtetsu/items/c43232c6c44918e9 77c9 • IT用語など決まった用語には注意する • 例:「 separation of concerns」→「関心の分離 ( SoC )」※機械翻訳だと「懸念の分離」や「関心 事の分離」と訳されることがある 52