Windows10
Python 3.8.5
で動作確認しています
Python 3.8.5
で動作確認しています
追記:2022/01/24
Python 3.10.2でも動作しました
実現したいこと
・TkinterのGUI
・常駐する
・タスクトレイにアイコン
・Windowを閉じても、定期的に実行される
デジタル時計の作成
import tkinter as tk
import datetime
import time
#===========================
# タイマーイベント関数
#===========================
def time_update():
now = datetime.datetime.now()
tm = "{:02}:{:02}:{:02}".format(now.hour, now.minute, now.second)
canvas.delete("all")
canvas.create_text(100, 50, text=tm, font=("",36))
root.after(1000, time_update)
#===========================
# メイン 関数
#===========================
def main():
global root
global canvas
#-----------------------
# フォーム表示
#-----------------------
root = tk.Tk()
root.title("時計")
root.geometry("200x100")
root.resizable(False, False)
canvas = tk.Canvas(master=root, width=200, height=100)
canvas.place(x=0, y=0)
#-----------------------
# タイマー
#-----------------------
root.after(1000, time_update)
#-----------------------
# Xボタンを押された時の処理
#-----------------------
#root.protocol('WM_DELETE_WINDOW', lambda:root.withdraw())
#-----------------------
# イベント待機
#-----------------------
root.mainloop()
#===========================
# 実行
#===========================
main()
root.after(1000, time_update)を使うのがコツ
Xボタンを押された時の処理は、コメントアウト(コメント化)されてますが、常駐化アプリにするときに使います。
タスクトレイにアイコン表示
ライブラリの導入
pip install pystray
プログラム作成
https://githubmemory.com/repo/firedm/FireDM/issues/241
上記を参考に、pystrayの部分の型枠だけを作成しました
import threading
import pystray
from pystray import Icon, Menu, MenuItem
from PIL import Image
#===========================
# スレッド関係の関数
#===========================
def thread_st():
global icon
#-----------------------
# メニュー
#-----------------------
options_map = {'Quit': lambda: thread_quit()}
items = []
for option, callback in options_map.items():
items.append(MenuItem(option, callback, default=True if option == 'Show' else False))
menu = Menu(*items)
#-----------------------
# アイコン表示
#-----------------------
image = Image.open("favicon.ico")
icon=pystray.Icon("name", image, "My System Tray Icon", menu)
icon.run()
def thread_quit():
global icon
icon.stop()
#===========================
# メイン 関数
#===========================
def main():
#-----------------------
# スレッド開始
#-----------------------
threading.Thread(target=thread_st).start()
#===========================
# 実行
#===========================
main()
アイコンを表示させるだけなら、スレッドを使う必要はありません。あと、上記のサンプルは、Windows環境以外では動作しないと思います。
デジタル時計の常駐アプリ化
今まで作成した2つのプログラムをマージ(合成)する形で、時計アプリを常駐アプリ化します
import tkinter as tk
import datetime
import time
import threading
import pystray
from pystray import Icon, Menu, MenuItem
from PIL import Image
#===========================
# タイマーイベント関数
#===========================
def time_update():
now = datetime.datetime.now()
tm = "{:02}:{:02}:{:02}".format(now.hour, now.minute, now.second)
canvas.delete("all")
canvas.create_text(100, 50, text=tm, font=("",36))
root.after(1000, time_update)
#===========================
# スレッド関係の関数
#===========================
def thread_st():
global icon
global root
#-----------------------
# メニュー
#-----------------------
options_map = {'Show': lambda:[print('show_main_window'),root.after(0,root.deiconify)], 'Quit': lambda: root.after(1, thread_quit)} #変更 update
items = []
for option, callback in options_map.items():
items.append(MenuItem(option, callback, default=True if option == 'Show' else False))
menu = Menu(*items)
#-----------------------
# アイコン表示
#-----------------------
image = Image.open("favicon.ico")
icon=pystray.Icon("name", image, "My System Tray Icon", menu)
icon.run()
def thread_quit():
global icon
global root
icon.stop()
root.destroy() #追加 add
#===========================
# メイン 関数
#===========================
def main():
global root
global canvas
#-----------------------
# フォーム表示
#-----------------------
root = tk.Tk()
root.title("時計")
root.geometry("200x100")
root.resizable(False, False)
canvas = tk.Canvas(master=root, width=200, height=100)
canvas.place(x=0, y=0)
#-----------------------
# タイマー
#-----------------------
root.after(1000, time_update)
#-----------------------
# Xボタンを押された時の処理
#-----------------------
root.protocol('WM_DELETE_WINDOW', lambda:root.withdraw())
#-----------------------
# スレッド開始
#-----------------------
threading.Thread(target=thread_st).start()
#-----------------------
# イベント待機
#-----------------------
root.mainloop()
#===========================
# 実行
#===========================
main()
・右クリックメニューのメニュー部分
・Xボタン押下時の処理
・thread_quit()のroot.destroy()
マージして、上記のようなところを少し追加・修正しています。
動画での説明
Windowを閉じても、定期的(1秒毎)に実行されるのを、動画の最後のほうで確認しています。
#--------------
# 動作確認用
#--------------
f = open('./file00.txt', 'a')
f.write(tm)
f.write("\n")
f.close()
#--------------
上記のようなコードを挿入して、ファイルに時刻が出力されることで確認しました。
スポンサーリンク