Files
Traffic-Intersection-Monito…/qt_app_pyside1/ui/analytics_tab_new.py
2025-08-26 13:24:53 -07:00

299 lines
11 KiB
Python

from PySide6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QPushButton, QTabWidget, QTableWidget, QTableWidgetItem, QHeaderView
)
from PySide6.QtCore import Qt, Slot
from PySide6.QtGui import QColor, QFont
class CleanAnalyticsWidget(QWidget):
"""Clean and minimal analytics widget with tabbed interface"""
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
"""Initialize the clean UI with tabs"""
layout = QVBoxLayout(self)
layout.setContentsMargins(10, 10, 10, 10)
layout.setSpacing(10)
# Title
title_label = QLabel("🚦 Traffic Intersection Monitor")
title_label.setStyleSheet("""
QLabel {
font-size: 20px;
font-weight: bold;
color: #2C3E50;
font-family: 'Roboto', Arial, sans-serif;
padding: 15px;
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop:0 #E8F4FD, stop:1 #F8FBFE);
border-radius: 8px;
border: 1px solid #BDC3C7;
}
""")
title_label.setAlignment(Qt.AlignCenter)
layout.addWidget(title_label)
# Create tab widget
self.tab_widget = QTabWidget()
self.tab_widget.setStyleSheet("""
QTabWidget::pane {
border: 1px solid #BDC3C7;
border-radius: 8px;
background-color: white;
}
QTabBar::tab {
background: #ECF0F1;
color: #2C3E50;
padding: 12px 20px;
margin-right: 2px;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
font-family: 'Roboto', Arial, sans-serif;
font-weight: 500;
min-width: 120px;
}
QTabBar::tab:selected {
background: #3498DB;
color: white;
}
QTabBar::tab:hover:!selected {
background: #D5DBDB;
}
""")
# Create tabs
self.create_traffic_light_tab()
self.create_violation_tab()
self.create_vehicle_tab()
layout.addWidget(self.tab_widget)
# Refresh button
refresh_btn = QPushButton("🔄 Refresh Data")
refresh_btn.setStyleSheet("""
QPushButton {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #3498DB, stop:1 #2980B9);
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
font-weight: bold;
font-family: 'Roboto', Arial, sans-serif;
font-size: 14px;
}
QPushButton:hover {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #5DADE2, stop:1 #3498DB);
}
QPushButton:pressed {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #2980B9, stop:1 #21618C);
}
""")
refresh_btn.clicked.connect(self.refresh_all_data)
# Center the button
button_layout = QHBoxLayout()
button_layout.addStretch()
button_layout.addWidget(refresh_btn)
button_layout.addStretch()
layout.addLayout(button_layout)
def create_traffic_light_tab(self):
"""Create traffic light status tab"""
tab = QWidget()
layout = QVBoxLayout(tab)
layout.setContentsMargins(15, 15, 15, 15)
# Table
self.traffic_table = QTableWidget(0, 5)
self.traffic_table.setHorizontalHeaderLabels([
"Detection", "Red Ratio", "Yellow Ratio", "Green Ratio", "Status"
])
# Apply clean table styling
self.apply_table_style(self.traffic_table)
# Sample data
sample_data = [
["Traffic Light 1", "0.353", "0.000", "0.000", "🔴 Red"],
["Traffic Light 2", "0.399", "0.000", "0.000", "🔴 Red"],
["Traffic Light 3", "0.499", "0.000", "0.000", "🔴 Red"],
["Traffic Light 4", "0.728", "0.000", "0.000", "🔴 Red"],
["Traffic Light 5", "0.958", "0.000", "0.000", "🔴 Red"],
["Traffic Light 6", "0.623", "0.000", "0.000", "🔴 Red"],
]
self.populate_table(self.traffic_table, sample_data, "traffic_light")
layout.addWidget(self.traffic_table)
self.tab_widget.addTab(tab, "🚦 Traffic Lights")
def create_violation_tab(self):
"""Create violation summary tab"""
tab = QWidget()
layout = QVBoxLayout(tab)
layout.setContentsMargins(15, 15, 15, 15)
# Table
self.violation_table = QTableWidget(0, 3)
self.violation_table.setHorizontalHeaderLabels([
"Track ID", "Violation Type", "Status"
])
# Apply clean table styling
self.apply_table_style(self.violation_table)
# Sample data
sample_data = [
["4", "🚨 Red Light Violation", "Active"],
["4", "Improper Stop on Crosswalk", "Detected"],
]
self.populate_table(self.violation_table, sample_data, "violation")
layout.addWidget(self.violation_table)
self.tab_widget.addTab(tab, "🚨 Violations")
def create_vehicle_tab(self):
"""Create vehicle tracking status tab"""
tab = QWidget()
layout = QVBoxLayout(tab)
layout.setContentsMargins(15, 15, 15, 15)
# Table
self.vehicle_table = QTableWidget(0, 6)
self.vehicle_table.setHorizontalHeaderLabels([
"Track ID", "Position (x,y)", "Center Y", "Moving", "Violating", "Status"
])
# Apply clean table styling
self.apply_table_style(self.vehicle_table)
# Sample data
sample_data = [
["1", "(387.0, 214.5)", "214.5", "False", "False", "🟢 Tracked"],
["2", "(380.5, 135.0)", "135.0", "False", "False", "🟢 Tracked"],
["3", "(258.5, 151.5)", "151.5", "False", "False", "🟢 Tracked"],
["4", "(519.0, 187.0)", "187.0", "False", "True", "🔴 Violating"],
["5", "(520.0, 132.0)", "132.0", "False", "False", "🟢 Tracked"],
["6", "(615.0, 172.0)", "172.0", "False", "False", "🟢 Tracked"],
["7", "(561.5, 334.0)", "334.0", "False", "False", "🟢 Tracked"],
["8", "(401.5, 71.5)", "71.5", "False", "False", "🟢 Tracked"],
]
self.populate_table(self.vehicle_table, sample_data, "vehicle")
layout.addWidget(self.vehicle_table)
self.tab_widget.addTab(tab, "🚗 Vehicles")
def apply_table_style(self, table):
"""Apply consistent styling to tables"""
# Set font
font = QFont("Roboto", 10)
table.setFont(font)
# Header styling
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
table.horizontalHeader().setStyleSheet("""
QHeaderView::section {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #34495E, stop:1 #2C3E50);
color: white;
padding: 10px;
border: 1px solid #2C3E50;
font-weight: bold;
font-family: 'Roboto', Arial, sans-serif;
}
""")
# Table styling
table.setStyleSheet("""
QTableWidget {
gridline-color: #E8E8E8;
background-color: white;
alternate-background-color: #F8F9FA;
selection-background-color: #E3F2FD;
border: 1px solid #E0E0E0;
border-radius: 6px;
}
QTableWidget::item {
padding: 8px;
border-bottom: 1px solid #E8E8E8;
}
QTableWidget::item:selected {
background-color: #E3F2FD;
color: #1976D2;
}
""")
# Enable alternating row colors
table.setAlternatingRowColors(True)
# Set selection behavior
table.setSelectionBehavior(QTableWidget.SelectRows)
def populate_table(self, table, data, table_type):
"""Populate table with data and apply color coding"""
table.setRowCount(len(data))
for i, row in enumerate(data):
for j, item in enumerate(row):
cell = QTableWidgetItem(str(item))
# Apply color coding based on content
if table_type == "traffic_light":
if "🔴" in str(item):
cell.setBackground(QColor(255, 235, 235)) # Light red
elif "🟡" in str(item):
cell.setBackground(QColor(255, 255, 235)) # Light yellow
elif "🟢" in str(item):
cell.setBackground(QColor(235, 255, 235)) # Light green
elif table_type == "violation":
if "Active" in str(item) or "🚨" in str(item):
cell.setBackground(QColor(255, 235, 235)) # Light red
elif "Detected" in str(item):
cell.setBackground(QColor(255, 248, 235)) # Light orange
elif table_type == "vehicle":
if "🔴" in str(item) or "True" in str(item) and j == 4: # Violating column
cell.setBackground(QColor(255, 235, 235)) # Light red
elif "🟢" in str(item):
cell.setBackground(QColor(235, 255, 235)) # Light green
table.setItem(i, j, cell)
def refresh_all_data(self):
"""Refresh all tables with latest data"""
print("🔄 Refreshing analytics data...")
# This would be connected to actual data update logic
class AnalyticsTab(QWidget):
"""Main analytics tab with clean design"""
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
"""Initialize the main analytics interface"""
layout = QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
# Create the clean analytics widget
self.analytics_widget = CleanAnalyticsWidget()
layout.addWidget(self.analytics_widget)
@Slot(dict)
def update_analytics(self, analytics):
"""Update analytics with new data (placeholder for future implementation)"""
# This would update the tables with real-time data
pass