Add main application structure and logging configuration
- Implement main application entry point in duck-ocr.py - Create logging configuration in logging_config.py - Add video streaming functionality in camera.py - Introduce main window UI in main_window.py - Include SVG assets for UI buttons and icons - Update .gitignore to exclude log files - Add placeholder .gitkeep files for empty directories
This commit is contained in:
188
app/main_window.py
Normal file
188
app/main_window.py
Normal file
@@ -0,0 +1,188 @@
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
import logging
|
||||
|
||||
from PySide6.QtWidgets import QGridLayout, QHBoxLayout, QMainWindow, QStyle, QToolButton, QWidget, QVBoxLayout, QPushButton
|
||||
from PySide6.QtGui import QIcon
|
||||
from PySide6.QtCore import Qt, QSize
|
||||
|
||||
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.setup_ui()
|
||||
|
||||
def setup_ui(self):
|
||||
self.central_widget = QWidget()
|
||||
self.setCentralWidget(self.central_widget)
|
||||
self.central_widget.setStyleSheet("background-color: #001e1e;")
|
||||
|
||||
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")
|
||||
Reference in New Issue
Block a user