0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【錯覚時間】イリュージョンタイマー作ってみた【Python】

Posted at

背景・目的

ランニングマシンでランニングをしているとき、ふと「5分や10分を区切りにして頑張ろう」と思うことがあります。実際に、その区切りが過ぎるまでは頑張ろうという意識が働き、走り続けることができるからです。
これなら、表示時間を短くし、実際の経過時間を長く設定することで、体感時間を短く感じさせ、実際にはより長く頑張ることができるのではないかと考えました。
そこで、「実際の経過時間と表示される時間が異なる」というイリュージョンタイマーを作成しようと思い立ちました。

完成イメージ

起動画面.png

  • 機能概要:
    • 時間の設定(見かけ上の時間と実際の時間)
    • 開始/停止/再開機能
    • リセット機能
    • タイマー終了時の通知機能

タイマーの仕様

設定時間と見かけ上の時間

このタイマーは、設定された「見かけ上の時間(表示される時間)」と、実際に経過している「実際の経過時間(実時間)」が異なる仕様です。

見かけ上の時間と実際の経過時間の算出方法

  1. 見かけ上の時間:

    • ユーザーが設定した時間(例えば、20分)が見かけ上のタイマーに表示される時間として使用されます。
  2. 実際の経過時間:

    • 実際には、ユーザーが設定した時間よりも長め(例えば、30分)の時間が実際に経過します。
    • この差をtime_ratio(時間比率)で計算します。
    • time_ratioは以下の式で計算されます:
      time_ratio = 実際の経過時間 / 見かけ上の時間
      
      例えば、見かけ上の時間20分実際の経過時間30分の場合、time_ratio30 / 20 = 1.5となります。
  3. 動作の仕組み:

    • タイマーの内部では、実際の経過時間がtime_ratioに基づいて更新されます。これにより、表示時間は短く(例えば、20分)表示される一方で、実際の経過時間はその時間に対して1.5倍30分)進行することになります。

ソースコード全体

import tkinter as tk
from tkinter import ttk, messagebox


class IllusionTimerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("イリュージョンタイマー")
        self.root.geometry("400x300")
        self.illusion_time = tk.IntVar(value=20)
        self.actually_time = tk.IntVar(value=30)
        self.is_running = False
        self.time_ratio = 1
        self.remaining_seconds = 0

        self.main_frame = ttk.Frame(self.root)
        self.main_frame.place(relx=0.5, rely=0.5, anchor="center")

        self.setup_gui()
        self.reset_timer()

    def setup_gui(self):
        ttk.Label(self.main_frame, text="見かけ上の時間 (分):").grid(row=0, column=0, padx=5, pady=5, sticky="e")
        ttk.Entry(self.main_frame, textvariable=self.illusion_time, width=5).grid(row=0, column=1, padx=5, pady=5)

        ttk.Label(self.main_frame, text="実際の経過時間 (分):").grid(row=1, column=0, padx=5, pady=5, sticky="e")
        ttk.Entry(self.main_frame, textvariable=self.actually_time, width=5).grid(row=1, column=1, padx=5, pady=5)

        self.timer_label = ttk.Label(self.main_frame, text="00:00", font=("Arial", 40))
        self.timer_label.grid(row=2, column=0, columnspan=2, pady=20)

        self.start_stop_button = ttk.Button(self.main_frame, text="開始", command=self.toggle_timer)
        self.start_stop_button.grid(row=3, column=0, columnspan=2, pady=10)

        self.reset_button = ttk.Button(self.main_frame, text="リセット", command=self.reset_timer)
        self.reset_button.grid(row=4, column=0, columnspan=2, pady=10)

    def toggle_timer(self):
        if self.is_running:
            self.is_running = False
            self.start_stop_button.config(text="再開")
        else:
            self.remaining_seconds = self.illusion_time.get() * 60
            self.start_timer()

    def start_timer(self):
        self.is_running = True
        self.start_stop_button.config(text="停止")
        self.run_timer()

    def initialize_timer(self):
        self.time_ratio = self.actually_time.get() / self.illusion_time.get()

    def run_timer(self):
        if self.remaining_seconds > 0 and self.is_running:
            minutes, seconds = divmod(self.remaining_seconds, 60)
            self.timer_label.config(text=f"{str(minutes).zfill(2)}:{str(seconds).zfill(2)}")
            self.remaining_seconds -= 1
            self.root.after(int(self.time_ratio * 1000), self.run_timer)
        elif self.remaining_seconds <= 0:
            self.timer_label.config(text="00:00", foreground="red")
            messagebox.showinfo("タイマー終了", "タイマーが終了しました!")
            self.start_stop_button.config(text="開始", state="disable")
            self.is_running = False

    def reset_timer(self):
        self.is_running = False
        self.remaining_seconds = self.illusion_time.get() * 60
        self.timer_label.config(text=self.format_time(self.remaining_seconds), foreground="black")
        self.start_stop_button.config(text="開始", state="normal")

    @staticmethod
    def format_time(seconds):
        minutes, seconds = divmod(seconds, 60)
        return f"{str(minutes).zfill(2)}:{str(seconds).zfill(2)}"


if __name__ == "__main__":
    root = tk.Tk()
    app = IllusionTimerApp(root)
    root.mainloop()

最後に

tkinterを使って錯覚を起こすタイマーを作成しました。設定時間によっては明らかにタイマーの進みが遅いですが意外と使えます。簡単に試すことができるのでぜひ使ってみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?