【python】PySimpleGUIでログインを作ってみた！



# はじめに

今回は簡単にpythonでのGUI開発をしてみました。

pythonと聞いたら皆さんは恐らくデート分析、機械学習などを思い浮かべるでしょう。しかしpythonは実は簡単にGUIを使っちゃいます。しかも今回使ったライブラリーは簡単に扱え、非常に便利なものです。

ぜひ皆さんもpythonで自分だけのGUIを使ってみましょう！

# TL;DR

[ソースコード](https://github.com/YomamaBanana/Random_Scripts/blob/main/GUI/app.py)はこちら！

# デモ

![demo_login.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/ef4cec30-9f97-04e0-980b-8dedc3e3d6f9.gif)

# インストール

今回使うライブラリーはPySimpleGUIになります。

https://pysimplegui.readthedocs.io/en/latest/

まさに文字通り、**python-簡単-GUI**です。

```shell
$ pip install pysimplegui
```

importする際には小文字・大文字に注意してください。

```python
import PySimpleGUI as sg
```

# イメージ図

### 画面
まず最初に開発したい**ログイン画面**のイメージ図を書いてみましょう。ざっくりしたイメージは次の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/9fc880c2-0840-e9a6-5239-4be3cc3c9677.png)

### 機能

この画面に必要な機能は次のものが考えられる。

1. ボタンクリック（アクション）
2. 情報対照（ユーザー・パスワード）
3. メッセージ表示 （成功・失敗の場合）



# ソースコード

```python
# 必要なライブラリーをimportする
import PySimpleGUI as sg
import cv2
import numpy as np

# ENTERキーの定義
QT_ENTER_KEY1 = 'special 16777220'
QT_ENTER_KEY2 = 'special 16777221'

# ユーザー情報を対照関数
def validation(name, password):
    correct_data = ("user", "1234")
    if (name, password) == correct_data:
        return True
    return False

# レイアウトの定義
# こちらの書き方は本当に上のイメージ図通りで、Text, Button, Inputなど分かりやすい名前となっている。
def define_layout(logo):
    layout = [
        [sg.Text("ログイン画面", font=('Meiryo UI', 13), size=(20, 2), justification="center")],
        [sg.Text("名前：", size=(10, 1), font=('Meiryo UI', 9)), sg.Input("", size=(25, 1), key="-name-")],
        [sg.Text("パスワード：", size=(10, 1), font=('Meiryo UI', 9)), sg.Input("", password_char='*', size=(25, 1), key="-password-")],
        [sg.Button("LOGIN", size=(10, 1), font=('Meiryo UI', 9),enable_events=True, key="-login-", button_color="darkblue"), sg.Button("EXIT", size=(10, 1), font=('Meiryo UI', 9), enable_events=True, key="-exit-", button_color="darkred")],
        [sg.Image(source=logo, key="logo", pad=5)]
    ]
    return layout

# 今回は特別にロゴを入れる。
def define_logo(logo_path):
    logo = cv2.imread(logo_path)
    logo = cv2.resize(logo, (200,100))
    logo = cv2.cvtColor(logo, cv2.COLOR_RGB2RGBA)
    logo[np.where(np.all(logo[..., :3] == 0, -1))] = 0

　　# GUIに表示させるためバイトへ変換
    imgbytes = cv2.imencode('.png', logo)[1].tobytes()
    return imgbytes    

# メイン画面の定義
def create_window(title, layout, logo):
    window = sg.Window(title, layout, size=(420, 390), return_keyboard_events=True, margins=(10, 80),element_justification='center', finalize=True)
    window["logo"].update(data=logo)
    return window

# メイン関数
def main():
    sg.theme("DarkGrey14")
    imgbytes = define_logo("./assets/aifield.png")
    layout = define_layout(imgbytes)
    window = create_window("DEMO", layout, imgbytes)

    while True:
        event, values = window.read()
        # ESCキー、閉じる、EXITボタンを押すと終了する。
        if event in [sg.WIN_CLOSED, '-exit-', 'Escape:27']:
            break

        # LOGINボタンをクリックする。
        elif event in ["-login-", '\r', QT_ENTER_KEY1, QT_ENTER_KEY2]:
            # 入力情報を確認する。
            if validation(values["-name-"], values["-password-"]):
                window.Hide()
                window["-password-"].update(value="")
                window["-name-"].update(value="")
                sg.popup_no_buttons("Welcome", keep_on_top=True, auto_close=True, auto_close_duration=2)
                window.UnHide()                
            else:
                sg.popup_no_buttons("ERROR: 情報が一致しません。", keep_on_top=True, auto_close=True, auto_close_duration=2, no_titlebar=True, background_color="red")
                window["-password-"].update(value="")

    window.close()

if __name__ == "__main__":
    main()
```

# あとがき
pythonとpysimpleguiを使ってログイン画面を作ってみました。

Pysimpleguiとは本当に便利なライブラリーで、ソースコードが分かりやすく、「とりあえず開発」にはぴったりではないかと思います。

さらに開発者らがgithubにてデモプログラムを山ほど公開しており、ただただ動かしてみるだけでも面白いかもしれません！

https://github.com/PySimpleGUI/PySimpleGUI/tree/master/DemoPrograms