Skip to content

Commit

Permalink
Merge branch 'helmholtz_design' of https://github.com/HelmholtzAI-Con…
Browse files Browse the repository at this point in the history
  • Loading branch information
Christina Bukas committed Mar 21, 2024
2 parents 052c481 + 37e5aa5 commit 93a436d
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 45 deletions.
56 changes: 14 additions & 42 deletions src/client/dcp_client/gui/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,9 @@
import os
from typing import TYPE_CHECKING

from PyQt5.QtWidgets import (
QPushButton,
QVBoxLayout,
QFileSystemModel,
QHBoxLayout,
QLabel,
QTreeView,
QProgressBar,
QShortcut,
QApplication,
QStyledItemDelegate,
)
from PyQt5.QtCore import (
Qt,
QModelIndex,
QThread,
pyqtSignal,
QRect,
QSize,
QVariant,
QDir,
)
from PyQt5.QtGui import (
QKeySequence,
QIcon,
QPixmap,
QPainter,
QImage,
QBrush,
QPen,
QFont,
)

# from PySide2.QtCore import QModelIndex

from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QFileSystemModel, QHBoxLayout, QLabel, QTreeView, QProgressBar, QShortcut, QApplication, QStyledItemDelegate
from PyQt5.QtCore import Qt, QModelIndex, QThread, pyqtSignal, QRect, QSize, QVariant, QDir
from PyQt5.QtGui import QKeySequence, QPixmap, QPainter, QImage, QBrush, QPen, QFont

from dcp_client.utils import settings
from dcp_client.utils.utils import IconProvider, CustomItemDelegate
Expand Down Expand Up @@ -564,16 +532,20 @@ def on_run_inference_button_clicked(self) -> None:
# start the worker thread to run inference
self.worker_thread.start()

def on_launch_napari_button_clicked(self) -> None:
"""
def on_launch_napari_button_clicked(self):
'''
Launches the napari window after the image is selected.
"""
if not self.app.cur_selected_img or "_seg.tiff" in self.app.cur_selected_img:
message_text = "Please first select an image you wish to visualise. The selected image must be an original image, not a mask."
'''
if not self.app.cur_selected_img or '_seg.tiff' in self.app.cur_selected_img:
message_text = "Please first select an image you wish to visualize. The selected image must be an original image, not a mask."
_ = self.create_warning_box(message_text, message_title="Warning")
else:
self.nap_win = NapariWindow(self.app)
self.nap_win.show()
try:
self.nap_win = NapariWindow(self.app)
self.nap_win.show()
except Exception as e:
message_text = f"An error occurred while opening the Napari window: {str(e)}"
_ = self.create_warning_box(message_text, message_title="Error")

def on_finished(self, result: tuple) -> None:
"""
Expand Down
31 changes: 31 additions & 0 deletions src/client/dcp_client/gui/napari_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,37 @@ def __init__(self, app: Application) -> None:

self.setLayout(layout)

remove_from_dataset_button = QPushButton('Remove from dataset')
remove_from_dataset_button.setStyleSheet(
"""QPushButton
{
background-color: #0064A8;
font-size: 12px;
font-weight: bold;
color: #D1D2D4;
border-radius: 5px;
padding: 8px 16px; }"""
"QPushButton:hover { background-color: #006FBA; }"
"QPushButton:pressed { background-color: #006FBA; }"

)
layout.addWidget(remove_from_dataset_button, 3, 0, 1, 4)
remove_from_dataset_button.clicked.connect(self.on_remove_from_dataset_button_clicked)

def on_remove_from_dataset_button_clicked(self) -> None:
"""
Defines what happens when the "Remove from dataset" button is clicked.
"""
seg_name_to_remove = self.viewer.layers.selection.active.name
if seg_name_to_remove:
# Delete the image and corresponding masks from the dataset
image_name = self.app.cur_selected_img
seg_files_to_remove = [seg_name_to_remove + '.tiff']
self.app.delete_images([image_name] + seg_files_to_remove)

self.viewer.close()
self.close()

def set_editable_mask(self) -> None:
"""
This function is not implemented. In theory the use can choose between which mask to edit.
Expand Down
46 changes: 43 additions & 3 deletions src/client/dcp_client/gui/welcome_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,55 @@ def __init__(self, app: Application) -> None:
self.path_layout.addWidget(self.train_textbox)
'''
self.file_open_button_val = QPushButton("Browse", self)
self.file_open_button_val.setFixedSize(80, 30)
self.file_open_button_val.setStyleSheet(
"""QPushButton
{
background-color: #3d81d1;
font-size: 11px;
font-weight: bold;
color: #ffffff;
border-radius: 5px;
padding: 8px 16px; }"""
"QPushButton:hover { background-color: #006FBA; }"
)
self.file_open_button_val.show()
self.file_open_button_val.clicked.connect(self.browse_eval_clicked)
self.file_open_button_prog = QPushButton("Browse", self)
self.file_open_button_prog.setFixedSize(80, 30)
self.file_open_button_prog.setStyleSheet(
"""QPushButton
{
background-color: #3d81d1;
font-size: 11px;
font-weight: bold;
color: #ffffff;
border-radius: 5px;
padding: 8px 16px; }"""
"QPushButton:hover { background-color: #006FBA; }"
)
self.file_open_button_prog.show()
self.file_open_button_prog.clicked.connect(self.browse_inprogr_clicked)
self.file_open_button_train = QPushButton("Browse", self)
self.file_open_button_train.setFixedSize(80, 30)
self.file_open_button_train.setStyleSheet(
"""QPushButton
{
background-color: #3d81d1;
font-size: 11px;
font-weight: bold;
color: #ffffff;
border-radius: 5px;
padding: 8px 16px; }"""
"QPushButton:hover { background-color: #006FBA; }"
)
self.file_open_button_train.show()
self.file_open_button_train.clicked.connect(self.browse_train_clicked)
self.button_layout.addWidget(self.file_open_button_val)
self.button_layout.addWidget(self.file_open_button_prog)
self.button_layout.addWidget(self.file_open_button_train)
Expand All @@ -143,7 +184,7 @@ def __init__(self, app: Application) -> None:
border-radius: 5px;
padding: 8px 16px; }"""
"QPushButton:hover { background-color: #7bc432; }"
"QPushButton:pressed { background-color: #7bc432; }"

)
self.start_button.show()
# check if we need to upload data to server
Expand Down Expand Up @@ -215,8 +256,7 @@ def eventFilter(self, obj, event):


def browse_inprogr_clicked(self):
""""
Activates when the user clicks the button to choose the curation in progress directory (QFileDialog) and
""" Activates when the user clicks the button to choose the curation in progress directory (QFileDialog) and
displays the name of the evaluation directory chosen in the validation textbox line (QLineEdit).
"""

Expand Down
13 changes: 13 additions & 0 deletions src/client/test/test_main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from dcp_client.utils.sync_src_dst import DataRSync
from dcp_client.utils import settings

from unittest.mock import MagicMock

@pytest.fixture()
def setup_global_variable():
Expand Down Expand Up @@ -141,6 +142,18 @@ def test_on_finished(qtbot, app):
assert app.inference_button.isEnabled()
assert app.worker_thread is None

def test_launch_napari_button_clicked_with_selected_img(qtbot, app):

with pytest.raises(Exception) as exc_info:
index = app.list_view_eval.indexAt(app.list_view_eval.viewport().rect().topLeft())
app.on_item_eval_selected(index)

window = MainWindow(app)
window.nap_win = MagicMock(side_effect=Exception("Test exception"))

window.on_launch_napari_button_clicked()

assert "An error occurred while opening the Napari window" in str(exc_info.value)

def test_launch_napari_button_click_without_selection(qtbot, app):
# Try clicking the view button without having selected an image
Expand Down

0 comments on commit 93a436d

Please sign in to comment.