きっかけ
Windowsのスタートアップに入れて
設定日時になるとウィンドウにメッセージを表示し警告音を出そうとしたのですが
pythonのtkinterでGUIを非表示(destroy)するとpython自体が落ちるので困っていた
勉強不足なのかもしれないけれどメッセージボックスは別のアプリの陰に表示されるし思い通りに操作出来ないし(特にcommandあたり)
ダメなコード?
destroy
で非表示(削除が正しい?)にしgui関数で再表示(描画)してやるー!
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
です
コード
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を検索しても執筆当時は2件
pythonのtkinterだと1件という少なさから記事を書いてみようと思いました
違いもわからないのに!
python attribute root.destroy() と root.quit()の違いは何ですか?の記事もチョット気になります
お知らせ
GitHub始めてみました
拙いコードですが今回の後者のコードを応用して制作しました
GitHub