KNEO-Academy/main.py
abin 7e323cf3e1 Fix: resolve 5 bugs found during project onboarding health check
- custom_inference_worker: reuse existing device_group from DeviceController
  to avoid double kp.connect_devices() conflict on same USB port
- custom_inference_worker: add TYPE_CHECKING guard for kp type annotations
  to prevent potential NameError at import time
- utilities_screen: replace missing back_arrow.png with text arrow (←)
- utilities_screen: add set_device_controller() so AppController can inject
  MainWindow's shared DeviceController instance
- main.py: wire UtilitiesScreen to share MainWindow's DeviceController
- video_thread: emit camera_error_signal on failure and max-retry exhaustion
- media_controller: connect camera_error_signal and display error on canvas
- media_panel: fix pause button using wrong delete icon; use video_normal SVG

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 14:33:37 +08:00

133 lines
4.4 KiB
Python

"""
main.py - Kneron Academy Application Entry Point
This module serves as the main entry point for the application.
It initializes the PyQt5 application and uses AppController to manage
navigation and screen transitions.
"""
import sys
from PyQt5.QtWidgets import QApplication, QStackedWidget
from src.views.mainWindows import MainWindow
from src.views.selection_screen import SelectionScreen
from src.views.login_screen import LoginScreen
from src.views.utilities_screen import UtilitiesScreen
from src.config import APP_NAME, WINDOW_SIZE
class AppController:
"""
Application Controller Class
Manages the entire application lifecycle, including:
- Initializing all screens
- Setting up signal connections between screens
- Controlling screen navigation logic
Attributes:
app (QApplication): The PyQt5 application instance
stack (QStackedWidget): Stacked widget container for managing multiple screens
selection_screen (SelectionScreen): The selection/home screen
login_screen (LoginScreen): The login screen
utilities_screen (UtilitiesScreen): The utilities screen
main_window (MainWindow): The main demo application window
"""
def __init__(self):
self.app = QApplication(sys.argv)
self.stack = QStackedWidget()
self.stack.setGeometry(100, 100, *WINDOW_SIZE)
self.stack.setWindowTitle(APP_NAME)
# Initialize screens
self.init_screens()
# Configure navigation signals
self.connect_signals()
# Start with selection screen
self.show_selection_screen()
def init_screens(self):
"""
Initialize all application screens.
Creates instances of each screen and adds them to the stacked widget.
The order of addition determines the default index of each screen.
"""
self.selection_screen = SelectionScreen()
self.stack.addWidget(self.selection_screen)
self.login_screen = LoginScreen()
self.stack.addWidget(self.login_screen)
self.utilities_screen = UtilitiesScreen()
self.stack.addWidget(self.utilities_screen)
self.main_window = MainWindow()
self.stack.addWidget(self.main_window)
# Share MainWindow's DeviceController with UtilitiesScreen so both
# screens reflect the same device connection state.
self.utilities_screen.set_device_controller(self.main_window.device_controller)
def connect_signals(self):
"""
Connect signals between screens for navigation.
Sets up Qt signal-slot connections to enable screen transitions:
- Selection screen -> Login screen (for utilities access)
- Selection screen -> Demo app
- Login screen -> Utilities screen (on successful login)
- Login screen -> Selection screen (back navigation)
- Utilities screen -> Selection screen (back navigation)
"""
self.selection_screen.open_utilities.connect(self.show_login_screen)
self.selection_screen.open_demo_app.connect(self.show_demo_app)
self.login_screen.login_success.connect(self.show_utilities_screen)
self.login_screen.back_to_selection.connect(self.show_selection_screen)
self.utilities_screen.back_to_selection.connect(self.show_selection_screen)
def show_selection_screen(self):
"""Switch to the selection/home screen."""
self.stack.setCurrentWidget(self.selection_screen)
def show_login_screen(self):
"""Switch to the login screen."""
self.stack.setCurrentWidget(self.login_screen)
def show_utilities_screen(self):
"""Switch to the utilities screen."""
self.stack.setCurrentWidget(self.utilities_screen)
def show_demo_app(self):
"""Switch to the main demo application window."""
self.stack.setCurrentWidget(self.main_window)
def run(self):
"""
Start the application event loop.
Returns:
int: The exit code from the Qt application event loop.
"""
self.stack.show()
return self.app.exec_()
def main():
"""
Application entry point function.
Creates the AppController and starts the application event loop.
Returns:
int: The exit code from the application.
"""
controller = AppController()
return controller.run()
if __name__ == "__main__":
main()