Source code for tommy.main_window

import os

from PySide6.QtCore import Qt
from PySide6.QtGui import QIcon, QGuiApplication
from PySide6.QtWidgets import (
    QMainWindow,
    QWidget, QHBoxLayout, QVBoxLayout, QSizePolicy
)

from tommy.controller.controller import Controller
from tommy.support.constant_variables import (
    text_font)
from tommy.view.graph_view import GraphView
from tommy.view.imported_files_view.file_label import FileLabel
from tommy.view.imported_files_view.imported_files_view import (
    ImportedFilesView)
from tommy.view.menu_bar import MenuBar
from tommy.view.plot_selection_view import (
    PlotSelectionView)
from tommy.view.selected_information_view import SelectedInformationView
from tommy.view.preprocessing_view import (
    PreprocessingView)
from tommy.view.settings_view.model_params_view import (
    ModelParamsView)
from tommy.view.supporting_components.custom_splitter.custom_splitter_component import \
    CustomSplitter
from tommy.view.topic_view.fetched_topics_view import \
    FetchedTopicsView
from tommy.view.topic_view.topic_entity_component.topic_entity import (
    TopicEntity)

from tommy.support.application_settings import get_assets_folder


[docs] class MainWindow(QMainWindow): """Main window class for the topic modelling application"""
[docs] def __init__(self) -> None: """Initialize the main window.""" super().__init__() # Create the main Controller self._controller: Controller = Controller() # Initialize window self.setWindowTitle("TOMMY") self.set_initial_window_size() self.setWindowIcon( QIcon(f"{os.path.join(get_assets_folder(), "tommy.png")}")) self.setStyleSheet(f""" QMainWindow {{ background-color: white; font-size: 15px; font-family: {text_font}; border: none; }} QMainWindow::children {{ font-family: {text_font}; }} QSplitter::handle {{ background-color: rgba(200, 200, 200, 200); border: none; }} """) # Create the main layout self.layout = QHBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(0) # Create the custom splitter to handle resizing self.splitter = CustomSplitter(Qt.Horizontal) self.splitter.setStyleSheet("border: none;" "background-color: white;") self.splitter.setContentsMargins(0, 0, 0, 0) self.left_container = QWidget() self.left_layout = QVBoxLayout(self.left_container) self.left_layout.setContentsMargins(0, 0, 0, 0) self.left_layout.setSpacing(0) self.center_container = QWidget() self.center_layout = QVBoxLayout(self.center_container) self.center_layout.setContentsMargins(0, 0, 0, 0) self.center_layout.setSpacing(0) self.right_container = QWidget() self.right_layout = QVBoxLayout(self.right_container) self.right_layout.setContentsMargins(0, 0, 0, 0) self.right_layout.setSpacing(0) self.splitter.addWidget(self.left_container) self.splitter.addWidget(self.center_container) self.splitter.addWidget(self.right_container) # Adjust size policies and minimum widths self.left_container.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.right_container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.center_container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.layout.addWidget(self.splitter) # Set the central widget central_widget = QWidget() central_widget.setLayout(self.layout) self.setCentralWidget(central_widget) # Initialize the menu bar self.setMenuBar(MenuBar(self, self._controller.project_settings_controller, self._controller.saving_loading_controller, self._controller.export_controller, self._controller.topic_modelling_controller)) # Create widgets self.preprocessing_view = PreprocessingView( self._controller.stopwords_controller, self._controller.synonyms_controller, self._controller.topic_modelling_controller) self.graph_view = GraphView() self.plot_selection_view = PlotSelectionView( self._controller.graph_controller, self._controller.config_controller, self.graph_view ) self.imported_files_view = ImportedFilesView( self._controller.corpus_controller, self._controller.topic_modelling_controller, self._controller.config_controller ) self.model_params_view = ModelParamsView( self._controller.model_parameters_controller, self._controller.language_controller, self._controller.config_controller, self._controller.topic_modelling_controller) self.fetched_topics_view = FetchedTopicsView( self._controller.graph_controller, self._controller.model_parameters_controller) self.selected_information_view = SelectedInformationView( self._controller.graph_controller, self._controller.model_parameters_controller) # Initialize widgets self.left_layout.addWidget(self.model_params_view) self.left_layout.addWidget(self.preprocessing_view) self.center_layout.addWidget(self.plot_selection_view) self.center_layout.addWidget(self.graph_view) self.center_layout.addWidget(self.imported_files_view) self.right_layout.addWidget(self.fetched_topics_view) self.right_layout.addWidget(self.selected_information_view) # Adjust the splitter stretch factors self.splitter.setStretchFactor(0, 1) self.splitter.setStretchFactor(1, 3) self.splitter.setStretchFactor(2, 1) self.display_correct_initial_files() # Initialize event handlers self.imported_files_view.fileClicked.connect(self.on_file_clicked) self.fetched_topics_view.topicClicked.connect(self.on_topic_clicked) self.fetched_topics_view.topicNameChanged.connect( self.on_topic_name_changed)
[docs] def initialize_widget(self, widget: QWidget, x: int, y: int, w: int, h: int) -> None: """ Initialize a widget on the main window. :param widget: The widget to initialize :param x: The x-coordinate of the widget :param y: The y-coordinate of the widget :param w: The width of the widget :param h: The height of the widget :return: None """ widget.setParent(self) widget.setGeometry(x, y, w, h) widget.show()
[docs] def set_initial_window_size(self) -> None: """ Set the initial window size based on screen size. :return: None """ app = QGuiApplication.instance() screen = app.primaryScreen() screen_geometry = screen.availableGeometry() initial_width = max(screen_geometry.width() / 1.5, 1050) initial_height = max(screen_geometry.height() / 1.5, 578) self.resize(initial_width, initial_height)
[docs] def on_file_clicked(self, file: FileLabel) -> None: """ Event handler for when a file is clicked. :param file: The file that was clicked :return: None """ # Show info about run if no file is selected if not file.selected: self.selected_information_view.display_run_info("Run Info") return self.selected_information_view.display_file_info(file)
[docs] def on_topic_clicked(self, topic_entity: TopicEntity) -> None: """ Event handler for when a topic is clicked. :param topic_entity: The topic that was clicked :return: None """ self.imported_files_view.deselect_all_files() self.imported_files_view.selected_label = None # Show info about run if no topic is selected if not topic_entity.selected: self.imported_files_view.display_files() self.selected_information_view.display_run_info("Run Info") return self.imported_files_view.on_topic_selected(topic_entity) self.selected_information_view.display_topic_info(topic_entity)
[docs] def on_topic_name_changed(self, topic_entity: TopicEntity) -> None: """ Event handler for when a topic name is changed. :param topic_entity: The topic entity whose name was changed :return: None """ if topic_entity.selected: self.selected_information_view.display_topic_info(topic_entity)
[docs] def display_correct_initial_files(self) -> None: """ Display the correct initial files in the main window. Setting the input folder path in the project settings will automatically notify the corpus model to extract the metadata from the files. Once the metadata is extracted, the imported files view will automatically get updated. :return: None """ # get and immediately reset the input folder path to cause the # project settings controller to notify its observers path = (self._controller.project_settings_controller .get_input_folder_path()) self._controller.project_settings_controller.set_input_folder_path( path)
@property def controller(self): return self._controller
""" This program has been developed by students from the bachelor Computer Science at Utrecht University within the Software Project course. © Copyright Utrecht University (Department of Information and Computing Sciences) """