PythonのtkinterでGUIを作ってみる_その２

## 過去のおはなし
[PythonのtkinterでGUIを作ってみる](https://qiita.com/daisuke8000/items/9b6bb05e78f2bbc0c315)

GUIはまだまだ奥が深いなぁと思ったので投稿します。

＜Github＞
[20191029_GUIのサンプル2.py](https://github.com/daisuke8000/WorkRecord/blob/master/20191029_GUI%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB2.py)

## 今回のおはなし「grid」と「StringVar」
gridはWidgetを配置するための手法みたいなやつです。（違う？）
「pack」とか「place」とかあります。（ちなみに前回はplaceでした）
昨日、今日に触る機会があったのでちょっとお勉強がてらやってみました。

## 感想
個人的な感想だが、考え方が少し抵抗ある。
直感的なのはplaceかなぁ。と思う。
gridはなんとなくだが、開発者っぽい考え方だなぁって印象でした。


## コード

```py

import tkinter as tk

#ボタンバインド用関数
def btn_click():
  onp = textbox1.get()
  var.set(onp)
  if len(onp)!=8:
    var1.set('Error')
  else:
    var1.set('Success')

#MainWindow
root = tk.Tk()
root.title(u"Input-Output app")
width = 400
height = 200
x = (root.winfo_screenwidth() - width) // 2
y = (root.winfo_screenheight() - height) // 2
geometory = f'{width}x{height}+{x}+{y}'  # ここは小文字のｘじゃなきゃだめ
root.geometry(geometory)

#ラベル更新用
var = tk.StringVar()
var.set("Waiting…")
var1 = tk.StringVar()
var1.set("Waiting2…")

#Frame_grid
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)

#Frame_wiget
frame = tk.Frame(root)
btn = tk.Button(frame, text='Push', command=btn_click)
textbox1 = tk.Entry(frame, width=40)
textbox1.bind("<Key-Return>",  lambda x:btn_click())
label2_1 = tk.Label(frame, text='Ouput',width = 10)
label2_2 = tk.Label(frame, textvariable=var,width = 10)
label3_1 = tk.Label(frame, text='Result',width = 10)
label3_2 = tk.Label(frame, textvariable=var1,width = 10)

#Wiget_Grid
frame.grid(row=0, column=0, sticky='nwse')
frame.grid_columnconfigure((0, 1, 2 ,3), weight=1)
frame.grid_rowconfigure((0, 1 ,2), weight=1)

#
btn.grid(row=0, column=0)
textbox1.grid(row=0, column=1, columnspan=2)
label2_1.grid(row=1, column=0)
label2_2.grid(row=1, column=1, columnspan=2)
label3_1.grid(row=2, column=0)
label3_2.grid(row=2, column=1, columnspan=2)

root.mainloop()

```

## grid
ウィンドウを座標でせこせこ調整していくplaceに対し、gridは配列と行に当て込んでいくようなイメージ。
意見色々ありそうだが、gridの考え方が結構お気に入りです。
なんか…開発者っぽいなぁって。(わかったよw)
なお、このコードを走らせると以下のような画面になる。
これを自己解釈で解説してみる。(つまり独り言だなw)

<img width="328" alt="無題.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493685/dd8f08d2-86bd-d245-e766-3981e2126933.jpeg">

コードでいうこの辺でまず枠(MainWindow)を作る
これがないと始まらないぜ。

```MainWindow.py
#MainWindow
root = tk.Tk()
root.title(u"Input-Output app")
width = 400
height = 200
x = (root.winfo_screenwidth() - width) // 2
y = (root.winfo_screenheight() - height) // 2
geometory = f'{width}x{height}+{x}+{y}'  # ここは小文字のｘじゃなきゃだめ
root.geometry(geometory)
```

次にMainWindowに表示するFrameなるもののを作る。

```Frame_grid.py
#Frame_grid
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
```
これはgridでroot上にFrameの設置位置を設定している段階みたい。
（MainWindowに「行0」と「列0」を定義するっていうのかな？）
なお、このFrameは可視化されないのでなんとなくあるんだろーなー
くらいに思ってください。

ホントは概念みたいなものがあるんだろうがとりあえず次。

```Frame_wiget.py

#Frame_wiget
frame = tk.Frame(root)
btn = tk.Button(frame, text='Push', command=btn_click)
textbox1 = tk.Entry(frame, width=40)
textbox1.bind("<Key-Return>",  lambda x:btn_click())
label2_1 = tk.Label(frame, text='Ouput',width = 10)
label2_2 = tk.Label(frame, textvariable=var,width = 10)
label3_1 = tk.Label(frame, text='Result',width = 10)
label3_2 = tk.Label(frame, textvariable=var1,width = 10)
```

1番上の文はさっきの設定位置にframeが設定されたみたいです。
それ以降はframeの文字が並ぶ通り、frame上に設定するbtnやらtextboxやらlabelやらの部品がどんどん作られています。
（まだ無いよ）

```Wiget_Grid.py

#Wiget_Grid
frame.grid(row=0, column=0, sticky='nwse')
frame.grid_columnconfigure((0, 1, 2), weight=1)
frame.grid_rowconfigure((0, 1 ,2), weight=1)

```

さっきやったことと一緒っすね。
今度はframe上にgridを表示しているみたい。
色んなとこを調べたあとの僕の解釈ですがgridの名が示すようにこういうことなのかなと理解してます。

<img width="329" alt="無題1.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493685/f8d92990-2e10-b4da-604c-0a79c12977e4.jpeg">

どっかのサイトでも方眼紙と見立てるようなことおっしゃっていられたような…。

```wiget.py

#
btn.grid(row=0, column=0)
textbox1.grid(row=0, column=1, columnspan=2)
label2_1.grid(row=1, column=0)
label2_2.grid(row=1, column=1, columnspan=2)
label3_1.grid(row=2, column=0)
label3_2.grid(row=2, column=1, columnspan=2)

root.mainloop()
```

んで、最後にさっき作った部品（wiget）にgrid位置を指定してあげて
root.mainloop()でひとまず完成。

どうだろうか？座標で位置を設定するよりもずっとスタイリッシュじゃない？


##StringVar

上の説明ではスルーしたがこれがすごくよかったので紹介しておく。

```StringVar(その１).py
#ラベル更新用
var = tk.StringVar()
var.set("Waiting…")
var1 = tk.StringVar()
var1.set("Waiting2…")
```

```StringVar(その２).py

label2_2 = tk.Label(frame, textvariable=var,width = 10)
label3_2 = tk.Label(frame, textvariable=var1,width = 10)
```

```StringVar(その３).py

#ボタンバインド用関数
def btn_click():
  onp = textbox1.get()
  var.set(onp)
  if len(onp)!=8:
    var1.set('Error')
  else:
    var1.set('Success')
```

これは、「その１」と「その２」で先に表示しておく文字を設定しておくのだが、関数にあるようにボタンを押すと表示が更新される。
これは個人的になかなかうれしい。
いちおう作成時には8桁の数字を照合させる意味合いで作っていたので8文字入力されれば「Success」、未満or超過すると「Error」が表示される。

## なるべくわかりやすくまとめたい
みづらい内容ですいません。
分かりやすく書いてる人はたくさんいると思うのでわからない人はそっち見ましょう。