Fbrowser/timer_m.py
2025-04-06 20:00:26 -05:00

205 lines
6.6 KiB
Python

# flake8: noqa: E501
import time
import threading
from PyQt6.QtWidgets import (
QWidget,
QVBoxLayout,
QPushButton,
QLabel,
QHBoxLayout,
QLineEdit,
)
from PyQt6.QtCore import QTimer
import numpy as np
import sounddevice as sd # type: ignore
class Timer:
def __init__(self):
self.remaining = 0
self.running = False
self.timer_thread = None
def set(self, hours, minutes, seconds):
self.remaining = hours * 3600 + minutes * 60 + seconds
def start(self):
if self.remaining > 0:
self.running = True
self.timer_thread = threading.Thread(target=self._run_timer)
self.timer_thread.start()
def _run_timer(self):
while self.running and self.remaining > 0:
time.sleep(1)
self.remaining -= 1
if self.running:
self._alarm()
def stop(self):
self.running = False
if self.timer_thread:
self.timer_thread.join()
def get_remaining_time(self):
return self.remaining
def _alarm(self):
print("Time's up!")
try:
self._play_tone()
# sleep = 1.2
self._play_tone2()
# sleep = 1
self._play_tone3()
# sleep = 1
self._play_tone4()
# sleep = 1
self._play_tone5()
except Exception as e:
print(f"Error generating alarm tone: {e}")
def _play_tone(self, frequency=587, duration=0.2, repeat=4):
"""Generate and play a tone with given frequency, duration, and repeat count."""
sample_rate = 44100
t = np.linspace(
0, duration, int(sample_rate * duration), endpoint=False
)
tone = 0.5 * np.sin(2 * np.pi * frequency * t)
for _ in range(repeat):
sd.play(tone, samplerate=sample_rate)
sd.wait()
def _play_tone2(self, frequency=698, duration=0.2, repeat=3):
"""Generate and play a tone with given frequency, duration, and repeat count."""
sample_rate = 44100
t = np.linspace(
0, duration, int(sample_rate * duration), endpoint=False
)
tone = 0.5 * np.sin(2 * np.pi * frequency * t)
for _ in range(repeat):
sd.play(tone, samplerate=sample_rate)
sd.wait()
def _play_tone3(self, frequency=659, duration=0.2, repeat=3):
"""Generate and play a tone with given frequency, duration, and repeat count."""
sample_rate = 44100
t = np.linspace(
0, duration, int(sample_rate * duration), endpoint=False
)
tone = 0.5 * np.sin(2 * np.pi * frequency * t)
for _ in range(repeat):
sd.play(tone, samplerate=sample_rate)
sd.wait()
def _play_tone4(self, frequency=554, duration=0.4, repeat=1):
"""Generate and play a tone with given frequency, duration, and repeat count."""
sample_rate = 44100
t = np.linspace(
0, duration, int(sample_rate * duration), endpoint=False
)
tone = 0.5 * np.sin(2 * np.pi * frequency * t)
for _ in range(repeat):
sd.play(tone, samplerate=sample_rate)
sd.wait()
def _play_tone5(self, frequency=554, duration=0.8, repeat=1):
"""Generate and play a tone with given frequency, duration, and repeat count."""
sample_rate = 44100
t = np.linspace(
0, duration, int(sample_rate * duration), endpoint=False
)
tone = 0.5 * np.sin(2 * np.pi * frequency * t)
for _ in range(repeat):
sd.play(tone, samplerate=sample_rate)
sd.wait()
class Timer_Ui(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Timer")
self.setFixedWidth(400)
self.setFixedHeight(200)
self.timer = Timer()
self.init_ui()
def init_ui(self):
layout = QVBoxLayout()
self.setLayout(layout)
self.timer_label = QLabel("Timer: Not Set")
layout.addWidget(self.timer_label)
timer_input_layout = QHBoxLayout()
self.hours_input = QLineEdit()
self.minutes_input = QLineEdit()
self.seconds_input = QLineEdit()
timer_input_layout.addWidget(QLabel("Hours:"))
timer_input_layout.addWidget(self.hours_input)
timer_input_layout.addWidget(QLabel("Minutes:"))
timer_input_layout.addWidget(self.minutes_input)
timer_input_layout.addWidget(QLabel("Seconds:"))
timer_input_layout.addWidget(self.seconds_input)
layout.addLayout(timer_input_layout)
self.set_timer_button = QPushButton("Set Timer")
self.set_timer_button.clicked.connect(self.set_timer)
layout.addWidget(self.set_timer_button)
self.start_timer_button = QPushButton("Start Timer")
self.start_timer_button.clicked.connect(self.start_timer)
layout.addWidget(self.start_timer_button)
self.stop_timer_button = QPushButton("Stop Timer")
self.stop_timer_button.clicked.connect(self.stop_timer)
layout.addWidget(self.stop_timer_button)
self.update_timer = QTimer()
self.update_timer.timeout.connect(self.update_timer_display)
self.update_timer.start(1000)
def set_timer(self):
try:
hours = int(self.hours_input.text() or 0)
minutes = int(self.minutes_input.text() or 0)
seconds = int(self.seconds_input.text() or 0)
self.timer.set(hours, minutes, seconds)
self.timer_label.setText(
f"Timer: Set to {hours:02d}:{minutes:02d}:{seconds:02d}"
)
except ValueError:
self.timer_label.setText("Timer: Invalid input")
def start_timer(self):
if self.timer.get_remaining_time() > 0:
self.timer.start()
else:
self.timer_label.setText("Timer: Not set")
def stop_timer(self):
self.timer.stop()
self.timer_label.setText("Timer: Stopped")
def update_timer_display(self):
if self.timer.running:
remaining = self.timer.get_remaining_time()
hours, remainder = divmod(remaining, 3600)
minutes, seconds = divmod(remainder, 60)
self.timer_label.setText(
f"Timer: {hours:02d}:{minutes:02d}:{seconds:02d}"
)
elif (
self.timer.get_remaining_time() == 0
and self.timer_label.text() != "Timer: Not Set"
):
self.timer_label.setText("Timer: Time's up!")
def showUI(self):
self.setWindowTitle("Timer")
self.setGeometry(100, 100, 300, 200)
super().show()