はじめに
どうも、趣味でデータ分析している猫背なエンジニアです。
今回は学生時代に作成したアーカイブ作品を公開いたします。作成時期は研究生時代真っ只中の2022年。生成AIもまだまだ普及しておらずハンドコーディングが主流の中、デスクトップアプリを作成しました。
今考えてみれば、いろいろ試行錯誤して調査して0からよくここまで作ったし、よほど時間があったのだろうなと思います。
今回はアーカイブ作品としてこれを投稿しますが、本記事の技術要素を用いてN-MAGIやKK-Adamの表示に今後取り組むことができたらいいなあと思い、掘り返しました👍
1. プロローグ
「シン・エヴァンゲリオン劇場版」の興行収入100億円超えおめでとうございます。小さい頃からエヴァンゲリオンが大好きで庵野秀明展も機会があったら行きたいと考えております。
私情はさておき、今回開発したアプリケーションはエヴァンゲリオンでも絶大な人気を誇る作戦、「ヤシマ作戦」を彷彿とさせるタイマーを開発しました。
2. 用途
長いスパンの目標を立てると途中で垂れてしまって、最終的に約束の期限を過ぎてしまい悲惨な事態になってしまうかもしれない…(例えば、研究論文提出日や納期など…(とても大事))
そんな時、このアプリケーションをデスクトップに画面表示させておくと、残りの時間が一目瞭然。作戦を遂行しているかのような臨場感と緊張感がある日常に変化し、大事な期限に「間に合わせなければ!」という意識改善ができると思います。意識改善という部分に着目し開発しました。
ロックな方からすると「なんといやらしいタイマーなんだ…」なんて言われそうですが(笑)
3. 操作方法(表示変更)
■ カウントダウン名と期限日時を設定する。
kigen_name_xxにはTODO名、text_xxにはTODOの英語表記,kigen_time_xxには期限日と時間を書くように設けております。プログラム内のこの部分をそれぞれ変更してファイルを保存します。
カウントダウンは最大で2つまでとなっています。

■ 完成画面
設定したプログラムを実行すると以下のように表示されます。作戦が完了すると「0日 0:0:0」と表示されます。
全ての作戦が終了しても表示されたままなので、作戦アプリを終了させたい時は赤ボタン(Mac)もしくは×ボタン(Win)を押すとプログラムが終了します。

4. 開発環境
■ 開発環境
- MacBook Air (13-inch, 2017)
- Jupyterlab 3.0.14
■ 試験環境(OS)
- mac OS(Big Sur)
- Windows OS(Windows 10 Pro)
■ Installation
- Python 3.7.4
- tkinter 8.6
- [けしのみ工房-keshikan.net]さまのDSEG(DSEG7 Classic Bold)
5. それぞれのインストール方法
インストールとしては、Python本体と装飾です。以下の二つが必要になってきますので、ダウンロードとフォントの登録をしてください。
■ Python - 公式HP
Pythonのインストールに関してはもともと入っていると仮定して省略いたします。もしPythonがインストールされていない場合は、公式HPでダウンロードしてください。
■ けしのみ工房-keshikan.net - DSEG
けしのみ工房からダウンロードをしてください。こちらは数字をセグメント表示するために使用せていただいております。
6. ソースコード
以下に作成したソースコードを記載致します。
# --- library ----
# Tkinter
import datetime
import tkinter as tk
# =========== 期限入力(変更部分) ===========
kigen_name_1 = "学士梗概集提出期限"
text_1 = "Deadline For Submitting Bachelor's Abstracts"
kigen_time_1 = "2022/3/6,19:4"
kigen_name_2 = "学士論文提出期限"
text_2 = "Deadline For Submission Of Bachelor's Papers"
kigen_time_2 = "2022/4/7,16:30"
# ========================================
kigen_1 = kigen_time_1.split(",")[0]
time_1 = kigen_time_1.split(",")[1]
year_1 = int(kigen_1.split("/")[0])
month_1 = int(kigen_1.split("/")[1])
day_1 = int(kigen_1.split("/")[2])
hour_1 = int(time_1.split(":")[0])
min_1 = int(time_1.split(":")[1])
kigen_2 = kigen_time_2.split(",")[0]
time_2 = kigen_time_2.split(",")[1]
year_2 = int(kigen_2.split("/")[0])
month_2 = int(kigen_2.split("/")[1])
day_2 = int(kigen_2.split("/")[2])
hour_2 = int(time_2.split(":")[0])
min_2 = int(time_2.split(":")[1])
target1_1 = datetime.datetime(year_1, month_1, day_1, hour_1, min_1)
date1_t1 = target1_1.strftime("%Y/%m/%d")
date1_t2 = target1_1.strftime("%Y/%m/%d %H:%M:%S")
target2_2 = datetime.datetime(year_2, month_2, day_2, hour_2, min_2)
date2_t1 = target2_2.strftime("%Y/%m/%d")
date2_t2 = target2_2.strftime("%Y/%m/%d %H:%M:%S")
class Application(tk.Frame):
def __init__(self, master):
super().__init__(master)
# メインウィンドウサイズ
master.geometry("1850x640")
master.title("〇〇作戦アプリ")
Label = tk.Label
self.pack()
# Countdown_1
self.Countdown_1 = Label(
self, bg="black", font=("", 50), text="Countdown", fg="#FF9933"
)
self.Countdown_1.grid(row=0, column=1, padx=(0, 200), sticky="news")
# [期限名1]
self.Countdown_time_1 = Label(
self,
bg="black",
font=(("ToppanBunkyuMidashi" "MinchoStdN-ExtraBold"), 60, "bold"),
text=kigen_name_1,
fg="#FF9933",
)
self.Countdown_time_1.grid(row=1, column=0, sticky="news")
# [期限日付表示_1]
self.wt1 = Label(
self, bg="black", font=("DSEG7 Classic", 80, "bold"), fg="#FF9933"
)
self.wt1.grid(row=1, column=1, sticky="news")
# [期限時刻表示_1]
self.wt1_1 = Label(
self, bg="black", font=("DSEG7 Classic", 80, "bold"), fg="#FF9933"
)
self.wt1_1.grid(row=1, column=2, padx=(0, 300), sticky="news")
# [英語表記]
self.Countdown_UN_1 = Label(
self, bg="black", font=("", 30), text=text_1, fg="#FF9933"
)
self.Countdown_UN_1.grid(row=2, column=0, sticky="news")
# [ラベル(Day)]
self.Countdown_UN_1 = Label(
self, bg="black", font=("", 30), text="Day", fg="#FF9933"
)
self.Countdown_UN_1.grid(row=2, column=1, sticky="news")
# [ラベル(Time)]
self.Countdown_UN_1 = Label(
self, bg="black", font=("", 30), text="Time", fg="#FF9933"
)
self.Countdown_UN_1.grid(row=2, column=2, sticky="news")
# Countdown_2
self.Countdown_2 = Label(
self, bg="black", font=("", 50), text="Countdown", fg="#FF9933"
)
self.Countdown_2.grid(row=3, column=1, padx=(0, 200), sticky="news")
# [期限名2]
self.Countdown_time_2 = Label(
self,
bg="black",
font=(("ToppanBunkyuMidashi" "MinchoStdN-ExtraBold"), 60, "bold"),
text=kigen_name_2,
fg="#FF9933",
)
self.Countdown_time_2.grid(row=4, column=0, padx=(0, 50), sticky="news")
# [期限日付表示_2]
self.wt2 = Label(
self, bg="black", font=("DSEG7 Classic", 80, "bold"), fg="#FF9933"
)
self.wt2.grid(row=4, column=1, sticky="news")
# [期限時刻表示_2]
self.wt2_1 = Label(
self, bg="black", font=("DSEG7 Classic", 80, "bold"), fg="#FF9933"
)
self.wt2_1.grid(row=4, column=2, padx=(0, 300), sticky="news")
# [英語表記]
self.Countdown_UN_2 = Label(
self, bg="black", font=("", 30), text=text_2, fg="#FF9933"
)
self.Countdown_UN_2.grid(row=5, column=0, sticky="news")
# [ラベル(Day)]
self.Countdown_UN_2 = Label(
self, bg="black", font=("", 30), text="Day", fg="#FF9933"
)
self.Countdown_UN_2.grid(row=5, column=1, sticky="news")
# [ラベル(Time)]
self.Countdown_UN_2 = Label(
self, bg="black", font=("", 30), text="Time", fg="#FF9933"
)
self.Countdown_UN_2.grid(row=5, column=2, sticky="news")
# --- 日本標準時 ---
self.Countdown_3 = Label(
self, bg="black", font=("", 50), text="Live", fg="#FF9933"
)
self.Countdown_3.grid(row=9, column=1, padx=(0, 350), sticky="news")
# [日本標準時]
self.Countdown_time_3 = Label(
self,
bg="black",
font=(("ToppanBunkyuMidashi" "MinchoStdN-ExtraBold"), 60, "bold"),
text="日本標準時",
fg="#FF9933",
)
self.Countdown_time_3.grid(row=10, column=0, padx=(0, 120), sticky="news")
# [期限時刻表示]
self.wt3 = Label(
self, bg="black", font=("DSEG7 Classic", 80, "bold"), fg="#FF9933"
)
self.wt3.grid(row=10, column=1)
self.wt3_1 = Label(
self, bg="black", font=("DSEG7 Classic", 80, "bold"), fg="#FF9933"
)
self.wt3_1.grid(row=10, padx=(0, 300), column=2)
# [英語表記]
self.Countdown_UN_3 = Label(
self, bg="black", font=("", 30), text="Japan Standard Time", fg="#FF9933"
)
self.Countdown_UN_3.grid(row=11, column=0, padx=(0, 120), sticky="news")
master.after(50, self.update)
def update(self):
# Countdown_setup
today = datetime.datetime.now()
# Target_Time
target_day_1 = datetime.datetime.strptime(date1_t2, "%Y/%m/%d %H:%M:%S")
target_time_1 = datetime.datetime.strptime(date1_t2, "%Y/%m/%d %H:%M:%S")
if today > target_day_1:
self.wt1.configure(text=("%s" % 0))
self.wt1_1.configure(text=("%s:%s:%s" % (0, 0, 0)))
else:
days_Abstracts_days = target_day_1 - today
days_Abstracts_time = target_time_1 - today
secs_time_1 = days_Abstracts_time.seconds + 1
# Days
self.wt1.configure(text=days_Abstracts_days.days)
# Time
second_1 = int((secs_time_1 % 60))
minut_1 = int((secs_time_1 / 60) % 60)
hour_1 = int((secs_time_1 / 3600))
(self.wt1_1.configure(text=("%s:%s:%s" % (hour_1, minut_1, second_1))))
# Target_Time
target_day_2 = datetime.datetime.strptime(date2_t2, "%Y/%m/%d %H:%M:%S")
target_time_2 = datetime.datetime.strptime(date2_t2, "%Y/%m/%d %H:%M:%S")
if today > target_day_2:
self.wt2.configure(text=("%s" % 0))
self.wt2_1.configure(text=("%s:%s:%s" % (0, 0, 0)))
else:
days_Papers_days = target_day_2 - today
days_Papers_time = target_time_2 - today
secs_time_2 = days_Papers_time.seconds + 1
# Days
self.wt2.configure(text=days_Papers_days.days)
# Time
second_2 = int((secs_time_2 % 60))
minut_2 = int((secs_time_2 / 60) % 60)
hour_2 = int((secs_time_2 / 3600))
(self.wt2_1.configure(text=("%s:%s:%s" % (hour_2, minut_2, second_2))))
# Live
self.wt3.configure(text=today.strftime("%m-%d"))
self.wt3_1.configure(text=today.strftime("%H:%M:%S"))
# 1秒後に再表示
self.master.after(1000, self.update)
def main():
root = tk.Tk()
app = Application(master=root)
app.config(bg="black")
app.mainloop()
if __name__ == "__main__":
main()
7. 実行方法
実行方法は、コマンドによる実行を記載します。
ターミナル(Mac)を開いてPythonと記述し、その後に「mission_clocck_MT.py」をドラック&ドロップしてください。
最終的に以下のように書けましたら、実行できます。
$ python /Users/ユーザーネーム/Desktop/mission_clocke_MT.py
8. 自己評価
今回作成したアプリケーションを実際に研究室で使用しているのですが、電子掲示板のように使われており、多忙な研究生からは残りの時間をすぐ見れて計画を立てやすいとの意見をいただきました。当初は緊張感や臨場感を与え、急がせるために開発したのですが、新しい観点で利用してくれた研究生もいたので、今後もアップデートをして新しい価値を生み出せたらと思いました。
9. おわりに
最後まで読んでいただきありがとうございます。今回はtkinterとPythonを使用してアプリケーションを作ったアーカイブ成果物を載せました。
学生時代特有のあどけなさが残っている文章にも見えます。今後の展望としては文頭にも記載させていただいたように、Twitter投稿時に使用できるような形に変えて表示部分に使用したいと思っております。
学生時代の化石を復活、リメイクできることが楽しみです。
参考文献