205 lines
6.6 KiB
Python
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()
|