mosamatic2 2.0.24__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- models.py +259 -0
- mosamatic2/__init__.py +0 -0
- mosamatic2/app.py +32 -0
- mosamatic2/cli.py +50 -0
- mosamatic2/commands/__init__.py +0 -0
- mosamatic2/commands/boadockerpipeline.py +48 -0
- mosamatic2/commands/calculatemaskstatistics.py +59 -0
- mosamatic2/commands/calculatescores.py +73 -0
- mosamatic2/commands/createdicomsummary.py +61 -0
- mosamatic2/commands/createpngsfromsegmentations.py +65 -0
- mosamatic2/commands/defaultdockerpipeline.py +84 -0
- mosamatic2/commands/defaultpipeline.py +70 -0
- mosamatic2/commands/dicom2nifti.py +55 -0
- mosamatic2/commands/liveranalysispipeline.py +61 -0
- mosamatic2/commands/rescaledicomimages.py +54 -0
- mosamatic2/commands/segmentmusclefatl3tensorflow.py +55 -0
- mosamatic2/commands/selectslicefromscans.py +66 -0
- mosamatic2/commands/totalsegmentator.py +77 -0
- mosamatic2/constants.py +27 -0
- mosamatic2/core/__init__.py +0 -0
- mosamatic2/core/data/__init__.py +5 -0
- mosamatic2/core/data/dicomimage.py +27 -0
- mosamatic2/core/data/dicomimageseries.py +26 -0
- mosamatic2/core/data/dixonseries.py +22 -0
- mosamatic2/core/data/filedata.py +26 -0
- mosamatic2/core/data/multidicomimage.py +30 -0
- mosamatic2/core/data/multiniftiimage.py +26 -0
- mosamatic2/core/data/multinumpyimage.py +26 -0
- mosamatic2/core/data/niftiimage.py +13 -0
- mosamatic2/core/data/numpyimage.py +13 -0
- mosamatic2/core/managers/__init__.py +0 -0
- mosamatic2/core/managers/logmanager.py +45 -0
- mosamatic2/core/managers/logmanagerlistener.py +3 -0
- mosamatic2/core/pipelines/__init__.py +4 -0
- mosamatic2/core/pipelines/boadockerpipeline/__init__.py +0 -0
- mosamatic2/core/pipelines/boadockerpipeline/boadockerpipeline.py +70 -0
- mosamatic2/core/pipelines/defaultdockerpipeline/__init__.py +0 -0
- mosamatic2/core/pipelines/defaultdockerpipeline/defaultdockerpipeline.py +28 -0
- mosamatic2/core/pipelines/defaultpipeline/__init__.py +0 -0
- mosamatic2/core/pipelines/defaultpipeline/defaultpipeline.py +90 -0
- mosamatic2/core/pipelines/liveranalysispipeline/__init__.py +0 -0
- mosamatic2/core/pipelines/liveranalysispipeline/liveranalysispipeline.py +48 -0
- mosamatic2/core/pipelines/pipeline.py +14 -0
- mosamatic2/core/singleton.py +9 -0
- mosamatic2/core/tasks/__init__.py +13 -0
- mosamatic2/core/tasks/applythresholdtosegmentationstask/__init__.py +0 -0
- mosamatic2/core/tasks/applythresholdtosegmentationstask/applythresholdtosegmentationstask.py +117 -0
- mosamatic2/core/tasks/calculatemaskstatisticstask/__init__.py +0 -0
- mosamatic2/core/tasks/calculatemaskstatisticstask/calculatemaskstatisticstask.py +104 -0
- mosamatic2/core/tasks/calculatescorestask/__init__.py +0 -0
- mosamatic2/core/tasks/calculatescorestask/calculatescorestask.py +152 -0
- mosamatic2/core/tasks/createdicomsummarytask/__init__.py +0 -0
- mosamatic2/core/tasks/createdicomsummarytask/createdicomsummarytask.py +88 -0
- mosamatic2/core/tasks/createpngsfromsegmentationstask/__init__.py +0 -0
- mosamatic2/core/tasks/createpngsfromsegmentationstask/createpngsfromsegmentationstask.py +101 -0
- mosamatic2/core/tasks/dicom2niftitask/__init__.py +0 -0
- mosamatic2/core/tasks/dicom2niftitask/dicom2niftitask.py +45 -0
- mosamatic2/core/tasks/rescaledicomimagestask/__init__.py +0 -0
- mosamatic2/core/tasks/rescaledicomimagestask/rescaledicomimagestask.py +64 -0
- mosamatic2/core/tasks/segmentationnifti2numpytask/__init__.py +0 -0
- mosamatic2/core/tasks/segmentationnifti2numpytask/segmentationnifti2numpytask.py +57 -0
- mosamatic2/core/tasks/segmentationnumpy2niftitask/__init__.py +0 -0
- mosamatic2/core/tasks/segmentationnumpy2niftitask/segmentationnumpy2niftitask.py +86 -0
- mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/__init__.py +0 -0
- mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/paramloader.py +39 -0
- mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/segmentmusclefatl3tensorflowtask.py +122 -0
- mosamatic2/core/tasks/segmentmusclefatt4pytorchtask/__init__.py +0 -0
- mosamatic2/core/tasks/segmentmusclefatt4pytorchtask/paramloader.py +39 -0
- mosamatic2/core/tasks/segmentmusclefatt4pytorchtask/segmentmusclefatt4pytorchtask.py +128 -0
- mosamatic2/core/tasks/selectslicefromscanstask/__init__.py +0 -0
- mosamatic2/core/tasks/selectslicefromscanstask/selectslicefromscanstask.py +249 -0
- mosamatic2/core/tasks/task.py +50 -0
- mosamatic2/core/tasks/totalsegmentatortask/__init__.py +0 -0
- mosamatic2/core/tasks/totalsegmentatortask/totalsegmentatortask.py +75 -0
- mosamatic2/core/utils.py +405 -0
- mosamatic2/server.py +146 -0
- mosamatic2/ui/__init__.py +0 -0
- mosamatic2/ui/mainwindow.py +426 -0
- mosamatic2/ui/resources/VERSION +1 -0
- mosamatic2/ui/resources/icons/mosamatic2.icns +0 -0
- mosamatic2/ui/resources/icons/mosamatic2.ico +0 -0
- mosamatic2/ui/resources/icons/spinner.gif +0 -0
- mosamatic2/ui/resources/images/body-composition.jpg +0 -0
- mosamatic2/ui/settings.py +62 -0
- mosamatic2/ui/utils.py +36 -0
- mosamatic2/ui/widgets/__init__.py +0 -0
- mosamatic2/ui/widgets/dialogs/__init__.py +0 -0
- mosamatic2/ui/widgets/dialogs/dialog.py +16 -0
- mosamatic2/ui/widgets/dialogs/helpdialog.py +9 -0
- mosamatic2/ui/widgets/panels/__init__.py +0 -0
- mosamatic2/ui/widgets/panels/defaultpanel.py +31 -0
- mosamatic2/ui/widgets/panels/logpanel.py +65 -0
- mosamatic2/ui/widgets/panels/mainpanel.py +82 -0
- mosamatic2/ui/widgets/panels/pipelines/__init__.py +0 -0
- mosamatic2/ui/widgets/panels/pipelines/boadockerpipelinepanel.py +195 -0
- mosamatic2/ui/widgets/panels/pipelines/defaultdockerpipelinepanel.py +314 -0
- mosamatic2/ui/widgets/panels/pipelines/defaultpipelinepanel.py +302 -0
- mosamatic2/ui/widgets/panels/pipelines/liveranalysispipelinepanel.py +187 -0
- mosamatic2/ui/widgets/panels/pipelines/pipelinepanel.py +6 -0
- mosamatic2/ui/widgets/panels/settingspanel.py +16 -0
- mosamatic2/ui/widgets/panels/stackedpanel.py +22 -0
- mosamatic2/ui/widgets/panels/tasks/__init__.py +0 -0
- mosamatic2/ui/widgets/panels/tasks/applythresholdtosegmentationstaskpanel.py +271 -0
- mosamatic2/ui/widgets/panels/tasks/calculatemaskstatisticstaskpanel.py +215 -0
- mosamatic2/ui/widgets/panels/tasks/calculatescorestaskpanel.py +238 -0
- mosamatic2/ui/widgets/panels/tasks/createdicomsummarytaskpanel.py +206 -0
- mosamatic2/ui/widgets/panels/tasks/createpngsfromsegmentationstaskpanel.py +247 -0
- mosamatic2/ui/widgets/panels/tasks/dicom2niftitaskpanel.py +183 -0
- mosamatic2/ui/widgets/panels/tasks/rescaledicomimagestaskpanel.py +184 -0
- mosamatic2/ui/widgets/panels/tasks/segmentationnifti2numpytaskpanel.py +192 -0
- mosamatic2/ui/widgets/panels/tasks/segmentationnumpy2niftitaskpanel.py +213 -0
- mosamatic2/ui/widgets/panels/tasks/segmentmusclefatl3tensorflowtaskpanel.py +216 -0
- mosamatic2/ui/widgets/panels/tasks/segmentmusclefatt4pytorchtaskpanel.py +217 -0
- mosamatic2/ui/widgets/panels/tasks/selectslicefromscanstaskpanel.py +193 -0
- mosamatic2/ui/widgets/panels/tasks/taskpanel.py +6 -0
- mosamatic2/ui/widgets/panels/tasks/totalsegmentatortaskpanel.py +195 -0
- mosamatic2/ui/widgets/panels/visualizations/__init__.py +0 -0
- mosamatic2/ui/widgets/panels/visualizations/liversegmentvisualization/__init__.py +0 -0
- mosamatic2/ui/widgets/panels/visualizations/liversegmentvisualization/liversegmentpicker.py +96 -0
- mosamatic2/ui/widgets/panels/visualizations/liversegmentvisualization/liversegmentviewer.py +130 -0
- mosamatic2/ui/widgets/panels/visualizations/liversegmentvisualization/liversegmentvisualization.py +120 -0
- mosamatic2/ui/widgets/panels/visualizations/sliceselectionvisualization/__init__.py +0 -0
- mosamatic2/ui/widgets/panels/visualizations/sliceselectionvisualization/sliceselectionviewer.py +61 -0
- mosamatic2/ui/widgets/panels/visualizations/sliceselectionvisualization/sliceselectionvisualization.py +133 -0
- mosamatic2/ui/widgets/panels/visualizations/sliceselectionvisualization/slicetile.py +63 -0
- mosamatic2/ui/widgets/panels/visualizations/slicevisualization/__init__.py +0 -0
- mosamatic2/ui/widgets/panels/visualizations/slicevisualization/custominteractorstyle.py +80 -0
- mosamatic2/ui/widgets/panels/visualizations/slicevisualization/sliceviewer.py +116 -0
- mosamatic2/ui/widgets/panels/visualizations/slicevisualization/slicevisualization.py +141 -0
- mosamatic2/ui/widgets/panels/visualizations/visualization.py +6 -0
- mosamatic2/ui/widgets/splashscreen.py +101 -0
- mosamatic2/ui/worker.py +29 -0
- mosamatic2-2.0.24.dist-info/METADATA +43 -0
- mosamatic2-2.0.24.dist-info/RECORD +136 -0
- mosamatic2-2.0.24.dist-info/WHEEL +4 -0
- mosamatic2-2.0.24.dist-info/entry_points.txt +5 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import mosamatic2.constants as constants
|
|
3
|
+
from PySide6.QtWidgets import (
|
|
4
|
+
QMainWindow,
|
|
5
|
+
)
|
|
6
|
+
from PySide6.QtGui import (
|
|
7
|
+
QGuiApplication,
|
|
8
|
+
QAction,
|
|
9
|
+
QIcon,
|
|
10
|
+
)
|
|
11
|
+
from PySide6.QtCore import Qt, QByteArray
|
|
12
|
+
from mosamatic2.ui.utils import version, resource_path, is_macos
|
|
13
|
+
from mosamatic2.core.managers.logmanager import LogManager
|
|
14
|
+
from mosamatic2.ui.settings import Settings
|
|
15
|
+
from mosamatic2.ui.widgets.panels.mainpanel import MainPanel
|
|
16
|
+
from mosamatic2.ui.widgets.panels.logpanel import LogPanel
|
|
17
|
+
from mosamatic2.ui.widgets.panels.tasks.rescaledicomimagestaskpanel import RescaleDicomImagesTaskPanel
|
|
18
|
+
from mosamatic2.ui.widgets.panels.tasks.segmentmusclefatl3tensorflowtaskpanel import SegmentMuscleFatL3TensorFlowTaskPanel
|
|
19
|
+
from mosamatic2.ui.widgets.panels.tasks.segmentmusclefatt4pytorchtaskpanel import SegmentMuscleFatT4PyTorchTaskPanel
|
|
20
|
+
from mosamatic2.ui.widgets.panels.tasks.createpngsfromsegmentationstaskpanel import CreatePngsFromSegmentationsTaskPanel
|
|
21
|
+
from mosamatic2.ui.widgets.panels.tasks.calculatescorestaskpanel import CalculateScoresTaskPanel
|
|
22
|
+
from mosamatic2.ui.widgets.panels.tasks.dicom2niftitaskpanel import Dicom2NiftiTaskPanel
|
|
23
|
+
from mosamatic2.ui.widgets.panels.tasks.segmentationnifti2numpytaskpanel import SegmentationNifti2NumpyTaskPanel
|
|
24
|
+
from mosamatic2.ui.widgets.panels.tasks.segmentationnumpy2niftitaskpanel import SegmentationNumpy2NiftiTaskPanel
|
|
25
|
+
from mosamatic2.ui.widgets.panels.tasks.createdicomsummarytaskpanel import CreateDicomSummaryTaskPanel
|
|
26
|
+
from mosamatic2.ui.widgets.panels.tasks.selectslicefromscanstaskpanel import SelectSliceFromScansTaskPanel
|
|
27
|
+
from mosamatic2.ui.widgets.panels.tasks.totalsegmentatortaskpanel import TotalSegmentatorTaskPanel
|
|
28
|
+
from mosamatic2.ui.widgets.panels.tasks.calculatemaskstatisticstaskpanel import CalculateMaskStatisticsTaskPanel
|
|
29
|
+
from mosamatic2.ui.widgets.panels.tasks.applythresholdtosegmentationstaskpanel import ApplyThresholdToSegmentationsTaskPanel
|
|
30
|
+
from mosamatic2.ui.widgets.panels.pipelines.defaultpipelinepanel import DefaultPipelinePanel
|
|
31
|
+
from mosamatic2.ui.widgets.panels.pipelines.defaultdockerpipelinepanel import DefaultDockerPipelinePanel
|
|
32
|
+
from mosamatic2.ui.widgets.panels.pipelines.boadockerpipelinepanel import BoaDockerPipelinePanel
|
|
33
|
+
from mosamatic2.ui.widgets.panels.pipelines.liveranalysispipelinepanel import LiverAnalysisPipelinePanel
|
|
34
|
+
from mosamatic2.ui.widgets.panels.visualizations.slicevisualization.slicevisualization import SliceVisualization
|
|
35
|
+
from mosamatic2.ui.widgets.panels.visualizations.sliceselectionvisualization.sliceselectionvisualization import SliceSelectionVisualization
|
|
36
|
+
from mosamatic2.ui.widgets.panels.visualizations.liversegmentvisualization.liversegmentvisualization import LiverSegmentVisualization
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
LOG = LogManager()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class MainWindow(QMainWindow):
|
|
43
|
+
def __init__(self):
|
|
44
|
+
super(MainWindow, self).__init__()
|
|
45
|
+
self._settings = None
|
|
46
|
+
self._main_panel = None
|
|
47
|
+
self._log_panel = None
|
|
48
|
+
self._decompress_dicom_files_task_panel = None
|
|
49
|
+
self._rescale_dicom_images_task_panel = None
|
|
50
|
+
self._segment_muscle_fat_l3_tensorflow_task_panel = None
|
|
51
|
+
self._segment_muscle_fat_t4_pytorch_task_panel = None
|
|
52
|
+
self._create_pngs_from_segmentations_task_panel = None
|
|
53
|
+
self._calculate_scores_task_panel = None
|
|
54
|
+
self._dicom2nifti_task_panel = None
|
|
55
|
+
self._segmentation_numpy_to_nifti_task_panel = None
|
|
56
|
+
self._segmentation_nifti_to_numpy_task_panel = None
|
|
57
|
+
self._create_dicom_summary_task_panel = None
|
|
58
|
+
self._select_slice_from_scans_task_panel = None
|
|
59
|
+
self._total_segmentator_task_panel = None
|
|
60
|
+
self._calculate_mask_statistics_task_panel = None
|
|
61
|
+
self._apply_threshold_to_segmentations_task_panel = None
|
|
62
|
+
self._default_pipeline_panel = None
|
|
63
|
+
self._default_docker_pipeline_panel = None
|
|
64
|
+
self._boa_docker_pipeline_panel = None
|
|
65
|
+
self._liver_analysis_pipeline_panel = None
|
|
66
|
+
self._slice_visualization = None
|
|
67
|
+
self._slice_selection_visualization = None
|
|
68
|
+
self._liver_segment_visualization = None
|
|
69
|
+
self.init_window()
|
|
70
|
+
|
|
71
|
+
def init_window(self):
|
|
72
|
+
self.setWindowTitle(f'{constants.MOSAMATIC2_WINDOW_TITLE} {version()}')
|
|
73
|
+
icon_file_name = constants.MOSAMATIC2_APP_ICON_FILE_NAME_MAC if is_macos() else constants.MOSAMATIC2_APP_ICON_FILE_NAME_WIN
|
|
74
|
+
icon_path = resource_path(os.path.join(constants.MOSAMATIC2_ICONS_DIR_PATH, icon_file_name))
|
|
75
|
+
self.setWindowIcon(QIcon(icon_path))
|
|
76
|
+
if not self.load_geometry_and_state():
|
|
77
|
+
self.set_default_size_and_position()
|
|
78
|
+
self.init_menus()
|
|
79
|
+
self.init_status_bar()
|
|
80
|
+
self.addDockWidget(Qt.DockWidgetArea.TopDockWidgetArea, self.main_panel())
|
|
81
|
+
self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, self.log_panel())
|
|
82
|
+
|
|
83
|
+
def init_menus(self):
|
|
84
|
+
self.init_app_menu()
|
|
85
|
+
self.init_tasks_menu()
|
|
86
|
+
self.init_pipelines_menu()
|
|
87
|
+
self.init_visualizations_menu()
|
|
88
|
+
if is_macos():
|
|
89
|
+
self.menuBar().setNativeMenuBar(False)
|
|
90
|
+
|
|
91
|
+
def init_app_menu(self):
|
|
92
|
+
exit_action = QAction('Exit', self)
|
|
93
|
+
exit_action.triggered.connect(self.close)
|
|
94
|
+
app_menu = self.menuBar().addMenu('Application')
|
|
95
|
+
app_menu.addAction(exit_action)
|
|
96
|
+
|
|
97
|
+
def init_tasks_menu(self):
|
|
98
|
+
rescale_dicom_images_task_action = QAction('RescaleDicomImagesTask', self)
|
|
99
|
+
rescale_dicom_images_task_action.triggered.connect(self.handle_rescale_dicom_images_task_action)
|
|
100
|
+
segment_muscle_fat_l3_tensorflow_task_action = QAction('SegmentMuscleAndFatL3TensorFlowTask', self)
|
|
101
|
+
segment_muscle_fat_l3_tensorflow_task_action.triggered.connect(self.handle_segment_muscle_fat_l3_tensorflow_task_action)
|
|
102
|
+
segment_muscle_fat_t4_pytorch_task_action = QAction("SegmentMuscleFatT4PytorchTask", self)
|
|
103
|
+
segment_muscle_fat_t4_pytorch_task_action.triggered.connect(self.handle_segment_muscle_fat_t4_pytorch_task_action)
|
|
104
|
+
calculate_scores_task_action = QAction('CalculateScoresTask', self)
|
|
105
|
+
calculate_scores_task_action.triggered.connect(self.handle_calculate_scores_task_action)
|
|
106
|
+
create_pngs_from_segmentations_task_action = QAction('CreatePngsFromSegmentationsTask', self)
|
|
107
|
+
create_pngs_from_segmentations_task_action.triggered.connect(self.handle_create_pngs_from_segmentations_task_action)
|
|
108
|
+
dicom2nifti_task_action = QAction('Dicom2NiftiTask', self)
|
|
109
|
+
dicom2nifti_task_action.triggered.connect(self.handle_dicom2nifti_task_action)
|
|
110
|
+
segmentation_numpy_to_nifti_task_action = QAction('SegmentationNumpy2NiftiTask', self)
|
|
111
|
+
segmentation_numpy_to_nifti_task_action.triggered.connect(self.handle_segmentation_numpy_to_nifti_task_action)
|
|
112
|
+
segmentation_nifti_to_numpy_task_action = QAction('SegmentationNifti2NumpyTask', self)
|
|
113
|
+
segmentation_nifti_to_numpy_task_action.triggered.connect(self.handle_segmentation_nifti_to_numpy_task_action)
|
|
114
|
+
create_dicom_summary_task_action = QAction('CreateDicomSummaryTask', self)
|
|
115
|
+
create_dicom_summary_task_action.triggered.connect(self.handle_create_dicom_summary_task_action)
|
|
116
|
+
select_slice_from_scans_task_action = QAction('SelectSliceFromScansTask', self)
|
|
117
|
+
select_slice_from_scans_task_action.triggered.connect(self.handle_select_slice_from_scans_task_action)
|
|
118
|
+
total_segmentator_task_action = QAction('TotalSegmentatorTask', self)
|
|
119
|
+
total_segmentator_task_action.triggered.connect(self.handle_total_segmentator_task_action)
|
|
120
|
+
calculate_mask_statistics_task_action = QAction('CalculateMaskStatisticsTask', self)
|
|
121
|
+
calculate_mask_statistics_task_action.triggered.connect(self.handle_calculate_mask_statistics_task_action)
|
|
122
|
+
apply_threshold_to_segmentations_task_action = QAction('ApplyThresholdToSegmentationsTask', self)
|
|
123
|
+
apply_threshold_to_segmentations_task_action.triggered.connect(self.handle_apply_threshold_to_segmentations_task_action)
|
|
124
|
+
tasks_menu = self.menuBar().addMenu('Tasks')
|
|
125
|
+
tasks_menu.addAction(rescale_dicom_images_task_action)
|
|
126
|
+
tasks_menu.addAction(segment_muscle_fat_l3_tensorflow_task_action)
|
|
127
|
+
tasks_menu.addAction(segment_muscle_fat_t4_pytorch_task_action)
|
|
128
|
+
tasks_menu.addAction(calculate_scores_task_action)
|
|
129
|
+
tasks_menu.addAction(create_pngs_from_segmentations_task_action)
|
|
130
|
+
tasks_menu.addAction(dicom2nifti_task_action)
|
|
131
|
+
tasks_menu.addAction(segmentation_numpy_to_nifti_task_action)
|
|
132
|
+
tasks_menu.addAction(segmentation_nifti_to_numpy_task_action)
|
|
133
|
+
tasks_menu.addAction(create_dicom_summary_task_action)
|
|
134
|
+
tasks_menu.addAction(select_slice_from_scans_task_action)
|
|
135
|
+
tasks_menu.addAction(total_segmentator_task_action)
|
|
136
|
+
tasks_menu.addAction(calculate_mask_statistics_task_action)
|
|
137
|
+
tasks_menu.addAction(apply_threshold_to_segmentations_task_action)
|
|
138
|
+
|
|
139
|
+
def init_pipelines_menu(self):
|
|
140
|
+
default_pipeline_action = QAction('DefaultPipeline', self)
|
|
141
|
+
default_pipeline_action.triggered.connect(self.handle_default_pipeline_action)
|
|
142
|
+
default_docker_pipeline_action = QAction('DefaultDockerPipeline', self)
|
|
143
|
+
default_docker_pipeline_action.triggered.connect(self.handle_default_docker_pipeline_action)
|
|
144
|
+
boa_docker_pipeline_action = QAction('BoaDockerPipeline', self)
|
|
145
|
+
boa_docker_pipeline_action.triggered.connect(self.handle_boa_docker_pipeline_action)
|
|
146
|
+
liver_analysis_pipeline_action = QAction('LiverAnalysisPipeline', self)
|
|
147
|
+
liver_analysis_pipeline_action.triggered.connect(self.handle_liver_analysis_pipeline_action)
|
|
148
|
+
pipelines_menu = self.menuBar().addMenu('Pipelines')
|
|
149
|
+
pipelines_menu.addAction(default_pipeline_action)
|
|
150
|
+
pipelines_menu.addAction(default_docker_pipeline_action)
|
|
151
|
+
pipelines_menu.addAction(boa_docker_pipeline_action)
|
|
152
|
+
pipelines_menu.addAction(liver_analysis_pipeline_action)
|
|
153
|
+
|
|
154
|
+
def init_visualizations_menu(self):
|
|
155
|
+
slice_visualization_action = QAction('SliceVisualization', self)
|
|
156
|
+
slice_visualization_action.triggered.connect(self.handle_slice_visualization_action)
|
|
157
|
+
slice_selection_visualization_action = QAction('SliceSelectionVisualization', self)
|
|
158
|
+
slice_selection_visualization_action.triggered.connect(self.handle_slice_selection_visualization_action)
|
|
159
|
+
liver_segment_visualization_action = QAction('LiverSegmentVisualization', self)
|
|
160
|
+
liver_segment_visualization_action.triggered.connect(self.handle_liver_segment_visualization_action)
|
|
161
|
+
visualizations_menu = self.menuBar().addMenu('Visualizations')
|
|
162
|
+
visualizations_menu.addAction(slice_visualization_action)
|
|
163
|
+
visualizations_menu.addAction(slice_selection_visualization_action)
|
|
164
|
+
visualizations_menu.addAction(liver_segment_visualization_action)
|
|
165
|
+
|
|
166
|
+
def init_status_bar(self):
|
|
167
|
+
self.set_status('Ready')
|
|
168
|
+
|
|
169
|
+
# GET
|
|
170
|
+
|
|
171
|
+
def settings(self):
|
|
172
|
+
if not self._settings:
|
|
173
|
+
self._settings = Settings()
|
|
174
|
+
return self._settings
|
|
175
|
+
|
|
176
|
+
def main_panel(self):
|
|
177
|
+
if not self._main_panel:
|
|
178
|
+
self._main_panel = MainPanel(self)
|
|
179
|
+
self._main_panel.add_panel(self.rescale_dicom_images_task_panel(), 'rescaledicomimagestaskpanel')
|
|
180
|
+
self._main_panel.add_panel(self.segment_muscle_fat_l3_tensorflow_task_panel(), 'segmentmusclefatl3tensorflowtaskpanel')
|
|
181
|
+
self._main_panel.add_panel(self.segment_muscle_fat_t4_pytorch_task_panel(), 'segmentmusclefatt4pytorchtaskpanel')
|
|
182
|
+
self._main_panel.add_panel(self.create_pngs_from_segmentations_task_panel(), 'createpngsfromsegmentationstaskpanel')
|
|
183
|
+
self._main_panel.add_panel(self.calculate_scores_task_panel(), 'calculatescorestaskpanel')
|
|
184
|
+
self._main_panel.add_panel(self.dicom2nifti_task_panel(), 'dicom2niftitaskpanel')
|
|
185
|
+
self._main_panel.add_panel(self.segmentation_numpy_to_nifti_task_panel(), 'segmentationnumpy2niftitaskpanel')
|
|
186
|
+
self._main_panel.add_panel(self.segmentation_nifti_to_numpy_task_panel(), 'segmentationnifti2numpytaskpanel')
|
|
187
|
+
self._main_panel.add_panel(self.create_dicom_summary_task_panel(), 'createdicomsummarytaskpanel')
|
|
188
|
+
self._main_panel.add_panel(self.select_slice_from_scans_task_panel(), 'selectslicefromscanstaskpanel')
|
|
189
|
+
self._main_panel.add_panel(self.total_segmentator_task_panel(), 'totalsegmentatortaskpanel')
|
|
190
|
+
self._main_panel.add_panel(self.calculate_mask_statistics_task_panel(), 'calculatemaskstatisticstaskpanel')
|
|
191
|
+
self._main_panel.add_panel(self.apply_threshold_to_segmentations_task_panel(), 'applythresholdtosegmentationstaskpanel')
|
|
192
|
+
self._main_panel.add_panel(self.default_pipeline_panel(), 'defaultpipelinepanel')
|
|
193
|
+
self._main_panel.add_panel(self.default_docker_pipeline_panel(), 'defaultdockerpipelinepanel')
|
|
194
|
+
self._main_panel.add_panel(self.boa_docker_pipeline_panel(), 'boadockerpipelinepanel')
|
|
195
|
+
self._main_panel.add_panel(self.liver_analysis_pipeline_panel(), 'liveranalysispipelinepanel')
|
|
196
|
+
self._main_panel.add_panel(self.slice_visualization(), 'slicevisualization')
|
|
197
|
+
self._main_panel.add_panel(self.slice_selection_visualization(), 'sliceselectionvisualization')
|
|
198
|
+
self._main_panel.add_panel(self.liver_segment_visualization(), 'liversegmentvisualization')
|
|
199
|
+
self._main_panel.select_panel('defaultpipelinepanel')
|
|
200
|
+
return self._main_panel
|
|
201
|
+
|
|
202
|
+
def log_panel(self):
|
|
203
|
+
if not self._log_panel:
|
|
204
|
+
self._log_panel = LogPanel()
|
|
205
|
+
LOG.add_listener(self._log_panel)
|
|
206
|
+
return self._log_panel
|
|
207
|
+
|
|
208
|
+
# MISCELLANEOUS
|
|
209
|
+
|
|
210
|
+
def rescale_dicom_images_task_panel(self):
|
|
211
|
+
if not self._rescale_dicom_images_task_panel:
|
|
212
|
+
self._rescale_dicom_images_task_panel = RescaleDicomImagesTaskPanel()
|
|
213
|
+
return self._rescale_dicom_images_task_panel
|
|
214
|
+
|
|
215
|
+
def segment_muscle_fat_l3_tensorflow_task_panel(self):
|
|
216
|
+
if not self._segment_muscle_fat_l3_tensorflow_task_panel:
|
|
217
|
+
self._segment_muscle_fat_l3_tensorflow_task_panel = SegmentMuscleFatL3TensorFlowTaskPanel()
|
|
218
|
+
return self._segment_muscle_fat_l3_tensorflow_task_panel
|
|
219
|
+
|
|
220
|
+
def segment_muscle_fat_t4_pytorch_task_panel(self):
|
|
221
|
+
if not self._segment_muscle_fat_t4_pytorch_task_panel:
|
|
222
|
+
self._segment_muscle_fat_t4_pytorch_task_panel = SegmentMuscleFatT4PyTorchTaskPanel()
|
|
223
|
+
return self._segment_muscle_fat_t4_pytorch_task_panel
|
|
224
|
+
|
|
225
|
+
def create_pngs_from_segmentations_task_panel(self):
|
|
226
|
+
if not self._create_pngs_from_segmentations_task_panel:
|
|
227
|
+
self._create_pngs_from_segmentations_task_panel = CreatePngsFromSegmentationsTaskPanel()
|
|
228
|
+
return self._create_pngs_from_segmentations_task_panel
|
|
229
|
+
|
|
230
|
+
def calculate_scores_task_panel(self):
|
|
231
|
+
if not self._calculate_scores_task_panel:
|
|
232
|
+
self._calculate_scores_task_panel = CalculateScoresTaskPanel()
|
|
233
|
+
return self._calculate_scores_task_panel
|
|
234
|
+
|
|
235
|
+
def dicom2nifti_task_panel(self):
|
|
236
|
+
if not self._dicom2nifti_task_panel:
|
|
237
|
+
self._dicom2nifti_task_panel = Dicom2NiftiTaskPanel()
|
|
238
|
+
return self._dicom2nifti_task_panel
|
|
239
|
+
|
|
240
|
+
def segmentation_numpy_to_nifti_task_panel(self):
|
|
241
|
+
if not self._segmentation_numpy_to_nifti_task_panel:
|
|
242
|
+
self._segmentation_numpy_to_nifti_task_panel = SegmentationNumpy2NiftiTaskPanel()
|
|
243
|
+
return self._segmentation_numpy_to_nifti_task_panel
|
|
244
|
+
|
|
245
|
+
def segmentation_nifti_to_numpy_task_panel(self):
|
|
246
|
+
if not self._segmentation_nifti_to_numpy_task_panel:
|
|
247
|
+
self._segmentation_nifti_to_numpy_task_panel = SegmentationNifti2NumpyTaskPanel()
|
|
248
|
+
return self._segmentation_nifti_to_numpy_task_panel
|
|
249
|
+
|
|
250
|
+
def create_dicom_summary_task_panel(self):
|
|
251
|
+
if not self._create_dicom_summary_task_panel:
|
|
252
|
+
self._create_dicom_summary_task_panel = CreateDicomSummaryTaskPanel()
|
|
253
|
+
return self._create_dicom_summary_task_panel
|
|
254
|
+
|
|
255
|
+
def select_slice_from_scans_task_panel(self):
|
|
256
|
+
if not self._select_slice_from_scans_task_panel:
|
|
257
|
+
self._select_slice_from_scans_task_panel = SelectSliceFromScansTaskPanel()
|
|
258
|
+
return self._select_slice_from_scans_task_panel
|
|
259
|
+
|
|
260
|
+
def total_segmentator_task_panel(self):
|
|
261
|
+
if not self._total_segmentator_task_panel:
|
|
262
|
+
self._total_segmentator_task_panel = TotalSegmentatorTaskPanel()
|
|
263
|
+
return self._total_segmentator_task_panel
|
|
264
|
+
|
|
265
|
+
def calculate_mask_statistics_task_panel(self):
|
|
266
|
+
if not self._calculate_mask_statistics_task_panel:
|
|
267
|
+
self._calculate_mask_statistics_task_panel = CalculateMaskStatisticsTaskPanel()
|
|
268
|
+
return self._calculate_mask_statistics_task_panel
|
|
269
|
+
|
|
270
|
+
def apply_threshold_to_segmentations_task_panel(self):
|
|
271
|
+
if not self._apply_threshold_to_segmentations_task_panel:
|
|
272
|
+
self._apply_threshold_to_segmentations_task_panel = ApplyThresholdToSegmentationsTaskPanel()
|
|
273
|
+
return self._apply_threshold_to_segmentations_task_panel
|
|
274
|
+
|
|
275
|
+
def default_pipeline_panel(self):
|
|
276
|
+
if not self._default_pipeline_panel:
|
|
277
|
+
self._default_pipeline_panel = DefaultPipelinePanel()
|
|
278
|
+
return self._default_pipeline_panel
|
|
279
|
+
|
|
280
|
+
def default_docker_pipeline_panel(self):
|
|
281
|
+
if not self._default_docker_pipeline_panel:
|
|
282
|
+
self._default_docker_pipeline_panel = DefaultDockerPipelinePanel()
|
|
283
|
+
return self._default_docker_pipeline_panel
|
|
284
|
+
|
|
285
|
+
def boa_docker_pipeline_panel(self):
|
|
286
|
+
if not self._boa_docker_pipeline_panel:
|
|
287
|
+
self._boa_docker_pipeline_panel = BoaDockerPipelinePanel()
|
|
288
|
+
return self._boa_docker_pipeline_panel
|
|
289
|
+
|
|
290
|
+
def liver_analysis_pipeline_panel(self):
|
|
291
|
+
if not self._liver_analysis_pipeline_panel:
|
|
292
|
+
self._liver_analysis_pipeline_panel = LiverAnalysisPipelinePanel()
|
|
293
|
+
return self._liver_analysis_pipeline_panel
|
|
294
|
+
|
|
295
|
+
def slice_visualization(self):
|
|
296
|
+
if not self._slice_visualization:
|
|
297
|
+
self._slice_visualization = SliceVisualization()
|
|
298
|
+
return self._slice_visualization
|
|
299
|
+
|
|
300
|
+
def slice_selection_visualization(self):
|
|
301
|
+
if not self._slice_selection_visualization:
|
|
302
|
+
self._slice_selection_visualization = SliceSelectionVisualization()
|
|
303
|
+
return self._slice_selection_visualization
|
|
304
|
+
|
|
305
|
+
def liver_segment_visualization(self):
|
|
306
|
+
if not self._liver_segment_visualization:
|
|
307
|
+
self._liver_segment_visualization = LiverSegmentVisualization()
|
|
308
|
+
return self._liver_segment_visualization
|
|
309
|
+
|
|
310
|
+
# SETTERS
|
|
311
|
+
|
|
312
|
+
def set_status(self, message):
|
|
313
|
+
self.statusBar().showMessage(message)
|
|
314
|
+
|
|
315
|
+
# EVENT HANDLERS
|
|
316
|
+
|
|
317
|
+
def handle_rescale_dicom_images_task_action(self):
|
|
318
|
+
self.main_panel().select_panel('rescaledicomimagestaskpanel')
|
|
319
|
+
|
|
320
|
+
def handle_segment_muscle_fat_l3_tensorflow_task_action(self):
|
|
321
|
+
self.main_panel().select_panel('segmentmusclefatl3tensorflowtaskpanel')
|
|
322
|
+
|
|
323
|
+
def handle_segment_muscle_fat_t4_pytorch_task_action(self):
|
|
324
|
+
self.main_panel().select_panel('segmentmusclefatt4pytorchtaskpanel')
|
|
325
|
+
|
|
326
|
+
def handle_create_pngs_from_segmentations_task_action(self):
|
|
327
|
+
self.main_panel().select_panel('createpngsfromsegmentationstaskpanel')
|
|
328
|
+
|
|
329
|
+
def handle_calculate_scores_task_action(self):
|
|
330
|
+
self.main_panel().select_panel('calculatescorestaskpanel')
|
|
331
|
+
|
|
332
|
+
def handle_dicom2nifti_task_action(self):
|
|
333
|
+
self.main_panel().select_panel('dicom2niftitaskpanel')
|
|
334
|
+
|
|
335
|
+
def handle_segmentation_numpy_to_nifti_task_action(self):
|
|
336
|
+
self.main_panel().select_panel('segmentationnumpy2niftitaskpanel')
|
|
337
|
+
|
|
338
|
+
def handle_segmentation_nifti_to_numpy_task_action(self):
|
|
339
|
+
self.main_panel().select_panel('segmentationnifti2numpytaskpanel')
|
|
340
|
+
|
|
341
|
+
def handle_create_dicom_summary_task_action(self):
|
|
342
|
+
self.main_panel().select_panel('createdicomsummarytaskpanel')
|
|
343
|
+
|
|
344
|
+
def handle_select_slice_from_scans_task_action(self):
|
|
345
|
+
self.main_panel().select_panel('selectslicefromscanstaskpanel')
|
|
346
|
+
|
|
347
|
+
def handle_total_segmentator_task_action(self):
|
|
348
|
+
self.main_panel().select_panel('totalsegmentatortaskpanel')
|
|
349
|
+
|
|
350
|
+
def handle_calculate_mask_statistics_task_action(self):
|
|
351
|
+
self.main_panel().select_panel('calculatemaskstatisticstaskpanel')
|
|
352
|
+
|
|
353
|
+
def handle_apply_threshold_to_segmentations_task_action(self):
|
|
354
|
+
self.main_panel().select_panel('applythresholdtosegmentationstaskpanel')
|
|
355
|
+
|
|
356
|
+
def handle_default_pipeline_action(self):
|
|
357
|
+
self.main_panel().select_panel('defaultpipelinepanel')
|
|
358
|
+
|
|
359
|
+
def handle_default_docker_pipeline_action(self):
|
|
360
|
+
self.main_panel().select_panel('defaultdockerpipelinepanel')
|
|
361
|
+
|
|
362
|
+
def handle_boa_docker_pipeline_action(self):
|
|
363
|
+
self.main_panel().select_panel('boadockerpipelinepanel')
|
|
364
|
+
|
|
365
|
+
def handle_liver_analysis_pipeline_action(self):
|
|
366
|
+
self.main_panel().select_panel('liveranalysispipelinepanel')
|
|
367
|
+
|
|
368
|
+
def handle_slice_visualization_action(self):
|
|
369
|
+
self.main_panel().select_panel('slicevisualization')
|
|
370
|
+
|
|
371
|
+
def handle_slice_selection_visualization_action(self):
|
|
372
|
+
self.main_panel().select_panel('sliceselectionvisualization')
|
|
373
|
+
|
|
374
|
+
def handle_liver_segment_visualization_action(self):
|
|
375
|
+
self.main_panel().select_panel('liversegmentvisualization')
|
|
376
|
+
|
|
377
|
+
def showEvent(self, event):
|
|
378
|
+
return super().showEvent(event)
|
|
379
|
+
|
|
380
|
+
def closeEvent(self, event):
|
|
381
|
+
self.save_geometry_and_state()
|
|
382
|
+
# Save inputs and parameters of relevant panels
|
|
383
|
+
self.rescale_dicom_images_task_panel().save_inputs_and_parameters()
|
|
384
|
+
self.segment_muscle_fat_l3_tensorflow_task_panel().save_inputs_and_parameters()
|
|
385
|
+
self.segment_muscle_fat_t4_pytorch_task_panel().save_inputs_and_parameters()
|
|
386
|
+
self.create_pngs_from_segmentations_task_panel().save_inputs_and_parameters()
|
|
387
|
+
self.calculate_scores_task_panel().save_inputs_and_parameters()
|
|
388
|
+
self.dicom2nifti_task_panel().save_inputs_and_parameters()
|
|
389
|
+
self.segmentation_numpy_to_nifti_task_panel().save_inputs_and_parameters()
|
|
390
|
+
self.segmentation_nifti_to_numpy_task_panel().save_inputs_and_parameters()
|
|
391
|
+
self.create_dicom_summary_task_panel().save_inputs_and_parameters()
|
|
392
|
+
self.select_slice_from_scans_task_panel().save_inputs_and_parameters()
|
|
393
|
+
self.total_segmentator_task_panel().save_inputs_and_parameters()
|
|
394
|
+
self.calculate_mask_statistics_task_panel().save_inputs_and_parameters()
|
|
395
|
+
self.apply_threshold_to_segmentations_task_panel().save_inputs_and_parameters()
|
|
396
|
+
self.default_pipeline_panel().save_inputs_and_parameters()
|
|
397
|
+
self.default_docker_pipeline_panel().save_inputs_and_parameters()
|
|
398
|
+
self.boa_docker_pipeline_panel().save_inputs_and_parameters()
|
|
399
|
+
self.liver_analysis_pipeline_panel().save_inputs_and_parameters()
|
|
400
|
+
self.slice_visualization().save_inputs_and_parameters()
|
|
401
|
+
self.slice_selection_visualization().save_inputs_and_parameters()
|
|
402
|
+
self.liver_segment_visualization().save_inputs_and_parameters()
|
|
403
|
+
return super().closeEvent(event)
|
|
404
|
+
|
|
405
|
+
def load_geometry_and_state(self):
|
|
406
|
+
geometry = self.settings().get(constants.MOSAMATIC2_WINDOW_GEOMETRY_KEY)
|
|
407
|
+
state = self.settings().get(constants.MOSAMATIC2_WINDOW_STATE_KEY)
|
|
408
|
+
if isinstance(geometry, QByteArray) and self.restoreGeometry(geometry):
|
|
409
|
+
if isinstance(state, QByteArray):
|
|
410
|
+
self.restoreState(state)
|
|
411
|
+
return True
|
|
412
|
+
return False
|
|
413
|
+
|
|
414
|
+
def save_geometry_and_state(self):
|
|
415
|
+
self.settings().set(constants.MOSAMATIC2_WINDOW_GEOMETRY_KEY, self.saveGeometry())
|
|
416
|
+
self.settings().set(constants.MOSAMATIC2_WINDOW_STATE_KEY, self.saveState())
|
|
417
|
+
|
|
418
|
+
def set_default_size_and_position(self):
|
|
419
|
+
self.resize(constants.MOSAMATIC2_WINDOW_W, constants.MOSAMATIC2_WINDOW_H)
|
|
420
|
+
self.center_window()
|
|
421
|
+
|
|
422
|
+
def center_window(self):
|
|
423
|
+
screen = QGuiApplication.primaryScreen().geometry()
|
|
424
|
+
x = (screen.width() - self.geometry().width()) / 2
|
|
425
|
+
y = (screen.height() - self.geometry().height()) / 2
|
|
426
|
+
self.move(int(x), int(y))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.0.24
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import mosamatic2.constants as constants
|
|
2
|
+
from PySide6.QtCore import QSettings
|
|
3
|
+
from mosamatic2.core.managers.logmanager import LogManager
|
|
4
|
+
|
|
5
|
+
LOG = LogManager()
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Settings(QSettings):
|
|
9
|
+
def __init__(self):
|
|
10
|
+
super(Settings, self).__init__(
|
|
11
|
+
QSettings.IniFormat,
|
|
12
|
+
QSettings.UserScope,
|
|
13
|
+
constants.MOSAMATIC2_BUNDLE_IDENTIFIER,
|
|
14
|
+
constants.MOSAMATIC2_APP_NAME,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
def prepend_bundle_identifier_and_name(self, name):
|
|
18
|
+
return '{}.{}.{}'.format(constants.MOSAMATIC2_BUNDLE_IDENTIFIER, constants.MOSAMATIC2_APP_NAME, name)
|
|
19
|
+
|
|
20
|
+
def get(self, name, default=None):
|
|
21
|
+
if not name.startswith(constants.MOSAMATIC2_BUNDLE_IDENTIFIER):
|
|
22
|
+
name = self.prepend_bundle_identifier_and_name(name)
|
|
23
|
+
value = self.value(name)
|
|
24
|
+
if value is None or value == '':
|
|
25
|
+
return default
|
|
26
|
+
return value
|
|
27
|
+
|
|
28
|
+
def get_int(self, name, default=None):
|
|
29
|
+
try:
|
|
30
|
+
return int(self.get(name, default))
|
|
31
|
+
except ValueError as e:
|
|
32
|
+
return default
|
|
33
|
+
|
|
34
|
+
def get_float(self, name, default=None):
|
|
35
|
+
try:
|
|
36
|
+
return float(self.get(name, default))
|
|
37
|
+
except ValueError as e:
|
|
38
|
+
return default
|
|
39
|
+
|
|
40
|
+
def get_bool(self, name, default=None):
|
|
41
|
+
try:
|
|
42
|
+
value = self.get(name, default)
|
|
43
|
+
if value and isinstance(value, str):
|
|
44
|
+
if value == '0' or value.lower() == 'false':
|
|
45
|
+
return False
|
|
46
|
+
elif value == '1' or value.lower() == 'true':
|
|
47
|
+
return True
|
|
48
|
+
else:
|
|
49
|
+
return default
|
|
50
|
+
if value and isinstance(value, bool):
|
|
51
|
+
return value
|
|
52
|
+
except ValueError as e:
|
|
53
|
+
return default
|
|
54
|
+
|
|
55
|
+
def set(self, name, value):
|
|
56
|
+
name = self.prepend_bundle_identifier_and_name(name)
|
|
57
|
+
self.setValue(name, value)
|
|
58
|
+
|
|
59
|
+
def print(self):
|
|
60
|
+
LOG.info(f'Settings path: {self.fileName()}')
|
|
61
|
+
for key in self.allKeys():
|
|
62
|
+
LOG.info(f'Settings: {key}')
|
mosamatic2/ui/utils.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import mosamatic2.constants as constants
|
|
4
|
+
from PySide6.QtGui import (
|
|
5
|
+
QPixmap,
|
|
6
|
+
QPainter,
|
|
7
|
+
QColor
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def resource_path(relative_path):
|
|
12
|
+
base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
|
13
|
+
return os.path.join(base_path, relative_path)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def version():
|
|
17
|
+
with open(resource_path(constants.MOSAMATIC2_VERSION_FILE), 'r') as f:
|
|
18
|
+
return f.readline().strip()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def is_macos():
|
|
22
|
+
return sys.platform.startswith('darwin')
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def icon(parent, icon_type):
|
|
26
|
+
return parent.style().standardIcon(icon_type)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def set_opacity(pixmap, opacity):
|
|
30
|
+
result = QPixmap(pixmap.size())
|
|
31
|
+
result.fill(QColor(0, 0, 0, 0))
|
|
32
|
+
painter = QPainter(result)
|
|
33
|
+
painter.setOpacity(opacity)
|
|
34
|
+
painter.drawPixmap(0, 0, pixmap)
|
|
35
|
+
painter.end()
|
|
36
|
+
return result
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from PySide6.QtWidgets import (
|
|
2
|
+
QDialog,
|
|
3
|
+
)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Dialog(QDialog):
|
|
7
|
+
def __init__(self, parent=None):
|
|
8
|
+
super(Dialog, self).__init__(parent)
|
|
9
|
+
self.setFixedWidth(400)
|
|
10
|
+
|
|
11
|
+
def clear(self):
|
|
12
|
+
raise NotImplementedError()
|
|
13
|
+
|
|
14
|
+
def showEvent(self, arg__1):
|
|
15
|
+
self.clear()
|
|
16
|
+
return super().showEvent(arg__1)
|
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from PySide6.QtWidgets import QWidget, QPushButton
|
|
2
|
+
|
|
3
|
+
from mosamatic2.ui.widgets.dialogs.helpdialog import HelpDialog
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DefaultPanel(QWidget):
|
|
7
|
+
def __init__(self):
|
|
8
|
+
super(DefaultPanel, self).__init__()
|
|
9
|
+
self._title = None
|
|
10
|
+
self._help_dialog = None
|
|
11
|
+
self._show_help_button = None
|
|
12
|
+
|
|
13
|
+
def title(self):
|
|
14
|
+
return self._title
|
|
15
|
+
|
|
16
|
+
def set_title(self, title):
|
|
17
|
+
self._title = title
|
|
18
|
+
|
|
19
|
+
def help_dialog(self):
|
|
20
|
+
if not self._help_dialog:
|
|
21
|
+
self._help_dialog = HelpDialog()
|
|
22
|
+
return self._help_dialog
|
|
23
|
+
|
|
24
|
+
def show_help_button(self):
|
|
25
|
+
if not self._show_help_button:
|
|
26
|
+
self._show_help_button = QPushButton('Help')
|
|
27
|
+
self._show_help_button.clicked.connect(self.handle_show_help_button)
|
|
28
|
+
return self._show_help_button
|
|
29
|
+
|
|
30
|
+
def handle_show_help_button(self):
|
|
31
|
+
self.help_dialog().show()
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from PySide6.QtWidgets import (
|
|
2
|
+
QWidget,
|
|
3
|
+
QDockWidget,
|
|
4
|
+
QTextEdit,
|
|
5
|
+
QPushButton,
|
|
6
|
+
QVBoxLayout,
|
|
7
|
+
QLabel,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
from mosamatic2.core.managers.logmanagerlistener import LogManagerListener
|
|
11
|
+
|
|
12
|
+
PANEL_TITLE = 'Output log'
|
|
13
|
+
PANEL_NAME = 'logpanel'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class LogPanel(QDockWidget, LogManagerListener):
|
|
17
|
+
def __init__(self):
|
|
18
|
+
super(LogPanel, self).__init__()
|
|
19
|
+
self._title_label = None
|
|
20
|
+
self._text_edit = None
|
|
21
|
+
self.init_layout()
|
|
22
|
+
|
|
23
|
+
def title_label(self):
|
|
24
|
+
if not self._title_label:
|
|
25
|
+
self._title_label = QLabel(PANEL_TITLE)
|
|
26
|
+
return self._title_label
|
|
27
|
+
|
|
28
|
+
def text_edit(self):
|
|
29
|
+
if not self._text_edit:
|
|
30
|
+
self._text_edit = QTextEdit()
|
|
31
|
+
return self._text_edit
|
|
32
|
+
|
|
33
|
+
def init_layout(self):
|
|
34
|
+
clear_logs_button = QPushButton('Clear log')
|
|
35
|
+
clear_logs_button.clicked.connect(self.handle_clear_logs_button)
|
|
36
|
+
layout = QVBoxLayout()
|
|
37
|
+
# layout.addWidget(self.title_label())
|
|
38
|
+
layout.addWidget(self.text_edit())
|
|
39
|
+
layout.addWidget(clear_logs_button)
|
|
40
|
+
container = QWidget()
|
|
41
|
+
container.setLayout(layout)
|
|
42
|
+
self.setObjectName(PANEL_NAME)
|
|
43
|
+
self.setWindowTitle(self.title_label().text())
|
|
44
|
+
self.setWidget(container)
|
|
45
|
+
|
|
46
|
+
# HELPERS
|
|
47
|
+
|
|
48
|
+
def add_line(self, line):
|
|
49
|
+
self.text_edit().insertPlainText(line + '\n')
|
|
50
|
+
self.move_to_end()
|
|
51
|
+
|
|
52
|
+
def move_to_end(self):
|
|
53
|
+
cursor = self.text_edit().textCursor()
|
|
54
|
+
cursor.movePosition(cursor.MoveOperation.End)
|
|
55
|
+
self.text_edit().setTextCursor(cursor)
|
|
56
|
+
self.text_edit().ensureCursorVisible()
|
|
57
|
+
|
|
58
|
+
# EVENTS
|
|
59
|
+
|
|
60
|
+
def handle_clear_logs_button(self):
|
|
61
|
+
self.text_edit().clear()
|
|
62
|
+
|
|
63
|
+
# implements(LogManagerListener)
|
|
64
|
+
def new_message(self, message):
|
|
65
|
+
self.add_line(message)
|