yesssssssssss ; it fucking wooooooooooorks !!!!

This commit is contained in:
rattatwinko
2025-05-26 17:19:24 +02:00
parent 2887e2927c
commit 4a06b759e3

View File

@@ -1302,6 +1302,14 @@ class MainWindow(QMainWindow):
# Initialize configuration # Initialize configuration
self.config = Config() self.config = Config()
# Initialize default values
self.current_layout = 0 # Default to single camera layout
self.detector = MultiCamYOLODetector()
self.camera_settings = {}
# Load saved settings first
self.load_saved_settings()
# Set dark theme style # Set dark theme style
self.setStyleSheet(""" self.setStyleSheet("""
QMainWindow, QWidget { QMainWindow, QWidget {
@@ -1401,16 +1409,18 @@ class MainWindow(QMainWindow):
palette.setColor(palette.HighlightedText, Qt.black) palette.setColor(palette.HighlightedText, Qt.black)
self.setPalette(palette) self.setPalette(palette)
self.detector = MultiCamYOLODetector() # Initialize UI elements
self.camera_settings = {}
# Load saved settings
self.load_saved_settings()
self.create_menus()
self.init_ui() self.init_ui()
# Create menus
self.create_menus()
# Initialize timer
self.init_timer() self.init_timer()
# Apply saved settings to UI
self.apply_saved_settings()
def load_saved_settings(self): def load_saved_settings(self):
"""Load saved settings from configuration""" """Load saved settings from configuration"""
# Load model directory # Load model directory
@@ -1426,11 +1436,16 @@ class MainWindow(QMainWindow):
# Load layout setting # Load layout setting
self.current_layout = int(self.config.load_setting('layout', 0)) self.current_layout = int(self.config.load_setting('layout', 0))
def save_settings(self): def apply_saved_settings(self):
"""Save current settings to configuration""" """Apply loaded settings to UI elements"""
self.config.save_setting('model_dir', self.detector.model_dir) if hasattr(self, 'fps_spin'):
self.config.save_setting('fps', self.fps_spin.value()) self.fps_spin.setValue(self.detector.target_fps)
self.config.save_setting('layout', self.layout_combo.currentIndex())
if hasattr(self, 'layout_combo'):
self.layout_combo.setCurrentIndex(self.current_layout)
if hasattr(self, 'model_label') and self.detector.model_dir:
self.model_label.setText(f"Model: {os.path.basename(self.detector.model_dir)}")
def create_menus(self): def create_menus(self):
menubar = self.menuBar() menubar = self.menuBar()
@@ -1452,6 +1467,7 @@ class MainWindow(QMainWindow):
# Add Camera Selector action # Add Camera Selector action
select_cameras_action = QAction('Select Cameras...', self) select_cameras_action = QAction('Select Cameras...', self)
select_cameras_action.setIcon(QIcon.fromTheme('camera-web'))
select_cameras_action.triggered.connect(self.show_camera_selector) select_cameras_action.triggered.connect(self.show_camera_selector)
self.camera_menu.addAction(select_cameras_action) self.camera_menu.addAction(select_cameras_action)
@@ -1459,41 +1475,240 @@ class MainWindow(QMainWindow):
# Add Network Camera Settings action # Add Network Camera Settings action
network_camera_action = QAction('Network Camera Settings...', self) network_camera_action = QAction('Network Camera Settings...', self)
network_camera_action.setIcon(QIcon.fromTheme('network-wireless'))
network_camera_action.triggered.connect(self.show_network_camera_dialog) network_camera_action.triggered.connect(self.show_network_camera_dialog)
self.camera_menu.addAction(network_camera_action) self.camera_menu.addAction(network_camera_action)
self.camera_menu.addSeparator() self.camera_menu.addSeparator()
self.camera_action_group = QActionGroup(self) # Create camera groups
self.camera_action_group.setExclusive(False) self.local_camera_menu = QMenu('Local Cameras', self)
self.network_camera_menu = QMenu('Network Cameras', self)
self.camera_menu.addMenu(self.local_camera_menu)
self.camera_menu.addMenu(self.network_camera_menu)
# Create action groups for each camera type
self.local_camera_group = QActionGroup(self)
self.local_camera_group.setExclusive(False)
self.network_camera_group = QActionGroup(self)
self.network_camera_group.setExclusive(False)
# Initial population
self.populate_camera_menu() self.populate_camera_menu()
def populate_camera_menu(self): def populate_camera_menu(self):
"""Populate the camera menu with available cameras""" """Populate the camera menu with available cameras"""
# Clear existing camera actions (except refresh and network camera settings) # Clear existing camera actions
for action in self.camera_menu.actions()[3:]: self.local_camera_menu.clear()
self.camera_menu.removeAction(action) self.network_camera_menu.clear()
# Add refresh action to both menus
refresh_action = QAction('Refresh List', self)
refresh_action.triggered.connect(self.populate_camera_menu)
self.local_camera_menu.addAction(refresh_action)
self.local_camera_menu.addSeparator()
available_cams = self.detector.scan_for_cameras() available_cams = self.detector.scan_for_cameras()
for cam_path in available_cams: local_cams_found = False
# Display friendly name network_cams_found = False
if cam_path.startswith('net:'):
name = cam_path[4:] # Use the camera name directly
display_name = f"{name}"
elif cam_path.startswith('/dev/'):
display_name = os.path.basename(cam_path)
else:
display_name = f"Camera {cam_path}"
action = QAction(display_name, self, checkable=True)
action.setData(cam_path)
self.camera_action_group.addAction(action)
self.camera_menu.addAction(action)
if not available_cams: for cam_path in available_cams:
no_cam_action = QAction('No cameras found', self) if cam_path.startswith('net:'):
no_cam_action.setEnabled(False) # Network camera
self.camera_menu.addAction(no_cam_action) name = cam_path[4:]
action = QAction(name, self)
action.setCheckable(True)
action.setData(cam_path)
self.network_camera_group.addAction(action)
self.network_camera_menu.addAction(action)
network_cams_found = True
else:
# Local camera
if cam_path.startswith('/dev/'):
display_name = os.path.basename(cam_path)
else:
display_name = f"Camera {cam_path}"
action = QAction(display_name, self)
action.setCheckable(True)
action.setData(cam_path)
self.local_camera_group.addAction(action)
self.local_camera_menu.addAction(action)
local_cams_found = True
# Add placeholder text if no cameras found
if not local_cams_found:
no_local = QAction('No local cameras found', self)
no_local.setEnabled(False)
self.local_camera_menu.addAction(no_local)
if not network_cams_found:
no_net = QAction('No network cameras found', self)
no_net.setEnabled(False)
self.network_camera_menu.addAction(no_net)
# Update the camera label
self.update_selection_labels()
def update_selection_labels(self):
"""Update the model and camera selection labels"""
selected_cams = []
# Check local cameras
for action in self.local_camera_group.actions():
if action.isChecked():
selected_cams.append(action.text())
# Check network cameras
for action in self.network_camera_group.actions():
if action.isChecked():
selected_cams.append(action.text())
if selected_cams:
self.cameras_label.setText(f"Selected Cameras: {', '.join(selected_cams)}")
else:
self.cameras_label.setText("Selected Cameras: None")
def start_detection(self):
"""Start the detection process"""
if not self.detector.model_dir:
QMessageBox.critical(self, "Error", "No model directory selected!")
return
# Get selected cameras
selected_cameras = []
# Get local cameras
for action in self.local_camera_group.actions():
if action.isChecked():
selected_cameras.append(action.data())
# Get network cameras
for action in self.network_camera_group.actions():
if action.isChecked():
selected_cameras.append(action.data())
if not selected_cameras:
QMessageBox.critical(self, "Error", "No cameras selected!")
return
# Set FPS
self.detector.target_fps = self.fps_spin.value()
self.detector.frame_interval = 1.0 / self.detector.target_fps
# Connect to cameras
if not self.detector.connect_cameras(selected_cameras):
QMessageBox.critical(self, "Error", "Failed to connect to cameras!")
return
# Update UI
self.update_selection_labels()
self.start_btn.setEnabled(False)
self.stop_btn.setEnabled(True)
self.fps_spin.setEnabled(False)
# Start timer
self.timer.start(int(1000 / self.detector.target_fps))
def show_camera_selector(self):
"""Show a simplified camera selector dialog"""
dialog = QDialog(self)
dialog.setWindowTitle("Select Cameras")
dialog.setModal(True)
layout = QVBoxLayout(dialog)
# Create tabs for different camera types
tabs = QTabWidget()
local_tab = QWidget()
network_tab = QWidget()
# Local cameras tab
local_layout = QVBoxLayout(local_tab)
local_list = QListWidget()
local_layout.addWidget(QLabel("Available Local Cameras:"))
local_layout.addWidget(local_list)
# Network cameras tab
network_layout = QVBoxLayout(network_tab)
network_list = QListWidget()
network_layout.addWidget(QLabel("Available Network Cameras:"))
network_layout.addWidget(network_list)
# Add tabs
tabs.addTab(local_tab, "Local Cameras")
tabs.addTab(network_tab, "Network Cameras")
layout.addWidget(tabs)
# Populate lists
available_cams = self.detector.scan_for_cameras()
for cam_path in available_cams:
if cam_path.startswith('net:'):
name = cam_path[4:]
item = QListWidgetItem(name)
item.setData(Qt.UserRole, cam_path)
item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
item.setCheckState(Qt.Unchecked)
network_list.addItem(item)
else:
display_name = os.path.basename(cam_path) if cam_path.startswith('/dev/') else f"Camera {cam_path}"
item = QListWidgetItem(display_name)
item.setData(Qt.UserRole, cam_path)
item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
item.setCheckState(Qt.Unchecked)
local_list.addItem(item)
# Check currently selected cameras
for action in self.local_camera_group.actions():
if action.isChecked():
for i in range(local_list.count()):
item = local_list.item(i)
if item.data(Qt.UserRole) == action.data():
item.setCheckState(Qt.Checked)
for action in self.network_camera_group.actions():
if action.isChecked():
for i in range(network_list.count()):
item = network_list.item(i)
if item.data(Qt.UserRole) == action.data():
item.setCheckState(Qt.Checked)
# Buttons
btn_layout = QHBoxLayout()
ok_btn = QPushButton("OK")
cancel_btn = QPushButton("Cancel")
btn_layout.addWidget(ok_btn)
btn_layout.addWidget(cancel_btn)
layout.addLayout(btn_layout)
ok_btn.clicked.connect(dialog.accept)
cancel_btn.clicked.connect(dialog.reject)
if dialog.exec_() == QDialog.Accepted:
# Update camera selections
for action in self.local_camera_group.actions():
action.setChecked(False)
for action in self.network_camera_group.actions():
action.setChecked(False)
# Update local camera selections
for i in range(local_list.count()):
item = local_list.item(i)
if item.checkState() == Qt.Checked:
cam_path = item.data(Qt.UserRole)
for action in self.local_camera_group.actions():
if action.data() == cam_path:
action.setChecked(True)
# Update network camera selections
for i in range(network_list.count()):
item = network_list.item(i)
if item.checkState() == Qt.Checked:
cam_path = item.data(Qt.UserRole)
for action in self.network_camera_group.actions():
if action.data() == cam_path:
action.setChecked(True)
self.update_selection_labels()
def load_model_directory(self): def load_model_directory(self):
"""Open file dialog to select model directory""" """Open file dialog to select model directory"""
@@ -1631,12 +1846,6 @@ class MainWindow(QMainWindow):
# Start with sidebar expanded # Start with sidebar expanded
self.sidebar.expand() self.sidebar.expand()
# Set saved FPS value
self.fps_spin.setValue(self.detector.target_fps)
# Set saved layout
self.layout_combo.setCurrentIndex(self.current_layout)
def change_camera_layout(self, index): def change_camera_layout(self, index):
"""Change the camera display layout""" """Change the camera display layout"""
@@ -1674,40 +1883,6 @@ class MainWindow(QMainWindow):
self.timer = QTimer() self.timer = QTimer()
self.timer.timeout.connect(self.update_feeds) self.timer.timeout.connect(self.update_feeds)
def start_detection(self):
"""Start the detection process"""
if not self.detector.model_dir:
QMessageBox.critical(self, "Error", "No model directory selected!")
return
# Get selected cameras
selected_cameras = []
for action in self.camera_action_group.actions():
if action.isChecked():
selected_cameras.append(action.data())
if not selected_cameras:
QMessageBox.critical(self, "Error", "No cameras selected!")
return
# Set FPS
self.detector.target_fps = self.fps_spin.value()
self.detector.frame_interval = 1.0 / self.detector.target_fps
# Connect to cameras
if not self.detector.connect_cameras(selected_cameras):
QMessageBox.critical(self, "Error", "Failed to connect to cameras!")
return
# Update UI
self.update_selection_labels()
self.start_btn.setEnabled(False)
self.stop_btn.setEnabled(True)
self.fps_spin.setEnabled(False)
# Start timer
self.timer.start(int(1000 / self.detector.target_fps))
def stop_detection(self): def stop_detection(self):
"""Stop the detection process""" """Stop the detection process"""
self.timer.stop() self.timer.stop()
@@ -1730,15 +1905,6 @@ class MainWindow(QMainWindow):
} }
""") """)
def update_selection_labels(self):
"""Update the model and camera selection labels"""
# Update cameras label
selected_cams = []
for action in self.camera_action_group.actions():
if action.isChecked():
selected_cams.append(action.text())
self.cameras_label.setText(f"Selected Cameras: {', '.join(selected_cams) or 'None'}")
def update_feeds(self): def update_feeds(self):
"""Update the camera feeds in the display""" """Update the camera feeds in the display"""
frames = self.detector.get_frames() frames = self.detector.get_frames()
@@ -1793,30 +1959,6 @@ class MainWindow(QMainWindow):
dialog.exec_() dialog.exec_()
# Refresh camera list after dialog closes # Refresh camera list after dialog closes
self.populate_camera_menu() self.populate_camera_menu()
def show_camera_selector(self):
"""Show the camera selector dialog"""
dialog = CameraSelectorDialog(self)
if dialog.exec_() == QDialog.Accepted and dialog.selected_cameras:
# Stop current detection if running
was_running = False
if self.stop_btn.isEnabled():
was_running = True
self.stop_detection()
# Update selected cameras
for action in self.camera_action_group.actions():
action.setChecked(action.data() in dialog.selected_cameras)
# Restart detection if it was running
if was_running:
self.start_detection()
def closeEvent(self, event):
"""Handle window close event"""
self.stop_detection()
self.save_settings()
super().closeEvent(event)
if __name__ == "__main__": if __name__ == "__main__":
app = QApplication(sys.argv) app = QApplication(sys.argv)