【Python】tkinterでGUIの表示・非表示？

#きっかけ

Windowsのスタートアップに入れて
設定日時になるとウィンドウにメッセージを表示し警告音を出そうとしたのですが
pythonのtkinterでGUIを非表示(destroy)するとpython自体が落ちるので困っていた
勉強不足なのかもしれないけれどメッセージボックスは別のアプリの陰に表示されるし思い通りに操作出来ないし(特にcommandあたり)

#ダメなコード？

`destroy`で非表示(削除が正しい？)にしgui関数で再表示(描画)してやるー！

```python:window_hide.py
import time
import tkinter as tk

import sched

# entry内の文字列をprint
def print_entry():
    global entry
    print(entry.get())

# 3秒経つとprint_entryを呼びます
# 5秒経つとguiを呼びます
def wait():
    s = sched.scheduler(time.time, time.sleep)
    s.enter(3, 1, print_entry)
    s.enter(5, 1, gui)
    s.run()

# ウィンドウをデストロイしwaitを呼びます
def window_hide():
    global root
    root.destroy()
    wait()

# ウィンドウを描画します
def gui():
    global root, entry
    root = tk.Tk()
    root.attributes('-topmost', True)
    root.geometry('+0+0')
    root.title('お知らせ')

    label = tk.Label(root, text='通知です')
    label.pack(fill='x')
    button = tk.Button(root, text='OK', command=window_hide)
    button.pack(fill='x')
    entry = tk.Entry(root)
    entry.pack(fill='x')
    entry.delete(0, tk.END)
    entry.insert(tk.END, 'test')

    root.mainloop()

def main():
    gui()

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

初期のコードを消してしまったので適当に書きました間違ってたらごめんなさい

wait関数内で3秒後のprint_entryを呼び出すとエラーで落ちます
ループしないので楽しく無いです

#落ちないでprintしループする方法

`withdraw`で非表示にできるのならば表示する方法があるはず
と検索して出てきたのが`deiconify`です

#コード

```python:window_hide.py
import time
import tkinter as tk

import sched

# entry内の文字列をprint
def print_entry():
    global entry
    print(entry.get())

# 3秒経つとprint_entryを呼びます
# 5秒経つとwindow_displayを呼びます
def wait():
    s = sched.scheduler(time.time, time.sleep)
    s.enter(2, 1, print_entry)
    s.enter(5, 1, window_display)
    s.run()

# ウィンドウを表示
def window_display():
    global root
    root.deiconify()

# ウィンドウを非表示にしwaitを呼びます
def window_hide():
    global root
    root.withdraw()
    wait()

# main関数でウィンドウを描画します
def main():
    global root, entry
    root = tk.Tk()
    root.attributes('-topmost', True)
    root.title('お知らせ')

    label = tk.Label(root, text='通知です')
    label.pack(fill='x')
    button = tk.Button(root, text='OK', command=window_hide)
    button.pack(fill='x')
    entry = tk.Entry(root)
    entry.pack(fill='x')
    entry.delete(0, tk.END)
    entry.insert(tk.END, 'test')

    root.mainloop()

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

無事に`entry`の文字列を`print`しループしています
**※こちらループしますのでご注意ください**


#最後に

###前者のコード
`mainloop`を`destroy`してしまうため非表示中の`entry`を読み込めずにエラーを起こします
エラーを起こさない様に記述した場合ウィンドウを再描画しているためチョット違った挙動になったりします

###後者のコード
あくまでも「非表示」なので非表示中の`entry`も読み込むことができます
環境によりますが非表示なので再表示で~~同じ座標に表示されます~~

**追記：**
Mac Mojaveの場合は同じ座標でしたが
Xubuntuではウィンドウの状態により真ん中だったり左上だったり
Windowsは手持ちに環境が無いので後に追記します

**他に違いのわかる方いらっしゃったらご教示お願いいたします**

#おまけの戯言

本来は非表示中にラベルやボタンの表示を変えようとしてpythonが落ちてたのですが
再現できるコードが書けないため(おばか)強引にプリントでごまかしてます
多分ですが下記のGitHubに上げたコードはそれを利用してると思います

[Qiitaでdeiconifyを検索](https://qiita.com/search?q=deiconify)しても執筆当時は2件
pythonのtkinterだと1件という少なさから記事を書いてみようと思いました
違いもわからないのに！

[python attribute root.destroy() と root.quit()の違いは何ですか?](https://code-examples.net/ja/q/233588)の記事もチョット気になります

######お知らせ

GitHub始めてみました
拙いコードですが今回の後者のコードを応用して制作しました
[GitHub](https://github.com/mushroominger/measurement_date/blob/master/measurement_date_sn_ver.py)