Source code for districtheatingsim.DistrictHeatingSim

"""
Main entry point for the DistrictHeatingSim application.

This module provides a PyQt6-based GUI application for planning and optimizing
district heating networks. It implements the Model-View-Presenter (MVP) pattern
with clear separation between data management, business logic, and user interface.

:author: Dipl.-Ing. (FH) Jonas Pfeiffer

The application provides:

    - Project management with variant support
    - Building heat demand calculation using BDEW profiles
    - Network generation from GIS data (OpenStreetMap)
    - Thermohydraulic simulation with pandapipes
    - Heat generator sizing and economic analysis
    - Multi-variant comparison

Architecture:

    - **Model**: ProjectConfigManager, DataManager, ProjectFolderManager
    - **View**: HeatSystemDesignGUI (main window with tab-based interface)
    - **Presenter**: HeatSystemPresenter (coordinates business logic)

.. note::
    The application uses time-based theme selection (light/dark mode) and
    supports Windows taskbar integration when available.
"""

import sys
import os
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)

from PyQt6.QtWidgets import QApplication
from PyQt6.QtCore import QTimer

from districtheatingsim.utilities.utilities import handle_global_exception, get_stylesheet_based_on_time

from districtheatingsim.gui.MainTab.main_presenter import HeatSystemPresenter
from districtheatingsim.gui.MainTab.main_view import HeatSystemDesignGUI
from districtheatingsim.gui.MainTab.main_data_manager import ProjectConfigManager
from districtheatingsim.gui.MainTab.main_data_manager import DataManager
from districtheatingsim.gui.MainTab.main_data_manager import ProjectFolderManager


[docs] def main(): """ Initialize and launch the DistrictHeatingSim application. This function sets up the Qt application, initializes all managers (config, data, folder), creates the main GUI window, connects the MVP components, applies the theme, and starts the event loop. :raises SystemExit: Normal application termination :raises Exception: Caught by global exception handler for user-friendly error reporting .. note:: Windows-specific taskbar integration is applied if available but fails gracefully on other platforms. """ # Configure global exception handling for user-friendly error reporting sys.excepthook = handle_global_exception # Initialize Qt application with Fusion style for consistent appearance app = QApplication(sys.argv) app.setStyle('Fusion') # Configure Windows-specific taskbar integration for professional appearance try: import ctypes # Set unique application ID for proper Windows taskbar grouping myappid = 'districtheatingsim.main.1.0' # Unique app identifier ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid) except ImportError: # Graceful fallback for non-Windows systems print("Windows-specific taskbar integration not available on this platform.") pass except Exception as e: # Handle any other Windows integration errors print(f"Warning: Could not configure Windows taskbar integration: {e}") pass # Initialize the core application managers with proper dependency injection config_manager = ProjectConfigManager() folder_manager = ProjectFolderManager(config_manager) data_manager = DataManager() # Create the main GUI window with manager dependencies view = HeatSystemDesignGUI(folder_manager, data_manager) # Initialize the presenter and establish MVP connections presenter = HeatSystemPresenter(view, folder_manager, data_manager, config_manager) view.set_presenter(presenter) # Apply time-based theme for optimal user experience theme_path = get_stylesheet_based_on_time() view.applyTheme(theme_path) # Load initial application data for immediate availability presenter.view.updateTemperatureData() presenter.view.updateHeatPumpData() # Configure window display with proper timing to ensure complete initialization QTimer.singleShot(0, lambda: view.showMaximized()) QTimer.singleShot(0, lambda: view.update_project_folder_label(folder_manager.variant_folder)) # Display the main window and enter the Qt event loop view.show() # Start the application event loop and handle clean shutdown exit_code = app.exec() sys.exit(exit_code)
if __name__ == '__main__': import traceback # Check if stdin is available (console window exists) has_console = sys.stdin is not None and hasattr(sys.stdin, 'fileno') try: if has_console: print("DistrictHeatingSim wird gestartet...") print("-" * 80) main() except Exception as e: if has_console: print("\n" + "="*80) print("FEHLER BEIM START DER ANWENDUNG") print("="*80) print(f"\nFehlermeldung: {e}\n") print("Vollständiger Traceback:") print("-"*80) traceback.print_exc() print("-"*80) print("\nDrücken Sie ENTER zum Beenden...") try: input() except: pass sys.exit(1) finally: # Keep console open when console window exists (debug builds, development) if has_console: print("\n" + "="*80) print("Drücken Sie ENTER zum Beenden der Konsole...") try: input() except: pass