Files
duck-stain-ocr/app/main_window.py
bartool 651c150e23 test controllera
Co-authored-by: Copilot <copilot@github.com>
2026-05-10 21:52:34 +02:00

206 lines
6.6 KiB
Python

from enum import Enum
from typing import Any
import logging
from PySide6.QtWidgets import QGridLayout, QHBoxLayout, QMainWindow, QStyle, QToolButton, QWidget, QVBoxLayout, QPushButton, QLabel
from PySide6.QtGui import QIcon, QPixmap
from PySide6.QtCore import Qt, QSize
from .video_stream.controller import VideoStreamController, FrameMetrics
logger = logging.getLogger(__name__)
class VideoMode(Enum):
STREAMING = "streaming"
RECORDING = "recording"
PLAYING = "playing"
STOPPED = "stopped"
icons = {
"load_file":{
"path": "assets/folder-svgrepo-com.svg",
"tooltip": "Open File",
"size": QSize(48, 48)
},
"close_file": {
"path": "assets/close-square-svgrepo-com.svg",
"tooltip": "Close File",
"size": QSize(32, 32)
},
"record_on": {
"path": "assets/record_btn_on.svg",
"tooltip": "Start Recording",
"size": QSize(48, 48)
},
"record_off": {
"path": "assets/record_btn_off.svg",
"tooltip": "Stop Recording",
"size": QSize(48, 48)
},
"play": {
"path": "assets/play-svgrepo-com.svg",
"tooltip": "Play Video",
"size": QSize(48, 48)
},
"pause": {
"path": "assets/pause-svgrepo-com.svg",
"tooltip": "Pause Video",
"size": QSize(32, 32)
}
}
def set_icon(button: QToolButton, icon: str):
button.setIcon(QIcon(icons[icon]["path"]))
button.setToolTip(icons[icon]["tooltip"])
button.setIconSize(icons[icon]["size"])
def create_tool_button(icon: str) -> QToolButton:
button = QToolButton()
set_icon(button, icon)
button.setFixedSize(48, 48)
button.setStyleSheet("background-color: transparent; border: none;")
return button
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Duck Stain OCR")
self.resize(1280, 720)
self.video_mode = VideoMode.STREAMING
logger.debug(f"Initial video mode: {self.video_mode}")
self.video_controller = VideoStreamController()
self.video_controller.change_source(0) # Start with default camera
self.video_controller.image_ready.connect(self.update_frame)
self.setup_ui()
self.video_controller.start()
def setup_ui(self):
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.central_widget.setStyleSheet("background-color: #001e1e;")
self.video_label = QLabel(self.central_widget)
self.toolbar_widget = QWidget(self.central_widget)
self.toolbar_widget.setMinimumWidth(400)
self.toolbar_widget.setObjectName("bottomToolbar")
self.toolbar_widget.setStyleSheet(
"""
QWidget#bottomToolbar {
background: rgba(0, 0, 0, 0.1);
border-radius: 18px;
}
"""
)
left_layout = QHBoxLayout()
right_layout = QHBoxLayout()
self.toolbar_layout = QGridLayout(self.toolbar_widget)
self.toolbar_layout.setContentsMargins(18, 16, 18, 16)
self.toolbar_layout.setColumnStretch(0, 1)
self.toolbar_layout.setColumnStretch(1, 0)
self.toolbar_layout.setColumnStretch(2, 1)
self.toolbar_layout.addLayout(left_layout, 0, 0)
self.toolbar_layout.addLayout(right_layout, 0, 2)
# Add buttons to the left layout
self.open_file_button = create_tool_button("load_file")
self.open_file_button.clicked.connect(self.load_video)
left_layout.addWidget(self.open_file_button)
self.close_file_button = create_tool_button("close_file")
self.close_file_button.clicked.connect(self.close_video)
self.close_file_button.setEnabled(False)
left_layout.addWidget(self.close_file_button)
left_layout.addStretch()
# Add the record button to the center of the toolbar
self.action_button = create_tool_button("record_off")
self.action_button.clicked.connect(self.toggle_action)
self.toolbar_layout.addWidget(self.action_button, 0, 1, alignment=Qt.AlignmentFlag.AlignCenter)
# Add buttons to the right layout
right_layout.addStretch()
def resizeEvent(self, event: Any) -> None:
super().resizeEvent(event)
self.toolbar_widget.adjustSize()
toolbar_size = self.toolbar_widget.sizeHint()
self.toolbar_widget.setGeometry(
(self.central_widget.width() - self.toolbar_widget.width()) // 2,
self.central_widget.height() - self.toolbar_widget.height() - 80,
self.toolbar_widget.width(),
self.toolbar_widget.height(),
)
self.toolbar_widget.raise_() # Ensure the toolbar is above other widgets
def toggle_action(self):
match self.video_mode:
case VideoMode.STREAMING:
self.start_recording()
case VideoMode.RECORDING:
self.stop_recording()
case VideoMode.PLAYING:
self.pause_video()
case VideoMode.STOPPED:
self.play_video()
case _:
pass
def start_recording(self):
logger.debug("Starting recording")
self.video_mode = VideoMode.RECORDING
set_icon(self.action_button, "record_on")
self.open_file_button.setEnabled(False)
self.close_file_button.setEnabled(False)
def stop_recording(self):
logger.debug("Stopping recording")
self.video_mode = VideoMode.STREAMING
set_icon(self.action_button, "record_off")
self.open_file_button.setEnabled(True)
self.close_file_button.setEnabled(False)
def load_video(self):
logger.debug("Loading video")
self.video_mode = VideoMode.STOPPED
set_icon(self.action_button, "play")
self.close_file_button.setEnabled(True)
def close_video(self):
logger.debug("Closing video")
self.video_mode = VideoMode.STREAMING
set_icon(self.action_button, "record_off")
self.close_file_button.setEnabled(False)
def play_video(self):
logger.debug("Playing video")
self.video_mode = VideoMode.PLAYING
set_icon(self.action_button, "pause")
def pause_video(self):
logger.debug("Pausing video")
self.video_mode = VideoMode.STOPPED
set_icon(self.action_button, "play")
def closeEvent(self, event: Any) -> None:
logger.debug("Closing main window, cleaning up resources.")
self.video_controller.cleanup()
super().closeEvent(event)
def update_frame(self, frame):
self.video_label.setPixmap(QPixmap.fromImage(frame))