systeminfo updated in the about section!
All checks were successful
Build MuCaPy Executable / build-and-package (push) Successful in 1m41s

This commit is contained in:
rattatwinko
2025-05-30 22:32:32 +02:00
parent c9c60f7237
commit e50ab9d03c

View File

@@ -16,6 +16,7 @@ from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout
from PyQt5.QtCore import Qt, QTimer, QDir, QSize, QSettings, QDateTime, QRect, QThread, pyqtSignal, QMutex, QObject from PyQt5.QtCore import Qt, QTimer, QDir, QSize, QSettings, QDateTime, QRect, QThread, pyqtSignal, QMutex, QObject
from PyQt5.QtGui import (QImage, QPixmap, QIcon, QColor, QKeySequence, QPainter, from PyQt5.QtGui import (QImage, QPixmap, QIcon, QColor, QKeySequence, QPainter,
QPen, QBrush) QPen, QBrush)
import platform
import time import time
import requests import requests
import subprocess import subprocess
@@ -759,48 +760,92 @@ class CollapsibleDock(QDockWidget):
self.toggle_button.setIcon(QIcon.fromTheme("arrow-left")) self.toggle_button.setIcon(QIcon.fromTheme("arrow-left"))
self.collapsed = False self.collapsed = False
class AboutWindow(QDialog): class AboutWindow(QDialog):
def __init__(self, parent=None): # Add parent parameter with default None def __init__(self, parent=None):
super().__init__(parent) # Pass parent to QDialog super().__init__(parent)
self.setWindowTitle("About Multi-Camera YOLO Detection") self.setWindowTitle("About Multi-Camera YOLO Detection")
self.setWindowIcon(QIcon.fromTheme("help-about")) self.setWindowIcon(QIcon.fromTheme("help-about"))
self.resize(400, 300) self.resize(450, 420)
# Make it modal and stay on top
self.setWindowModality(Qt.ApplicationModal) self.setWindowModality(Qt.ApplicationModal)
self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
layout = QVBoxLayout() layout = QVBoxLayout()
layout.setAlignment(Qt.AlignCenter) layout.setAlignment(Qt.AlignTop)
layout.setSpacing(20) layout.setSpacing(20)
# Application icon/logo (placeholder) # App icon
icon_label = QLabel() icon_label = QLabel()
icon_label.setPixmap(QIcon.fromTheme("camera-web").pixmap(64, 64)) icon_label.setPixmap(QIcon.fromTheme("camera-web").pixmap(64, 64))
icon_label.setAlignment(Qt.AlignCenter) icon_label.setAlignment(Qt.AlignCenter)
layout.addWidget(icon_label) layout.addWidget(icon_label)
# Application title # Title
title_label = QLabel("MuCaPy - 1") title_label = QLabel("MuCaPy - 1")
title_label.setStyleSheet("font-size: 18px; font-weight: bold;") title_label.setStyleSheet("font-size: 18px; font-weight: bold;")
title_label.setAlignment(Qt.AlignCenter) title_label.setAlignment(Qt.AlignCenter)
layout.addWidget(title_label) layout.addWidget(title_label)
# Version information # Version label
version_label = QLabel("Version 1.0") version_label = QLabel("Version 1.0")
version_label.setAlignment(Qt.AlignCenter) version_label.setAlignment(Qt.AlignCenter)
layout.addWidget(version_label) layout.addWidget(version_label)
# Description # Get system info
desc_label = QLabel( info = self.get_system_info()
"MuCaPy\n" self.important_keys = ["Python", "OpenCV", "Memory", "CUDA"]
"Multiple Camera Python\n" self.full_labels = {}
"Using CV2"
)
desc_label.setAlignment(Qt.AlignCenter)
desc_label.setWordWrap(True)
layout.addWidget(desc_label)
# Close Button # === System Info Group ===
self.sysinfo_box = QGroupBox()
sysinfo_main_layout = QVBoxLayout()
sysinfo_main_layout.setContentsMargins(8, 8, 8, 8)
# Header layout: title + triangle button
header_layout = QHBoxLayout()
header_label = QLabel("System Information")
header_label.setStyleSheet("font-weight: bold;")
header_layout.addWidget(header_label)
header_layout.addStretch()
self.toggle_btn = QToolButton()
self.toggle_btn.setText("")
self.toggle_btn.setCheckable(True)
self.toggle_btn.setChecked(False)
self.toggle_btn.setStyleSheet("""
QToolButton {
border: none;
background: transparent;
font-size: 14px;
color: #DDD;
}
""")
self.toggle_btn.toggled.connect(self.toggle_expand)
header_layout.addWidget(self.toggle_btn)
sysinfo_main_layout.addLayout(header_layout)
# Details layout
self.sysinfo_layout = QVBoxLayout()
self.sysinfo_layout.setSpacing(5)
for key, value in info.items():
if key == "MemoryGB":
continue
label = QLabel(f"{key}: {value}")
self.style_label(label, key, value)
self.sysinfo_layout.addWidget(label)
self.full_labels[key] = label
if key not in self.important_keys:
label.setVisible(False)
sysinfo_main_layout.addLayout(self.sysinfo_layout)
self.sysinfo_box.setLayout(sysinfo_main_layout)
layout.addWidget(self.sysinfo_box)
# Close button
close_btn = QPushButton("Close") close_btn = QPushButton("Close")
close_btn.clicked.connect(self.accept) close_btn.clicked.connect(self.accept)
close_btn.setFixedWidth(100) close_btn.setFixedWidth(100)
@@ -816,9 +861,9 @@ class AboutWindow(QDialog):
} }
QGroupBox { QGroupBox {
border: 1px solid #555; border: 1px solid #555;
border-radius: 4px; border-radius: 6px;
margin-top: 10px; margin-top: 10px;
padding-top: 15px; padding: 4px;
background-color: #252525; background-color: #252525;
} }
QGroupBox::title { QGroupBox::title {
@@ -841,6 +886,88 @@ class AboutWindow(QDialog):
""") """)
self.setLayout(layout) self.setLayout(layout)
def toggle_expand(self, checked):
for key, label in self.full_labels.items():
if key not in self.important_keys:
label.setVisible(checked)
self.toggle_btn.setText("" if checked else "")
def style_label(self, label, key, value):
if key == "Python":
label.setStyleSheet("color: #7FDBFF;")
elif key == "OpenCV":
label.setStyleSheet("color: #FF851B;")
elif key == "CUDA":
label.setStyleSheet("color: green;" if value == "Yes" else "color: red;")
elif key == "NumPy":
label.setStyleSheet("color: #B10DC9;")
elif key == "Requests":
label.setStyleSheet("color: #0074D9;")
elif key == "Memory":
try:
ram = int(value.split()[0])
if ram < 8:
label.setStyleSheet("color: red;")
elif ram < 16:
label.setStyleSheet("color: yellow;")
elif ram < 32:
label.setStyleSheet("color: lightgreen;")
else:
label.setStyleSheet("color: #90EE90;")
except:
label.setStyleSheet("color: gray;")
elif key == "CPU Usage":
try:
usage = float(value.strip('%'))
if usage > 80:
label.setStyleSheet("color: red;")
elif usage > 50:
label.setStyleSheet("color: yellow;")
else:
label.setStyleSheet("color: lightgreen;")
except:
label.setStyleSheet("color: gray;")
elif key in ("CPU Cores", "Logical CPUs"):
label.setStyleSheet("color: lightgreen;")
elif key in ("CPU", "Architecture", "OS"):
label.setStyleSheet("color: lightgray;")
else:
label.setStyleSheet("color: #DDD;")
def get_system_info(self):
import platform
info = {}
info['Python'] = sys.version.split()[0]
info['OS'] = f"{platform.system()} {platform.release()}"
info['Architecture'] = platform.machine()
info['OpenCV'] = cv2.__version__
info['CUDA'] = "Yes" if cv2.cuda.getCudaEnabledDeviceCount() > 0 else "No"
info['NumPy'] = np.__version__
info['Requests'] = requests.__version__
mem = psutil.virtual_memory()
info['MemoryGB'] = mem.total // (1024**3)
info['Memory'] = f"{info['MemoryGB']} GB RAM"
info['CPU Cores'] = psutil.cpu_count(logical=False)
info['Logical CPUs'] = psutil.cpu_count(logical=True)
info['CPU Usage'] = f"{psutil.cpu_percent()}%"
try:
if sys.platform == "win32":
info['CPU'] = platform.processor()
elif sys.platform == "linux":
info['CPU'] = subprocess.check_output("lscpu", shell=True).decode().split("\n")[0]
elif sys.platform == "darwin":
info['CPU'] = subprocess.check_output(["sysctl", "-n", "machdep.cpu.brand_string"]).decode().strip()
except Exception:
info['CPU'] = "Unknown"
return info
class NetworkCameraDialog(QDialog): class NetworkCameraDialog(QDialog):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)