main_window.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. """Main window for the countdown timer application."""
  2. from PyQt6.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
  3. QPushButton, QListWidget, QGroupBox, QLabel,
  4. QScrollArea, QFrame)
  5. from PyQt6.QtCore import QSettings, Qt, QTimer
  6. from PyQt6.QtGui import QFont
  7. from ui.settings_dialog import SettingsDialog
  8. from ui.timer_dialog import TimerDialog
  9. from ui.timer_widget import TimerWidget
  10. from ui.fullscreen_display import FullscreenDisplay
  11. from models.timer_model import Timer
  12. class MainWindow(QMainWindow):
  13. def __init__(self):
  14. super().__init__()
  15. self.settings = QSettings()
  16. self.timers = []
  17. self.timer_widgets = []
  18. self.fullscreen_display = None
  19. self.init_ui()
  20. self.load_timers()
  21. def init_ui(self):
  22. self.setWindowTitle("Countdown Timer Manager")
  23. self.setMinimumSize(1000, 600)
  24. # Central widget
  25. central_widget = QWidget()
  26. self.setCentralWidget(central_widget)
  27. main_layout = QHBoxLayout(central_widget)
  28. # Left panel - Timer management
  29. left_panel = QWidget()
  30. left_layout = QVBoxLayout(left_panel)
  31. left_panel.setMaximumWidth(350)
  32. # Timer list group
  33. timer_group = QGroupBox("Timer Library")
  34. timer_layout = QVBoxLayout()
  35. self.timer_list = QListWidget()
  36. timer_layout.addWidget(self.timer_list)
  37. # Timer management buttons
  38. timer_btn_layout = QVBoxLayout()
  39. self.add_timer_btn = QPushButton("Add Timer")
  40. self.edit_timer_btn = QPushButton("Edit Timer")
  41. self.delete_timer_btn = QPushButton("Delete Timer")
  42. self.start_timer_btn = QPushButton("Start Selected Timer")
  43. self.add_timer_btn.clicked.connect(self.add_timer)
  44. self.edit_timer_btn.clicked.connect(self.edit_timer)
  45. self.delete_timer_btn.clicked.connect(self.delete_timer)
  46. self.start_timer_btn.clicked.connect(self.start_timer)
  47. timer_btn_layout.addWidget(self.add_timer_btn)
  48. timer_btn_layout.addWidget(self.edit_timer_btn)
  49. timer_btn_layout.addWidget(self.delete_timer_btn)
  50. timer_btn_layout.addWidget(self.start_timer_btn)
  51. timer_layout.addLayout(timer_btn_layout)
  52. timer_group.setLayout(timer_layout)
  53. left_layout.addWidget(timer_group)
  54. # Global controls
  55. controls_group = QGroupBox("Global Controls")
  56. controls_layout = QVBoxLayout()
  57. self.stop_all_btn = QPushButton("Stop All Timers")
  58. self.pause_all_btn = QPushButton("Pause All Timers")
  59. self.resume_all_btn = QPushButton("Resume All Timers")
  60. self.stop_all_btn.clicked.connect(self.stop_all_timers)
  61. self.pause_all_btn.clicked.connect(self.pause_all_timers)
  62. self.resume_all_btn.clicked.connect(self.resume_all_timers)
  63. controls_layout.addWidget(self.pause_all_btn)
  64. controls_layout.addWidget(self.resume_all_btn)
  65. controls_layout.addWidget(self.stop_all_btn)
  66. controls_group.setLayout(controls_layout)
  67. left_layout.addWidget(controls_group)
  68. # Display mode group
  69. display_group = QGroupBox("Display Mode")
  70. display_layout = QVBoxLayout()
  71. self.fullscreen_btn = QPushButton("Show Fullscreen on Monitor")
  72. self.fullscreen_btn.clicked.connect(self.show_fullscreen_display)
  73. display_layout.addWidget(self.fullscreen_btn)
  74. display_group.setLayout(display_layout)
  75. left_layout.addWidget(display_group)
  76. # Settings button
  77. settings_btn = QPushButton("Settings")
  78. settings_btn.clicked.connect(self.open_settings)
  79. left_layout.addWidget(settings_btn)
  80. left_layout.addStretch()
  81. main_layout.addWidget(left_panel)
  82. # Right panel - Active timers display
  83. right_panel = QWidget()
  84. right_layout = QVBoxLayout(right_panel)
  85. title_label = QLabel("Active Timers")
  86. title_font = QFont("Arial", 16, QFont.Weight.Bold)
  87. title_label.setFont(title_font)
  88. title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
  89. right_layout.addWidget(title_label)
  90. # Scroll area for timers
  91. scroll_area = QScrollArea()
  92. scroll_area.setWidgetResizable(True)
  93. scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
  94. self.timers_container = QWidget()
  95. self.timers_layout = QVBoxLayout(self.timers_container)
  96. self.timers_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
  97. scroll_area.setWidget(self.timers_container)
  98. right_layout.addWidget(scroll_area)
  99. main_layout.addWidget(right_panel, stretch=1)
  100. # Status bar
  101. self.statusBar().showMessage("Ready")
  102. def add_timer(self):
  103. dialog = TimerDialog(self)
  104. if dialog.exec():
  105. timer = dialog.get_timer()
  106. self.timers.append(timer)
  107. self.timer_list.addItem(timer.name)
  108. self.save_timers()
  109. self.statusBar().showMessage(f"Timer '{timer.name}' added", 3000)
  110. def edit_timer(self):
  111. current_row = self.timer_list.currentRow()
  112. if current_row >= 0:
  113. timer = self.timers[current_row]
  114. dialog = TimerDialog(self, timer)
  115. if dialog.exec():
  116. updated_timer = dialog.get_timer()
  117. self.timers[current_row] = updated_timer
  118. self.timer_list.item(current_row).setText(updated_timer.name)
  119. self.save_timers()
  120. self.statusBar().showMessage(f"Timer '{updated_timer.name}' updated", 3000)
  121. def delete_timer(self):
  122. current_row = self.timer_list.currentRow()
  123. if current_row >= 0:
  124. timer_name = self.timers[current_row].name
  125. del self.timers[current_row]
  126. self.timer_list.takeItem(current_row)
  127. self.save_timers()
  128. self.statusBar().showMessage(f"Timer '{timer_name}' deleted", 3000)
  129. def start_timer(self):
  130. current_row = self.timer_list.currentRow()
  131. if current_row >= 0:
  132. timer = self.timers[current_row]
  133. # Create timer widget
  134. timer_widget = TimerWidget(timer)
  135. timer_widget.finished.connect(lambda: self.remove_timer_widget(timer_widget))
  136. self.timer_widgets.append(timer_widget)
  137. self.timers_layout.addWidget(timer_widget)
  138. # If fullscreen display is active, update it
  139. if self.fullscreen_display and self.fullscreen_display.isVisible():
  140. self.fullscreen_display.add_timer_widget(timer_widget)
  141. self.statusBar().showMessage(f"Timer '{timer.name}' started", 3000)
  142. def remove_timer_widget(self, timer_widget):
  143. if timer_widget in self.timer_widgets:
  144. self.timer_widgets.remove(timer_widget)
  145. self.timers_layout.removeWidget(timer_widget)
  146. timer_widget.deleteLater()
  147. # Update fullscreen display if active
  148. if self.fullscreen_display and self.fullscreen_display.isVisible():
  149. self.fullscreen_display.remove_timer_widget(timer_widget)
  150. self.statusBar().showMessage("Timer finished", 3000)
  151. def show_fullscreen_display(self):
  152. """Show all active timers on a fullscreen display."""
  153. if not self.timer_widgets:
  154. self.statusBar().showMessage("No timers running. Start a timer first.", 3000)
  155. return
  156. monitor_index = self.settings.value("monitor_index", 0, type=int)
  157. if self.fullscreen_display is None:
  158. self.fullscreen_display = FullscreenDisplay(monitor_index)
  159. self.fullscreen_display.closed.connect(self.on_fullscreen_closed)
  160. # Add all active timer widgets to fullscreen display
  161. for timer_widget in self.timer_widgets:
  162. self.fullscreen_display.add_timer_widget(timer_widget)
  163. self.fullscreen_display.show()
  164. self.statusBar().showMessage("Fullscreen display opened on selected monitor", 3000)
  165. def on_fullscreen_closed(self):
  166. """Handle fullscreen display being closed."""
  167. self.fullscreen_display = None
  168. self.statusBar().showMessage("Fullscreen display closed", 3000)
  169. def stop_all_timers(self):
  170. if not self.timer_widgets:
  171. self.statusBar().showMessage("No timers running", 3000)
  172. return
  173. count = len(self.timer_widgets)
  174. for timer_widget in list(self.timer_widgets):
  175. timer_widget.stop_timer()
  176. self.statusBar().showMessage(f"Stopped {count} timer(s)", 3000)
  177. def pause_all_timers(self):
  178. if not self.timer_widgets:
  179. self.statusBar().showMessage("No timers running", 3000)
  180. return
  181. count = 0
  182. for timer_widget in self.timer_widgets:
  183. if not timer_widget.is_paused:
  184. timer_widget.toggle_pause()
  185. count += 1
  186. self.statusBar().showMessage(f"Paused {count} timer(s)", 3000)
  187. def resume_all_timers(self):
  188. if not self.timer_widgets:
  189. self.statusBar().showMessage("No timers running", 3000)
  190. return
  191. count = 0
  192. for timer_widget in self.timer_widgets:
  193. if timer_widget.is_paused:
  194. timer_widget.toggle_pause()
  195. count += 1
  196. self.statusBar().showMessage(f"Resumed {count} timer(s)", 3000)
  197. def open_settings(self):
  198. dialog = SettingsDialog(self)
  199. dialog.exec()
  200. def save_timers(self):
  201. self.settings.beginWriteArray("timers")
  202. for i, timer in enumerate(self.timers):
  203. self.settings.setArrayIndex(i)
  204. self.settings.setValue("name", timer.name)
  205. self.settings.setValue("duration", timer.duration)
  206. self.settings.setValue("font_size", timer.font_size)
  207. self.settings.setValue("bg_color", timer.bg_color)
  208. self.settings.setValue("text_color", timer.text_color)
  209. self.settings.endArray()
  210. def load_timers(self):
  211. size = self.settings.beginReadArray("timers")
  212. for i in range(size):
  213. self.settings.setArrayIndex(i)
  214. timer = Timer(
  215. name=self.settings.value("name", ""),
  216. duration=self.settings.value("duration", 60, type=int),
  217. font_size=self.settings.value("font_size", 120, type=int),
  218. bg_color=self.settings.value("bg_color", "#000000"),
  219. text_color=self.settings.value("text_color", "#FFFFFF")
  220. )
  221. self.timers.append(timer)
  222. self.timer_list.addItem(timer.name)
  223. self.settings.endArray()