From acf50c199caea487121124c5c879f0b4edf2fe7a Mon Sep 17 00:00:00 2001 From: rattatwinko Date: Sun, 8 Jun 2025 20:24:45 +0200 Subject: [PATCH] modern warfare 2025 --- .vscode/launch.json | 21 ++++++ mucapy/main.py | 139 +++++++++++++++++++++++++++-------- mucapy/styling/mw.qss | 95 ++++++++++++++++++++++++ mucapy/styling/todostyle.qss | 5 ++ mucapy/todo.py | 50 +++++++++++++ 5 files changed, 278 insertions(+), 32 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 mucapy/styling/mw.qss create mode 100644 mucapy/styling/todostyle.qss create mode 100644 mucapy/todo.py diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..d1d2d72 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python Debugger: Current File", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "console": "externalTerminal" + }, + { + "name": "Python Debugger: Python File", + "type": "debugpy", + "request": "launch", + "program": "${file}" + } + ] +} diff --git a/mucapy/main.py b/mucapy/main.py index 5afbcd2..07161d9 100644 --- a/mucapy/main.py +++ b/mucapy/main.py @@ -17,6 +17,7 @@ from PyQt5.QtCore import Qt, QTimer, QDir, QSize, QSettings, QDateTime, QRect, Q from PyQt5.QtGui import (QImage, QPixmap, QIcon, QColor, QKeySequence, QPainter, QPen, QBrush) import platform +import todo import time import requests import subprocess @@ -68,8 +69,11 @@ class Config: try: # Ensure the file's directory exists os.makedirs(os.path.dirname(self.config_file), exist_ok=True) - with open(self.config_file, 'w') as f: - json.dump(self.settings, f, indent=4) + try: + with open(self.config_file, 'w') as f: + json.dump(self.settings, f, indent=4) + except FileNotFoundError: + exit(1) except Exception as e: print(f"Error saving config: {e}") @@ -421,8 +425,11 @@ class MultiCamYOLODetector(QObject): self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV) self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU) - with open(classes_path, 'r') as f: - self.classes = f.read().strip().split('\n') + try: + with open(classes_path, 'r') as f: + self.classes = f.read().strip().split('\n') + except FileNotFoundError: + exit(1) np.random.seed(42) self.colors = np.random.randint(0, 255, size=(len(self.classes), 3), dtype='uint8') @@ -566,8 +573,11 @@ class CameraDisplay(QLabel): self.setText("No camera feed") self.get_camera_display_style = getpath.resource_path("styling/camera_display.qss") - with open(self.get_camera_display_style,"r") as cdst: - self.setStyleSheet(cdst.read()) + try: + with open(self.get_camera_display_style,"r") as cdst: + self.setStyleSheet(cdst.read()) + except FileNotFoundError: + exit(1) self.setMinimumSize(320, 240) self.fullscreen_window = None @@ -816,8 +826,11 @@ class AboutWindow(QDialog): self.toggle_btn.setCheckable(True) self.toggle_btn.setChecked(False) toggle_btn_style = getpath.resource_path("styling/togglebtnabout.qss") - with open(toggle_btn_style,"r") as tgbstyle: - self.toggle_btn.setStyleSheet(tgbstyle.read()) + try: + with open(toggle_btn_style,"r") as tgbstyle: + self.toggle_btn.setStyleSheet(tgbstyle.read()) + except FileNotFoundError: + exit(1) # Debug shit #print("i did shit") @@ -855,11 +868,44 @@ class AboutWindow(QDialog): # Set Styling for About Section style_file = getpath.resource_path("styling/about.qss") - with open(style_file,"r") as aboutstyle: - self.setStyleSheet(aboutstyle.read()) + try: + with open(style_file,"r") as aboutstyle: + self.setStyleSheet(aboutstyle.read()) + except FileNotFoundError: + exit(1) self.setLayout(layout) + # Todo Label Shit + self.todo_obj = todo.todo() + todo_text = self.get_todo_text() + todo_label = QLabel(f"
{todo_text}
") + todo_label.setWordWrap(True) + todo_label.setAlignment(Qt.AlignCenter) + + # TODO: Fix this xD ; Fixing a TODO lol + try: + todo_style_path = getpath.resource_path("styling/todostyle.qss") + with open(todo_style_path,"r") as tdf: + todo_label.setStyleSheet(tdf.read()) + # here we have our wonderfull fix + if True == True: + todo_label.setStyleSheet("color: #f7ef02; font-style: italic;") + else: + pass + except FileNotFoundError: + print(f"Missing a Style File! => {todo_style_path}") + exit(1) + + self.camobj = todo.todo() + cam_text = self.get_cam_text() + cam_label = QLabel(f"
{cam_text}
") + cam_label.setWordWrap(True) + cam_label.setAlignment(Qt.AlignCenter) + cam_label.setStyleSheet("color: #FFFF; font-style: italic;") + layout.addWidget(todo_label) + layout.addWidget(cam_label) + def toggle_expand(self, checked): for key, label in self.full_labels.items(): if key not in self.important_keys: @@ -946,6 +992,26 @@ class AboutWindow(QDialog): return info + def get_todo_text(self): + try: + todo_text = self.todo_obj.gettodo() + if isinstance(todo_text, str): + return todo_text.strip() + else: + return "Invalid TODO format." + except Exception as e: + return f"Error retrieving TODO: {e}" + + def get_cam_text(self): + try: + cam_text = self.camobj.getcams() + if isinstance(cam_text,str): + return cam_text.strip() + else: + return "invalid cam format" + except Exception as e: + return f"You are fuck you {e}" + class NetworkCameraDialog(QDialog): @@ -1438,8 +1504,11 @@ class MainWindow(QMainWindow): # Set dark theme style style_file = getpath.resource_path("styling/mainwindow.qss") - with open(style_file, "r") as mainstyle: - self.setStyleSheet(mainstyle.read()) + try: + with open(style_file, "r") as mainstyle: + self.setStyleSheet(mainstyle.read()) + except FileNotFoundError: + exit(1) # Set palette for better dark mode support palette = self.palette() @@ -1958,9 +2027,12 @@ class MainWindow(QMainWindow): # Set Styling from cpu progress QSS file style_file = getpath.resource_path("styling/cpu_progress.qss") - with open(style_file,"r") as cpu_progress_style: - self.cpu_progress.setStyleSheet(cpu_progress_style.read()) - + try: + with open(style_file,"r") as cpu_progress_style: + self.cpu_progress.setStyleSheet(cpu_progress_style.read()) + except FileNotFoundError: + pass + cpu_layout.addWidget(self.cpu_progress) hw_monitor_layout.addLayout(cpu_layout) @@ -1976,9 +2048,12 @@ class MainWindow(QMainWindow): core_bar.setFormat("%p%") core_file = getpath.resource_path("styling/core_bar.qss") - with open(core_file,"r") as core_bar_styling: - core_bar.setStyleSheet(core_bar_styling.read()) - + try: + with open(core_file,"r") as core_bar_styling: + core_bar.setStyleSheet(core_bar_styling.read()) + except FileNotFoundError: + pass + cores_layout.addWidget(core_label, i, 0) cores_layout.addWidget(core_bar, i, 1) self.core_bars.append(core_bar) @@ -2043,8 +2118,11 @@ class MainWindow(QMainWindow): for display in self.camera_displays: display.setText("No camera feed") cleardisplaypath = getpath.resource_path("styling/cleardisplay.qss") - with open(cleardisplaypath,"r") as cdstyle: - display.setStyleSheet(cdstyle.read()) + try: + with open(cleardisplaypath,"r") as cdstyle: + display.setStyleSheet(cdstyle.read()) + except FileNotFoundError: + pass def update_feeds(self): """Update the camera feeds in the display""" @@ -2271,6 +2349,13 @@ class MainWindow(QMainWindow): self.stop_btn.setEnabled(False) class initQT(): + """ + This is a QOL Change if you prefer to do it the hard way. Or you just like to get Fist Fucked then i suggest you remove the Function Calls in the + Main Call of the Class! + + This is not needed for Windows as it does this Automatically (at least i think) + If some shit that is supposed to happen isnt happening. Step through this Class Via Debuggers! + """ def __init__(self): self.session_type = None # This is for QT # #--------------------# @@ -2280,11 +2365,6 @@ class initQT(): # If the OS is Linux get Qts Session Type if platform.system() == "Linux": self.session_type = os.getenv("XDG_SESSION_TYPE") - -# Enable this is stuff is exiting! - -# print(f"got {self.session_type} ") - return self.session_type else: # If theres no Type then Exit 1 @@ -2299,10 +2379,6 @@ class initQT(): # Set the Session Type to the one it got if self.session_type: os.environ["XDG_SESSION_TYPE"] = self.session_type - -# Enable if stuff is exiting! - -# print(f"set the ENVVAR to {self.session_type}") else: # If this fails then just exit with 1 print( @@ -2319,14 +2395,14 @@ class initQT(): pass if __name__ == "__main__": - # Initialize Qt if on Linux + # Initialize Qt if on Linux ; If shit fails then modify these Functions if platform.system() == "Linux": qt = initQT() qt.getenv() qt.setenv() qt.shutupCV() else: - # We do nothing, Windows doesnt need this + # We do nothing, Windows doesnt need this ; better shit anyways pass app = QApplication(sys.argv) @@ -2339,7 +2415,6 @@ if __name__ == "__main__": # Set application style to Fusion for better dark mode support app.setStyle("Fusion") - window = MainWindow() window.show() diff --git a/mucapy/styling/mw.qss b/mucapy/styling/mw.qss new file mode 100644 index 0000000..b8b9464 --- /dev/null +++ b/mucapy/styling/mw.qss @@ -0,0 +1,95 @@ +QMainWindow, QWidget { + background-color: #2D2D2D; + color: #DDD; +} + +QLabel { + color: #DDD; +} + +QPushButton { + background-color: #3A3A3A; + color: #DDD; + border: 1px solid #555; + border-radius: 4px; + padding: 5px; +} + +QPushButton:hover { + background-color: #4A4A4A; +} + +QPushButton:pressed { + background-color: #2A2A2A; +} + +QPushButton:disabled { + background-color: #2A2A2A; + color: #777; +} + +QComboBox, QSpinBox { + background-color: #3A3A3A; + color: #DDD; + border: 1px solid #555; + border-radius: 4px; + padding: 3px; +} + +QGroupBox { + border: 1px solid #555; + border-radius: 4px; + margin-top: 10px; + padding-top: 15px; + background-color: #252525; +} + +QGroupBox::title { + subcontrol-origin: margin; + left: 10px; + padding: 0 3px; + color: #DDD; +} + +QMenuBar { + background-color: #252525; + color: #DDD; +} + +QMenuBar::item { + background-color: transparent; + padding: 5px 10px; +} + +QMenuBar::item:selected { + background-color: #3A3A3A; +} + +QMenu { + background-color: #252525; + border: 1px solid #444; + color: #DDD; +} + +QMenu::item:selected { + background-color: #3A3A3A; +} + +QScrollArea { + border: none; +} + +QDockWidget { + titlebar-close-icon: url(none); + titlebar-normal-icon: url(none); +} + +QDockWidget::title { + background: #252525; + padding-left: 5px; +} + +QToolButton { + background-color: transparent; + border: none; +} \ No newline at end of file diff --git a/mucapy/styling/todostyle.qss b/mucapy/styling/todostyle.qss new file mode 100644 index 0000000..70412f5 --- /dev/null +++ b/mucapy/styling/todostyle.qss @@ -0,0 +1,5 @@ +QLabel#todoLabel { + color:rgb(21, 255, 0); + font-family: monospace; + font-size: 12px; +} diff --git a/mucapy/todo.py b/mucapy/todo.py new file mode 100644 index 0000000..998c75b --- /dev/null +++ b/mucapy/todo.py @@ -0,0 +1,50 @@ +""" +Here we have a simple fucking class to get the fuckass Todo thing +Probably will do none of them +anyways, if you have suggestions pr this shit + +idk if you are smarter than me then actually do them. + +fuck you + -Rattatwinko 8.jun.25 (20:25) +""" + +class todo: + def __init__(self): +#------------------------------------------------------------------------------------------------------------------------------------------------# + self.todo : str = """ + +Very Good Very Nice Todo List: + +NOTE: If you want to run this in Visual Studio Codes built in Terminal you will get fucked in your tiny tight ass. +NOTE: If you are running this from the Build Executable from the Workflow , you ass is fine (you wont get fucked you slut) +NOTE: If you compiled this yourself ; you are one Fucking Genious + +#-----------------------# +# Changes: # +# Not Very Much lolz # +#-----------------------# + +TODO: + [] - Fix Network Cameras from Crashing the Programm (This sometimes happens when only network cams are selected and it times out) + [] - Make Seperate Styling (unlikely that this will happen) + [] - RTSP Camera Streaming + [] - Make MJPEG more stable and efficient. (maybe use c++ for this or rust) + - NOTE: http://pendelcam.kip.uni-heidelberg.de/mjpg/video.mjpg + This is a Testing URL for MJPEG (stable and renders fine) + +""" # This will display Centered (look in about window class) +#------------------------------------------------------------------------------------------------------------------------------------------------# + + self.cameraURL : str = """ +Cameras: + - http://pendelcam.kip.uni-heidelberg.de/mjpg/video.mjpg +""" # This will also display centered + +#------------------------------------------------------------------------------------------------------------------------------------------------# + + def gettodo(self) -> str: + return self.todo + def getcams(self) -> str: + return self.cameraURL +