import cv2, numpy as np import sys import os import json from pathlib import Path from Tbd.helper import default_profile, CameraObject from UI.SetupPageWidget import SetupPage from UI.HomePageWidget import HomeWindow from UI.UILogger import UILogger from Tbd.TrackingController import TrackingController from PySide6.QtCore import Qt, QTimer from PySide6.QtGui import QImage, QPixmap from PySide6.QtWidgets import ( QApplication, QMainWindow, QStackedWidget, QMessageBox, QPlainTextEdit ) from PySide6.QtWidgets import QLineEdit from PySide6.QtGui import QIntValidator from PySide6.QtWidgets import QWidget, QLabel, QVBoxLayout, QPushButton, QHBoxLayout, QSizePolicy from typing import List CONFIG_PATH = Path("config/profile_default.json") class MainWindow(QMainWindow): """ Main control window: left sidebar + right content area. """ cameraList = [] def __init__(self): super().__init__() self.P_mats = {} self.setWindowTitle("Gaming Table Control") self.resize(1200, 1200) # Central root widget root = QWidget() self.setCentralWidget(root) self.main_layout = QVBoxLayout(root) self.main_interaction_layout = QHBoxLayout() # Create Logger self.console = QPlainTextEdit() self.logger = UILogger(self.console) # ---------- Sidebar ---------- self.sidebar = QVBoxLayout() self.btn_home = QPushButton("Home") self.btn_start = QPushButton("Start Game") self.btn_stop = QPushButton("Stop Game") self.btn_setup = QPushButton("Setup Cameras") self.btn_exit = QPushButton("Exit") for btn in [self.btn_home, self.btn_start, self.btn_stop, self.btn_setup, self.btn_exit]: btn.setMinimumHeight(40) self.sidebar.addWidget(btn) self.sidebar.addStretch(1) # push buttons to top # ---------- Content area (stack) ---------- self.stack = QStackedWidget() # Home page home_page = QWidget() self.homeWidget = HomeWindow( cameraList=self.cameraList, on_cameraList_changed=self.on_cameraList_changed, P_mats=self.P_mats, logger=self.logger ) home_layout = QVBoxLayout(home_page) home_label = QLabel("Welcome to the Gaming Table Control") home_label.setAlignment(Qt.AlignCenter) home_layout.addWidget(home_label) home_layout.addWidget(self.homeWidget) # Setup page self.setup_page = SetupPage( cameraList=self.cameraList, on_cameraList_changed=self.on_cameraList_changed, logger=self.logger ) # Options page (placeholder) stop_page = QWidget() stop_layout = QVBoxLayout(stop_page) stop_label = QLabel("The game was stopped") stop_label.setAlignment(Qt.AlignCenter) stop_layout.addWidget(stop_label) # Add pages to stack self.page_home_index = self.stack.addWidget(home_page) self.page_setup_index = self.stack.addWidget(self.setup_page) self.page_stop_index = self.stack.addWidget(stop_page) # ---------- Assemble layout ---------- self.main_interaction_layout.addLayout(self.sidebar) # left side self.main_interaction_layout.addWidget(self.stack, 1) # right side grows self.main_layout.addLayout(self.main_interaction_layout) self.main_layout.addWidget(self.console) # ---------- Connections ---------- self.btn_home.clicked.connect(self.show_home) self.btn_setup.clicked.connect(self.show_setup) self.btn_stop.clicked.connect(self.show_stop) self.btn_start.clicked.connect(self.start_game) self.btn_exit.clicked.connect(self.close) self.game_window = None self.tracking = None # -------------------- def on_cameraList_changed(self): self.homeWidget.updateCameras() self.logger.log("Camera List changed") for camera in self.cameraList: self.logger.log(str(camera.index)) def show_home(self): self.stack.setCurrentIndex(self.page_home_index) def show_setup(self): self.stack.setCurrentIndex(self.page_setup_index) def show_stop(self): self.stack.setCurrentIndex(self.page_stop_index) if(self.tracking) is not None: self.tracking.stop() def start_game(self): self.tracking = TrackingController( cameraList=self.cameraList, P_mats=self.P_mats, logger=self.logger, tick_ms=30 ) self.tracking.start() def main(): app = QApplication(sys.argv) win = MainWindow() win.show() sys.exit(app.exec()) if __name__ == "__main__": main()