class Form(QDialog):

    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.title = "Emoji Splitter"
        self.setWindowTitle(self.title)

        # preview_split widget
        self.preview_widget = QLabel()
        # media_preview = QPixmap('C:/Users/roela/PycharmProjects/Emojisplitter/bolkvis.png')
        # media_preview = QMovie('Naamloos.gif')  # QPixmap('Naamloos.gif')
        self.media_preview('Naamloos.gif')

        # embed preview_split in a scrollable window
        self.preview_scroll_area = QScrollArea()
        self.preview_scroll_area.setWidget(self.preview_widget)
        self.preview_scroll_area.setBackgroundRole(QPalette.Dark)
        self.preview_scroll_area.setWidgetResizable(True)

        # Create button widgets
        self.open_file_button = QPushButton("Select &File")
        self.filename = QLineEdit("C:/Users/roela/PycharmProjects/Emojisplitter/Naamloos.gif")
        self.preview_button = QPushButton("&Preview Split")
        self.fit_to_window_checkbox = QCheckBox("Fit Preview Image to &Window")
        self.horizontal_emojis_spinbox = QSpinBox()
        self.horizontal_emojis_spinbox.setMinimum(1)
        self.horizontal_emojis_label = QLabel("Number of &horizontal emojis:")
        self.horizontal_emojis_label.setBuddy(self.horizontal_emojis_spinbox)
        self.vertical_emojis_spinbox = QSpinBox()
        self.vertical_emojis_spinbox.setMinimum(1)
        self.vertical_emojis_label = QLabel("Number of &vertical emojis:")
        self.vertical_emojis_label.setBuddy(self.vertical_emojis_spinbox)
        self.split_emojis_button = QPushButton("&Split Emoji")
        self.results_folder_button = QPushButton("Open folder with &results")

        # give the button_layout a fixed width
        button_container = QWidget()
        button_container.setFixedWidth(256)

        # Create layout and add widgets
        button_layout = QVBoxLayout(button_container)
        button_layout.addWidget(self.open_file_button)
        button_layout.addWidget(self.filename)

        # Put labels next to spinboxes
        horizontal_emojis_layout = QHBoxLayout()
        horizontal_emojis_layout.addWidget(self.horizontal_emojis_label)
        horizontal_emojis_layout.addWidget(self.horizontal_emojis_spinbox)

        vertical_emojis_layout = QHBoxLayout()
        vertical_emojis_layout.addWidget(self.vertical_emojis_label)
        vertical_emojis_layout.addWidget(self.vertical_emojis_spinbox)

        button_layout.addLayout(horizontal_emojis_layout)
        button_layout.addLayout(vertical_emojis_layout)

        button_layout.addWidget(self.preview_button)
        button_layout.addWidget(self.fit_to_window_checkbox)
        button_layout.addWidget(self.split_emojis_button)
        button_layout.addWidget(self.results_folder_button)

        preview_layout = QVBoxLayout()
        # preview_layout.addWidget(self.preview_widget)
        preview_layout.addWidget(self.preview_scroll_area)

        # combine button and preview_split layout
        nested_layout = QHBoxLayout()
        nested_layout.addWidget(button_container)
        nested_layout.addLayout(preview_layout)
        # Set dialog layout
        self.setLayout(nested_layout)

        # Add button functions
        self.open_file_button.clicked.connect(self.open_file)
        self.preview_button.clicked.connect(self.preview_split)
        self.fit_to_window_checkbox.clicked.connect(self.fit_to_window)
        self.split_emojis_button.clicked.connect(self.split)
        self.results_folder_button.clicked.connect(self.open_folder_with_results)

        # update preview_split on changing value of a spinbox
        self.horizontal_emojis_spinbox.valueChanged.connect(self.preview_split)
        self.vertical_emojis_spinbox.valueChanged.connect(self.preview_split)

    # Preview the image.
    def preview_split(self):
        preview_image = emojisplitter.emojisplitter(self.filename.text(),
                                                    self.horizontal_emojis_spinbox.value(),
                                                    self.vertical_emojis_spinbox.value(),
                                                    False)
        self.preview_widget.setPixmap(preview_image)
        if self.fit_to_window_checkbox.checkState():
            self.fit_to_window()

    # Fit the image to the current window
    def fit_to_window(self):
        self.preview_widget.setPixmap(
            self.preview_widget.pixmap().scaled(self.preview_scroll_area.width(),
                                                self.preview_scroll_area.height(),
                                                aspectMode=Qt.KeepAspectRatio))

    # open file
    def open_file(self):
        self.filename.setText(QFileDialog.getOpenFileName(self, "Open Image")[0])
        self.media_preview(self.filename.text())

    def media_preview(self, filename):
        media_preview = QMovie(filename)
        self.preview_widget.setMovie(media_preview)
        self.preview_widget.movie().start()
        self.preview_widget.resize(media_preview.currentPixmap().width(), media_preview.currentPixmap().height())
        # self.preview_split()  # This immediately show where the split would be

    def split(self):
        emojisplitter.emojisplitter(self.filename.text(),
                                    self.horizontal_emojis_spinbox.value(),
                                    self.vertical_emojis_spinbox.value(),
                                    True)

    def open_folder_with_results(self):
        path = Path(self.filename.text()).parent
        webbrowser.open('file:///' + str(path))
Example #2
0
class UIDeleteROIWindow():
    def setup_ui(self, delete_roi_window_instance, regions_of_interest,
                 dataset_rtss, deleting_rois_structure_tuple):
        # Initialise the 2 lists for containing the ROI(s) that we are going to keep and delete respectively
        self.regions_of_interest_to_keep = []
        self.regions_of_interest_to_delete = []
        # This is for holding the original list of ROI(s)
        self.regions_of_interest_list = regions_of_interest
        # This is for holding the DICOM dataset of that specific patient
        self.dataset_rtss = dataset_rtss
        # Assigning new tuple for holding the deleting ROI(s)
        self.deleting_rois_structure_tuple = deleting_rois_structure_tuple

        # Initialise a DeleteROIWindow
        if platform.system() == 'Darwin':
            self.stylesheet_path = "res/stylesheet.qss"
        else:
            self.stylesheet_path = "res/stylesheet-win-linux.qss"
        stylesheet = open(resource_path(self.stylesheet_path)).read()
        window_icon = QIcon()
        window_icon.addPixmap(QPixmap(resource_path("res/images/icon.ico")),
                              QIcon.Normal, QIcon.Off)
        delete_roi_window_instance.setObjectName("DeleteRoiWindowInstance")
        delete_roi_window_instance.setWindowIcon(window_icon)
        delete_roi_window_instance.resize(800, 606)

        # Create a vertical box to hold all widgets
        self.delete_roi_window_instance_vertical_box = QVBoxLayout()
        self.delete_roi_window_instance_vertical_box.setObjectName(
            "DeleteRoiWindowInstanceVerticalBox")

        # Create a label for holding the window's title
        self.delete_roi_window_title = QLabel()
        self.delete_roi_window_title.setObjectName("DeleteRoiWindowTitle")
        self.delete_roi_window_title.setProperty("QLabelClass", "window-title")
        self.delete_roi_window_title.setAlignment(Qt.AlignLeft)
        self.delete_roi_window_instance_vertical_box.addWidget(
            self.delete_roi_window_title)

        # Create a label for holding the instruction of how to delete the ROIs
        self.delete_roi_window_instruction = QLabel()
        self.delete_roi_window_instruction.setObjectName(
            "DeleteRoiWindowInstruction")
        self.delete_roi_window_instruction.setAlignment(Qt.AlignCenter)
        self.delete_roi_window_instance_vertical_box.addWidget(
            self.delete_roi_window_instruction)

        # Create a horizontal box for holding the 2 lists and the move left, move right buttons
        self.delete_roi_window_keep_and_delete_box = QHBoxLayout()
        self.delete_roi_window_keep_and_delete_box.setObjectName(
            "DeleteRoiWindowKeepAndDeleteBox")
        # ================================= KEEP BOX =================================
        # Create a vertical box for holding the label and the tree view for holding the ROIs that we are keeping
        self.delete_roi_window_keep_vertical_box = QVBoxLayout()
        self.delete_roi_window_keep_vertical_box.setObjectName(
            "DeleteRoiWindowKeepVerticalBox")
        # Create a label for the tree view with the list of ROIs to keep
        self.delete_roi_window_keep_tree_view_label = QLabel()
        self.delete_roi_window_keep_tree_view_label.setObjectName(
            "DeleteRoiWindowKeepTreeViewLabel")
        self.delete_roi_window_keep_tree_view_label.setProperty(
            "QLabelClass", ["tree-view-label", "tree-view-label-keep-delete"])
        self.delete_roi_window_keep_tree_view_label.setAlignment(
            Qt.AlignCenter)
        self.delete_roi_window_keep_tree_view_label.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding,
                        QSizePolicy.MinimumExpanding))
        self.delete_roi_window_keep_tree_view_label.resize(
            self.delete_roi_window_keep_tree_view_label.sizeHint().width(),
            self.delete_roi_window_keep_tree_view_label.sizeHint().height())
        self.delete_roi_window_keep_vertical_box.addWidget(
            self.delete_roi_window_keep_tree_view_label)
        # Create a tree view for containing the list of ROIs to keep
        self.delete_roi_window_keep_tree_view = QTreeWidget()
        self.delete_roi_window_keep_tree_view.setObjectName(
            "DeleteRoiWindowKeepTreeView")
        self.delete_roi_window_keep_tree_view.setHeaderHidden(True)
        self.delete_roi_window_keep_tree_view.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding,
                        QSizePolicy.MinimumExpanding))
        self.delete_roi_window_keep_tree_view.resize(
            self.delete_roi_window_keep_tree_view.sizeHint().width(),
            self.delete_roi_window_keep_tree_view.sizeHint().height())
        self.delete_roi_window_keep_vertical_box.addWidget(
            self.delete_roi_window_keep_tree_view)
        self.delete_roi_window_keep_vertical_box.setStretch(1, 4)
        # Create a widget to hold the keep vertical box
        self.delete_roi_window_keep_widget = QWidget()
        self.delete_roi_window_keep_widget.setObjectName(
            "DeleteRoiWindowKeepWidget")
        self.delete_roi_window_keep_widget.setLayout(
            self.delete_roi_window_keep_vertical_box)
        self.delete_roi_window_keep_and_delete_box.addStretch(1)
        self.delete_roi_window_keep_and_delete_box.addWidget(
            self.delete_roi_window_keep_widget)
        # ================================= KEEP BOX =================================

        # ================================= MOVE LEFT/RIGHT BOX =================================
        # Create a vertical box for holding the 2 buttons for moving left and right
        self.delete_roi_window_move_left_right_vertical_box = QVBoxLayout()
        self.delete_roi_window_move_left_right_vertical_box.setObjectName(
            "DeleteRoiWindowMoveLeftRightVerticalBox")
        # Create Move Right Button / Delete Button
        self.move_right_button = QPushButton()
        self.move_right_button.setObjectName("MoveRightButton")
        self.move_right_button.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding,
                        QSizePolicy.MinimumExpanding))
        self.move_right_button.resize(
            self.move_right_button.sizeHint().width(),
            self.move_right_button.sizeHint().height())
        self.move_right_button.setCursor(
            QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.move_right_button.clicked.connect(
            self.move_right_button_onClicked)
        self.move_right_button.setProperty("QPushButtonClass", "fail-button")
        self.delete_roi_window_move_left_right_vertical_box.addStretch(1)
        self.delete_roi_window_move_left_right_vertical_box.addWidget(
            self.move_right_button)
        # Create Move Left Button / Keep Button
        self.move_left_button = QPushButton()
        self.move_left_button.setObjectName("MoveLeftButton")
        self.move_left_button.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding,
                        QSizePolicy.MinimumExpanding))
        self.move_left_button.resize(self.move_left_button.sizeHint().width(),
                                     self.move_left_button.sizeHint().height())
        self.move_left_button.setCursor(
            QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.move_left_button.clicked.connect(self.move_left_button_onClicked)
        self.move_left_button.setProperty("QPushButtonClass", "success-button")
        self.delete_roi_window_move_left_right_vertical_box.addWidget(
            self.move_left_button)
        self.delete_roi_window_move_left_right_vertical_box.addStretch(1)
        # Create a widget for holding the 2 buttons
        self.delete_roi_window_move_left_right_widget = QWidget()
        self.delete_roi_window_move_left_right_widget.setObjectName(
            "DeleteRoiWindowMoveLeftRightWidget")
        self.delete_roi_window_move_left_right_widget.setLayout(
            self.delete_roi_window_move_left_right_vertical_box)
        self.delete_roi_window_keep_and_delete_box.addWidget(
            self.delete_roi_window_move_left_right_widget)
        # ================================= MOVE LEFT/RIGHT BOX =================================

        # ================================= DELETE BOX =================================
        # Create a vertical box for holding the label and the tree view for holding the ROIs that we are deleting
        self.delete_roi_window_delete_vertical_box = QVBoxLayout()
        self.delete_roi_window_delete_vertical_box.setObjectName(
            "DeleteRoiWindowDeleteVerticalBox")
        # Create a label for the tree view with the list of ROIs to delete
        self.delete_roi_window_delete_tree_view_label = QLabel()
        self.delete_roi_window_delete_tree_view_label.setObjectName(
            "DeleteRoiWindowDeleteTreeViewLabel")
        self.delete_roi_window_delete_tree_view_label.setProperty(
            "QLabelClass", ["tree-view-label", "tree-view-label-keep-delete"])
        self.delete_roi_window_delete_tree_view_label.setAlignment(
            Qt.AlignCenter)
        self.delete_roi_window_delete_tree_view_label.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding,
                        QSizePolicy.MinimumExpanding))
        self.delete_roi_window_delete_tree_view_label.resize(
            self.delete_roi_window_delete_tree_view_label.sizeHint().width(),
            self.delete_roi_window_delete_tree_view_label.sizeHint().height())
        self.delete_roi_window_delete_vertical_box.addWidget(
            self.delete_roi_window_delete_tree_view_label)
        # Create a tree view for containing the list of ROIs to delete
        self.delete_roi_window_delete_tree_view = QTreeWidget()
        self.delete_roi_window_delete_tree_view.setObjectName(
            "DeleteRoiWindowDeleteTreeView")
        self.delete_roi_window_delete_tree_view.setHeaderHidden(True)
        self.delete_roi_window_delete_tree_view.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding,
                        QSizePolicy.MinimumExpanding))
        self.delete_roi_window_delete_tree_view.resize(
            self.delete_roi_window_delete_tree_view.sizeHint().width(),
            self.delete_roi_window_delete_tree_view.sizeHint().height())
        self.delete_roi_window_delete_vertical_box.addWidget(
            self.delete_roi_window_delete_tree_view)
        self.delete_roi_window_delete_vertical_box.setStretch(1, 4)
        # Create a widget to hold the delete vertical box
        self.delete_roi_window_delete_widget = QWidget()
        self.delete_roi_window_delete_widget.setObjectName(
            "DeleteRoiWindowDeleteWidget")
        self.delete_roi_window_delete_widget.setLayout(
            self.delete_roi_window_delete_vertical_box)
        self.delete_roi_window_keep_and_delete_box.addWidget(
            self.delete_roi_window_delete_widget)
        self.delete_roi_window_keep_and_delete_box.addStretch(1)
        self.delete_roi_window_keep_and_delete_box.setStretch(1, 4)
        self.delete_roi_window_keep_and_delete_box.setStretch(3, 4)
        # ================================= DELETE BOX =================================
        # Create a widget to hold the keep and delete box
        self.delete_roi_window_keep_and_delete_widget = QWidget()
        self.delete_roi_window_keep_and_delete_widget.setObjectName(
            "DeleteRoiWindowKeepAndDeleteWidget")
        self.delete_roi_window_keep_and_delete_widget.setLayout(
            self.delete_roi_window_keep_and_delete_box)
        self.delete_roi_window_instance_vertical_box.addWidget(
            self.delete_roi_window_keep_and_delete_widget)

        # Create a horizontal box to hold 2 action buttons for this window
        self.delete_roi_window_action_buttons_box = QHBoxLayout()
        self.delete_roi_window_action_buttons_box.setObjectName(
            "DeleteRoiWindowActionButtonsBox")
        # Create the cancel button
        self.delete_roi_window_cancel_button = QPushButton()
        self.delete_roi_window_cancel_button.setObjectName(
            "DeleteRoiWindowCancelButton")
        self.delete_roi_window_cancel_button.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding,
                        QSizePolicy.MinimumExpanding))
        self.delete_roi_window_cancel_button.resize(
            self.delete_roi_window_cancel_button.sizeHint().width(),
            self.delete_roi_window_cancel_button.sizeHint().height())
        self.delete_roi_window_cancel_button.setCursor(
            QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.delete_roi_window_cancel_button.clicked.connect(
            self.on_cancel_button_clicked)
        self.delete_roi_window_cancel_button.setProperty(
            "QPushButtonClass", "fail-button")
        self.delete_roi_window_action_buttons_box.addStretch(1)
        self.delete_roi_window_action_buttons_box.addWidget(
            self.delete_roi_window_cancel_button)
        # Create the confirm button
        self.delete_roi_window_confirm_button = QPushButton()
        self.delete_roi_window_confirm_button.setObjectName(
            "DeleteRoiWindowConfirmButton")
        self.delete_roi_window_confirm_button.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding,
                        QSizePolicy.MinimumExpanding))
        self.delete_roi_window_confirm_button.resize(
            self.delete_roi_window_confirm_button.sizeHint().width(),
            self.delete_roi_window_confirm_button.sizeHint().height())
        self.delete_roi_window_confirm_button.setCursor(
            QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.delete_roi_window_confirm_button.clicked.connect(
            self.confirm_button_onClicked)
        self.delete_roi_window_confirm_button.setEnabled(False)
        self.delete_roi_window_confirm_button.setProperty(
            "QPushButtonClass", "success-button")
        self.delete_roi_window_action_buttons_box.addWidget(
            self.delete_roi_window_confirm_button)
        # Create a widget to hold the action buttons
        self.delete_roi_window_action_buttons_widget = QWidget()
        self.delete_roi_window_action_buttons_widget.setObjectName(
            "DeleteRoiWindowActionButtonsWidget")
        self.delete_roi_window_action_buttons_widget.setLayout(
            self.delete_roi_window_action_buttons_box)
        self.delete_roi_window_instance_vertical_box.addWidget(
            self.delete_roi_window_action_buttons_widget)

        # Set text for all attributes
        self.retranslate_ui(delete_roi_window_instance)
        # Create a central widget to hold the vertical layout box
        self.delete_roi_window_instance_central_widget = QWidget()
        self.delete_roi_window_instance_central_widget.setObjectName(
            "DeleteRoiWindowInstanceCentralWidget")
        self.delete_roi_window_instance_central_widget.setLayout(
            self.delete_roi_window_instance_vertical_box)
        self.delete_roi_window_instance_vertical_box.setStretch(2, 4)
        # Set the central widget for the main window and style the window
        delete_roi_window_instance.setCentralWidget(
            self.delete_roi_window_instance_central_widget)
        delete_roi_window_instance.setStyleSheet(stylesheet)

        # Load the ROIs in
        self.display_rois_in_listViewKeep()
        # Set the selection mode to multi so that we can select multiple ROIs to delete
        self.delete_roi_window_keep_tree_view.setSelectionMode(
            QAbstractItemView.MultiSelection)
        self.delete_roi_window_delete_tree_view.setSelectionMode(
            QAbstractItemView.MultiSelection)

        QtCore.QMetaObject.connectSlotsByName(delete_roi_window_instance)

    def retranslate_ui(self, delete_roi_window_instance):
        _translate = QtCore.QCoreApplication.translate
        delete_roi_window_instance.setWindowTitle(
            _translate("DeleteRoiWindowInstance", "OnkoDICOM - Delete ROI(s)"))
        self.delete_roi_window_title.setText(
            _translate("DeleteRoiWindowTitle", "Delete ROI(s)"))
        self.delete_roi_window_instruction.setText(
            _translate(
                "DeleteRoiWindowInstruction",
                "Move the Regions of Interest to be deleted to the right-hand side or vice versa"
            ))
        self.delete_roi_window_keep_tree_view_label.setText(
            _translate("DeleteRoiWindowKeepTreeViewLabel", "To Keep"))
        self.delete_roi_window_delete_tree_view_label.setText(
            _translate("DeleteRoiWindowDeleteTreeViewLabel", "To Delete"))
        self.move_right_button.setText(
            _translate("MoveRightButton", "Move Right ->>>"))
        self.move_left_button.setText(
            _translate("MoveLeftButton", "<<<- Move Left"))
        self.delete_roi_window_cancel_button.setText(
            _translate("DeleteRoiWindowCancelButton", "Cancel"))
        self.delete_roi_window_confirm_button.setText(
            _translate("DeleteRoiWindowConfirmButton", "Confirm"))

    def on_cancel_button_clicked(self):
        self.close()

    def display_rois_in_listViewKeep(self):
        self.regions_of_interest_to_keep.clear()
        for roi_id, roi_dict in self.regions_of_interest_list.items():
            self.regions_of_interest_to_keep.append(roi_dict['name'])

        self.delete_roi_window_keep_tree_view.clear()
        self.delete_roi_window_keep_tree_view.setIndentation(0)

        self.item = QTreeWidgetItem(["item"])
        for index in self.regions_of_interest_to_keep:
            item = QTreeWidgetItem([index])
            self.delete_roi_window_keep_tree_view.addTopLevelItem(item)

    def move_right_button_onClicked(self):
        root_item = self.delete_roi_window_keep_tree_view.invisibleRootItem()
        for index in range(root_item.childCount()):
            item = root_item.child(index)
            if item in self.delete_roi_window_keep_tree_view.selectedItems():
                # This will get ROI name
                self.regions_of_interest_to_delete.append(item.text(0))

        # Move to the right column list
        self.delete_roi_window_delete_tree_view.clear()
        self.delete_roi_window_delete_tree_view.setIndentation(0)
        for roi in self.regions_of_interest_to_delete:
            item = QTreeWidgetItem([roi])
            self.delete_roi_window_delete_tree_view.addTopLevelItem(item)
            self.delete_roi_window_confirm_button.setEnabled(True)

        # Delete moved items from the left column list
        self.regions_of_interest_to_keep = [
            x for x in self.regions_of_interest_to_keep
            if x not in self.regions_of_interest_to_delete
        ]

        self.delete_roi_window_keep_tree_view.clear()
        for index in self.regions_of_interest_to_keep:
            item = QTreeWidgetItem([index])
            self.delete_roi_window_keep_tree_view.addTopLevelItem(item)

    def move_left_button_onClicked(self):
        root_item = self.delete_roi_window_delete_tree_view.invisibleRootItem()

        for index in range(root_item.childCount()):
            item = root_item.child(index)
            if item in self.delete_roi_window_delete_tree_view.selectedItems():
                # This will get ROI name
                self.regions_of_interest_to_keep.append(item.text(0))

        # Move to the left column list
        self.delete_roi_window_keep_tree_view.clear()
        self.delete_roi_window_keep_tree_view.setIndentation(0)
        for roi in self.regions_of_interest_to_keep:
            item = QTreeWidgetItem([roi])
            self.delete_roi_window_keep_tree_view.addTopLevelItem(item)

        # Delete moved items from the right column list
        self.regions_of_interest_to_delete = [
            x for x in self.regions_of_interest_to_delete
            if x not in self.regions_of_interest_to_keep
        ]

        self.delete_roi_window_delete_tree_view.clear()
        for index in self.regions_of_interest_to_delete:
            item = QTreeWidgetItem([index])
            self.delete_roi_window_delete_tree_view.addTopLevelItem(item)

        if len(self.regions_of_interest_to_delete) == 0:
            self.delete_roi_window_confirm_button.setEnabled(False)

    def confirm_button_onClicked(self):
        confirmation_dialog = QMessageBox.information(
            self, 'Delete ROI(s)?',
            'Region(s) of Interest in the To Delete table will be deleted. '
            'Would you like to continue?', QMessageBox.Yes | QMessageBox.No)
        if confirmation_dialog == QMessageBox.Yes:
            progress_window = DeleteROIProgressWindow(
                self, QtCore.Qt.WindowTitleHint)
            progress_window.signal_roi_deleted.connect(self.on_rois_deleted)
            progress_window.start_deleting(self.dataset_rtss,
                                           self.regions_of_interest_to_delete)
            progress_window.show()

    def on_rois_deleted(self, new_rtss):
        self.deleting_rois_structure_tuple.emit((new_rtss, {
            "delete":
            self.regions_of_interest_to_delete
        }))
        QMessageBox.about(self, "Saved",
                          "Regions of interest successfully deleted!")
        self.close()
Example #3
0
class PatientBar(QtWidgets.QWidget):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.setObjectName("PatientBar")
        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        patient_dict_container = PatientDictContainer()
        self.basic_info = patient_dict_container.get("basic_info")

        # Init layout
        self.patient_bar_layout = QHBoxLayout()
        self.patient_bar_layout.setObjectName("PatientBarLayout")
        self.patient_bar_layout.setSpacing(0)

        # Create patient icon
        self.patient_bar_icon = QLabel()
        self.patient_bar_icon.setObjectName("PatientBarIcon")
        self.patient_bar_icon.setText("")
        self.patient_bar_icon.setPixmap(
            QtGui.QPixmap(resource_path("res/images/btn-icons/patient.png")))

        # Create patient name
        self.patient_bar_name_info = QLabel()
        self.patient_bar_name_info.setObjectName("PatientBarNameInfo")
        self.patient_bar_name_info.setText(self.basic_info['name'])
        self.patient_bar_name_info.setSizePolicy(QSizePolicy.MinimumExpanding,
                                                 QSizePolicy.MinimumExpanding)
        self.patient_bar_name_info.resize(
            self.patient_bar_name_info.sizeHint().width(),
            self.patient_bar_name_info.sizeHint().height())
        self.patient_bar_name_info.setProperty("PatientBarClass", "value")
        self.patient_bar_name_info_label = QLabel()
        self.patient_bar_name_info_label.setObjectName(
            "PatientBarNameInfoLabel")
        self.patient_bar_name_info_label.setText("Name:")
        self.patient_bar_name_info_label.setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)
        self.patient_bar_name_info_label.resize(
            self.patient_bar_name_info_label.sizeHint().width(),
            self.patient_bar_name_info_label.sizeHint().height())
        self.patient_bar_name_info_label.setProperty("PatientBarClass",
                                                     "label")

        # # Create patient ID
        self.patient_bar_id_info = QLabel()
        self.patient_bar_id_info.setObjectName("PatientBarIdInfo")
        self.patient_bar_id_info.setText(self.basic_info['id'])
        self.patient_bar_id_info.setSizePolicy(QSizePolicy.MinimumExpanding,
                                               QSizePolicy.MinimumExpanding)
        self.patient_bar_id_info.resize(
            self.patient_bar_id_info.sizeHint().width(),
            self.patient_bar_id_info.sizeHint().height())
        self.patient_bar_id_info.setProperty("PatientBarClass", "value")
        self.patient_bar_id_info_label = QLabel()
        self.patient_bar_id_info_label.setObjectName("PatientBarIdInfoLabel")
        self.patient_bar_id_info_label.setText("ID:")
        self.patient_bar_id_info_label.setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)
        self.patient_bar_id_info_label.resize(
            self.patient_bar_id_info_label.sizeHint().width(),
            self.patient_bar_id_info_label.sizeHint().height())
        self.patient_bar_id_info_label.setProperty("PatientBarClass", "label")

        # # Create patient gender
        self.patient_bar_gender_info = QLabel()
        self.patient_bar_gender_info.setObjectName("PatientBarGenderInfo")
        self.patient_bar_gender_info.setText(self.basic_info['gender'])
        self.patient_bar_gender_info.setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
        self.patient_bar_gender_info.resize(
            self.patient_bar_gender_info.sizeHint().width(),
            self.patient_bar_gender_info.sizeHint().height())
        self.patient_bar_gender_info.setProperty("PatientBarClass", "value")
        self.patient_bar_gender_info_label = QLabel()
        self.patient_bar_gender_info_label.setObjectName(
            "PatientBarGenderInfoLabel")
        self.patient_bar_gender_info_label.setText("Gender:")
        self.patient_bar_gender_info_label.setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)
        self.patient_bar_gender_info_label.resize(
            self.patient_bar_gender_info_label.sizeHint().width(),
            self.patient_bar_gender_info_label.sizeHint().height())
        self.patient_bar_gender_info_label.setProperty("PatientBarClass",
                                                       "label")

        # # Create patient DOB
        self.patient_bar_dob_info = QLabel()
        self.patient_bar_dob_info.setObjectName("PatientBarDobInfo")
        self.patient_bar_dob_info.setText(self.basic_info['dob'])
        self.patient_bar_dob_info.setSizePolicy(QSizePolicy.MinimumExpanding,
                                                QSizePolicy.MinimumExpanding)
        self.patient_bar_dob_info.resize(
            self.patient_bar_dob_info.sizeHint().width(),
            self.patient_bar_dob_info.sizeHint().height())
        self.patient_bar_dob_info.setProperty("PatientBarClass", "value")
        self.patient_bar_dob_info_label = QLabel()
        self.patient_bar_dob_info_label.setObjectName("PatientBarDobInfoLabel")
        self.patient_bar_dob_info_label.setText("DoB:")
        self.patient_bar_dob_info_label.setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)
        self.patient_bar_dob_info_label.resize(
            self.patient_bar_dob_info_label.sizeHint().width(),
            self.patient_bar_dob_info_label.sizeHint().height())
        self.patient_bar_dob_info_label.setProperty("PatientBarClass", "label")
        # # Set layout
        self.patient_bar_layout.addWidget(self.patient_bar_icon)
        self.patient_bar_layout.addWidget(self.patient_bar_name_info_label)
        self.patient_bar_layout.addWidget(self.patient_bar_name_info)
        self.patient_bar_layout.addWidget(self.patient_bar_id_info_label)
        self.patient_bar_layout.addWidget(self.patient_bar_id_info)
        self.patient_bar_layout.addWidget(self.patient_bar_gender_info_label)
        self.patient_bar_layout.addWidget(self.patient_bar_gender_info)
        self.patient_bar_layout.addWidget(self.patient_bar_dob_info_label)
        self.patient_bar_layout.addWidget(self.patient_bar_dob_info)
        self.setLayout(self.patient_bar_layout)
        self.resize(self.sizeHint().width(), self.sizeHint().height())
Example #4
0
class Window(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.images = []
        self.index = -1
        self.ratio = 1  # ratio for QLabel image
        self.mouse_position = None
        self.settings = None

        # Extensions
        self.extensions = []
        for format in QImageReader.supportedImageFormats():
            self.extensions.append(format.data().decode('utf-8'))

        # Filters
        self.filters = []
        for extension in self.extensions:
            self.filters.append('*.{0}'.format(str(extension)))

        # UI
        self.set_up_ui()

        # settings
        self.load_settings()

    def on_message_received(self, msg):
        """ on message received from single application

        Args:
            msg (string): file path
        """
        self.create_images(msg)
        self.display_image()

    def set_up_ui(self):
        # Status Bar
        self.status_bar = self.statusBar()
        self.label_name = QLabel()
        self.label_numero = QLabel()
        self.status_bar.addPermanentWidget(self.label_name, 1)
        self.status_bar.addPermanentWidget(self.label_numero, 0)

        # Main Window
        self.setWindowTitle('BaloViewer')
        self.setWindowIcon(QIcon('baloviewer.ico'))

        # Label image
        self.image = QLabel()
        self.image.setScaledContents(True)

        # Scroll area
        self.scroll_area = QScrollArea()
        self.scroll_area.setWidget(self.image)
        self.scroll_area.showMaximized()
        self.scroll_area.setFocusPolicy(Qt.FocusPolicy.NoFocus)
        self.scroll_area.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.scroll_area.viewport().installEventFilter(self)

        # image list
        self.image_gallery = ImageGallery()
        self.image_gallery.itemClicked.connect(self.image_gallery_clicked)
        self.image_gallery.viewport().installEventFilter(self)
        self.dock_widget = QDockWidget('Image Gallery', self)
        self.dock_widget.setWidget(self.image_gallery)
        self.dock_widget.setFloating(False)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dock_widget)

        # central widget
        self.setCentralWidget(self.scroll_area)

        # Action bar
        self.create_actions()
        self.create_menubar()
        self.create_toolbar()

        # option parser
        parser = OptionParser()
        parser.add_option("-f", "--file", dest="filename", help="open a file")
        (options, args) = parser.parse_args()
        parser_file = options.filename
        if parser_file is not None and os.path.isfile(parser_file):
            self.create_images(parser_file)
            self.display_image()

    def create_actions(self):
        # Action Open
        self.action_open = QAction(QIcon.fromTheme('document-open'), 'Open',
                                   self)
        self.action_open.setShortcut('Ctrl+O')
        self.action_open.setStatusTip('Open file')
        self.action_open.triggered.connect(self.open)

        # Action Save
        self.action_save = QAction(QIcon.fromTheme('document-save'), 'Save',
                                   self)
        self.action_save.setShortcut('Ctrl+S')
        self.action_save.setStatusTip('Save file')
        self.action_save.triggered.connect(self.save)

        # Action Copy
        self.action_copy = QAction(QIcon.fromTheme('edit-copy'), 'Copy', self)
        self.action_copy.setStatusTip('Copy')
        self.action_copy.triggered.connect(self.copy)

        # Action move
        self.action_move = QAction(QIcon.fromTheme('edit-cut'), 'Move', self)
        self.action_move.setStatusTip('Move')
        self.action_move.triggered.connect(self.move)

        # Action Delete
        self.action_delete = QAction(QIcon.fromTheme('edit-delete'), 'Delete',
                                     self)
        self.action_delete.setStatusTip('Delete')
        self.action_delete.triggered.connect(self.delete)

        # Action Quit
        self.action_quit = QAction(QIcon.fromTheme('application-exit'), 'Quit',
                                   self)
        self.action_quit.setShortcut('Ctrl+Q')
        self.action_quit.setStatusTip('Quit')
        self.action_quit.triggered.connect(self.close)

        # Action Rotate left
        self.action_rotate_left = QAction(
            QIcon.fromTheme('object-rotate-left'), 'Rotate left', self)
        self.action_rotate_left.setStatusTip('Rotate left')
        self.action_rotate_left.triggered.connect(self.rotate_left)

        # Action Rotate right
        self.action_rotate_right = QAction(
            QIcon.fromTheme('object-rotate-right'), 'Rotate right', self)
        self.action_rotate_right.setStatusTip('Rotate right')
        self.action_rotate_right.triggered.connect(self.rotate_right)

        # Action Mirror
        self.action_flip_horizontal = QAction(
            QIcon.fromTheme('object-flip-horizontal'), 'Flip horizontally',
            self)
        self.action_flip_horizontal.setStatusTip('Flip horizontally')
        self.action_flip_horizontal.triggered.connect(self.flip_horizontal)

        # Action Flip vertical
        self.action_flip_vertical = QAction(
            QIcon.fromTheme('object-flip-vertical'), 'Flip vertically', self)
        self.action_flip_vertical.setStatusTip('Flip vertically')
        self.action_flip_vertical.triggered.connect(self.flip_vertical)

        # Action Previous image
        self.action_previous_image = QAction(QIcon.fromTheme('go-previous'),
                                             'Previous image', self)
        self.action_previous_image.setStatusTip('Previous image')
        self.action_previous_image.triggered.connect(self.previous_image)

        # Action Full screen
        self.action_fullscreen = QAction(QIcon.fromTheme('view-fullscreen'),
                                         'Full screen', self)
        self.action_fullscreen.setStatusTip('Full screen')
        self.action_fullscreen.triggered.connect(self.fullscreen)

        # Action Normal size
        self.action_normal_size = QAction(QIcon.fromTheme('zoom-original'),
                                          'Normal size', self)
        self.action_normal_size.setStatusTip('Normal Size')
        self.action_normal_size.triggered.connect(self.normal_size)

        # Action Fit Screen
        self.action_fit_screen = QAction(QIcon.fromTheme('zoom-fit-best'),
                                         'Fit to screen', self)
        self.action_fit_screen.setStatusTip('Fit to screen')
        self.action_fit_screen.setCheckable(True)
        self.action_fit_screen.triggered.connect(self.fit_screen)

        # Action Zoom in
        self.action_zoom_in = QAction(QIcon.fromTheme('zoom-in'), 'Zoom in',
                                      self)
        self.action_zoom_in.setStatusTip('Zoom in')
        self.action_zoom_in.triggered.connect(self.zoom_in)

        # Action Zoom out
        self.action_zoom_out = QAction(QIcon.fromTheme('zoom-out'), 'Zoom out',
                                       self)
        self.action_zoom_out.setStatusTip('Zoom out')
        self.action_zoom_out.triggered.connect(self.zoom_out)

        # Action Fit height
        self.action_fit_vertical = QAction('Fit vertically', self)
        self.action_fit_vertical.setStatusTip('Fit vertically')
        self.action_fit_vertical.setCheckable(True)
        self.action_fit_vertical.triggered.connect(self.fit_height)

        # Action Fit width
        self.action_fit_horizontal = QAction('Fit horizontally', self)
        self.action_fit_horizontal.setStatusTip('Fit horizontally')
        self.action_fit_horizontal.setCheckable(True)
        self.action_fit_horizontal.triggered.connect(self.fit_width)

        # Action Fit width
        self.action_fit_horizontal = QAction('Fit horizontally', self)
        self.action_fit_horizontal.setStatusTip('Fit horizontally')
        self.action_fit_horizontal.setCheckable(True)
        self.action_fit_horizontal.triggered.connect(self.fit_width)

        # Action Image list
        self.action_image_gallery = QAction('Image gallery', self)
        self.action_image_gallery.setStatusTip('Image gallery')
        self.action_image_gallery.setCheckable(True)
        self.action_image_gallery.triggered.connect(
            self.image_gallery_triggered)

        # Action Next_image
        self.action_next_image = QAction(QIcon.fromTheme('go-next'),
                                         'Next image', self)
        self.action_next_image.setStatusTip('Next image')
        self.action_next_image.triggered.connect(self.next_image)

        # Action First image
        self.action_first_image = QAction(QIcon.fromTheme('go-first'),
                                          'First image', self)
        self.action_first_image.setStatusTip('First image')
        self.action_first_image.triggered.connect(self.first_image)

        # Action Last image
        self.action_last_image = QAction(QIcon.fromTheme('go-last'),
                                         'Last image', self)
        self.action_last_image.setStatusTip('Last image')
        self.action_last_image.triggered.connect(self.last_image)

        # Action About
        self.action_about = QAction(QIcon.fromTheme('help-about'), 'About',
                                    self)
        self.action_about.setStatusTip('About')
        self.action_about.triggered.connect(self.about)

    def create_menubar(self):
        self.menubar = self.menuBar()

        # File
        self.menu_file = self.menubar.addMenu('File')
        self.menu_file.addAction(self.action_open)
        self.menu_file.addAction(self.action_save)
        self.menu_file.addSeparator()
        self.menu_file.addAction(self.action_copy)
        self.menu_file.addAction(self.action_move)
        self.menu_file.addAction(self.action_delete)
        self.menu_file.addSeparator()
        self.menu_file.addAction(self.action_quit)

        # Edit
        self.menu_edit = self.menubar.addMenu('Edit')
        self.menu_edit.addAction(self.action_rotate_left)
        self.menu_edit.addAction(self.action_rotate_right)
        self.menu_edit.addSeparator()
        self.menu_edit.addAction(self.action_flip_horizontal)
        self.menu_edit.addAction(self.action_flip_vertical)

        # View
        self.menu_view = self.menubar.addMenu('View')
        self.menu_view.addAction(self.action_fullscreen)
        self.menu_view.addAction(self.action_normal_size)
        self.menu_view.addAction(self.action_fit_screen)
        self.menu_view.addSeparator()
        self.menu_view.addAction(self.action_zoom_in)
        self.menu_view.addAction(self.action_zoom_out)
        self.menu_view.addSeparator()
        self.menu_view.addAction(self.action_fit_vertical)
        self.menu_view.addAction(self.action_fit_horizontal)
        self.menu_view.addSeparator()
        self.menu_view.addAction(self.action_image_gallery)

        # Go
        self.menu_go = self.menubar.addMenu('Go')
        self.menu_go.addAction(self.action_previous_image)
        self.menu_go.addAction(self.action_next_image)
        self.menu_go.addSeparator()
        self.menu_go.addAction(self.action_first_image)
        self.menu_go.addAction(self.action_last_image)

        # About
        self.menu_about = self.menubar.addMenu('About')
        self.menu_about.addAction(self.action_about)

    def create_toolbar(self):
        self.toolbar = self.addToolBar('Tool bar')

        self.toolbar.addAction(self.action_open)
        self.toolbar.addAction(self.action_save)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.action_fullscreen)
        self.toolbar.addAction(self.action_normal_size)
        self.toolbar.addAction(self.action_fit_screen)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.action_zoom_in)
        self.toolbar.addAction(self.action_zoom_out)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.action_rotate_left)
        self.toolbar.addAction(self.action_rotate_right)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.action_first_image)
        self.toolbar.addAction(self.action_previous_image)
        self.toolbar.addAction(self.action_next_image)
        self.toolbar.addAction(self.action_last_image)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.action_copy)
        self.toolbar.addAction(self.action_move)

    def load_settings(self):
        self.settings = QSettings()
        check_state = self.settings.value('view/image_gallery',
                                          True,
                                          type=bool)
        self.action_image_gallery.setChecked(check_state)
        self.image_gallery_triggered()

    def contextMenuEvent(self, QContextMenuEvent):
        menu = QMenu()
        menu.addAction(self.action_fullscreen)
        menu.addSeparator()
        menu.addAction(self.action_image_gallery)
        menu.addSeparator()
        menu.addAction(self.action_previous_image)
        menu.addAction(self.action_next_image)
        menu.addSeparator()
        menu.addAction(self.action_normal_size)
        menu.addAction(self.action_fit_screen)
        menu.addAction(self.action_fit_vertical)
        menu.addAction(self.action_fit_horizontal)
        menu.addSeparator()
        menu.addAction(self.action_zoom_in)
        menu.addAction(self.action_zoom_out)
        menu.addSeparator()
        menu.addAction(self.action_copy)
        menu.addAction(self.action_move)
        menu.addSeparator()
        menu.addAction(self.action_delete)
        menu.exec_(QContextMenuEvent.globalPos())

    def eventFilter(self, obj, event):
        """ filter events for wheel events

        Args:
            obj (QWidget): scroll_area
            event (QEvent): event
        """

        # try:
        if event.type() == QEvent.Wheel:
            if event.angleDelta().y() < 0:
                self.next_image()
            else:
                self.previous_image()

            return True
        elif event.type() == QEvent.MouseButtonPress and event.button(
        ) == Qt.RightButton:
            index = self.image_gallery.select_row_pos()
            if index > -1:
                self.index = index
                self.display_image()
                return True
        # pass the event on to the parent class
        return super(QMainWindow, self).eventFilter(obj, event)

    def keyPressEvent(self, event):
        key = event.key()
        if key == Qt.Key_Delete:
            self.delete()
        elif key == Qt.Key_Left:
            self.previous_image()
        elif key == Qt.Key_Right:
            self.next_image()
        elif key == Qt.Key_PageUp:
            self.first_image()
        elif key == Qt.Key_PageDown:
            self.last_image()
        elif key == Qt.Key_Escape and self.isFullScreen():
            self.fullscreen()
        else:
            QWidget.keyPressEvent(self, event)

    def mouseDoubleClickEvent(self, QMouseEvent):
        self.fullscreen()

    def mousePressEvent(self, QMouseEvent):
        self.mouse_position = QMouseEvent.pos()

    def mouseMoveEvent(self, QMouseEvent):
        diff = QPoint(QMouseEvent.pos() - self.mouse_position)
        self.mouse_position = QMouseEvent.pos()
        self.scroll_area.verticalScrollBar().setValue(
            self.scroll_area.verticalScrollBar().value() - diff.y())
        self.scroll_area.horizontalScrollBar().setValue(
            self.scroll_area.horizontalScrollBar().value() - diff.x())

    def resizeEvent(self, event):
        if not self.index == -1:
            self.display_image()

    def create_images(self, filename):
        """Create image list

        Args:
            filename (string): file from which to retrieve the list of images in the folder
        """

        self.images.clear()
        # get images only with an allowed extension
        for ext in self.extensions:
            self.images += glob.glob(
                os.path.join(
                    glob.escape(os.path.dirname(filename)),
                    '*.' + ''.join('[%s%s]' % (e.lower(), e.upper())
                                   for e in ext)))

        self.images.sort()
        if filename in self.images:
            self.index = self.images.index(filename)
        else:
            self.index = -1

        # iamge list
        self.image_gallery.add_images(self.images)

    def remove_index(self):
        """ remove file from list images and display next or previous image
        """

        del self.images[self.index]
        self.image_gallery.remove_row(self.index)

        if len(self.images) == 0:
            self.images.clear()
            self.index = -1
            self.image.clear()
            self.image.resize(self.image.minimumSizeHint())
        elif self.index < len(self.images) - 1:
            self.display_image()
        else:
            self.index = len(self.images) - 1
            self.display_image()

    def display_image(self):
        if not self.index == -1:
            self.image.clear()
            self.image.resize(self.image.minimumSizeHint())

            file = self.images[self.index]
            if os.path.isfile(file):
                self.label_name.setText(file)
                self.label_numero.setText(
                    str(self.index + 1) + ' / ' + str(len(self.images)))

                # image list
                self.image_gallery.select_row(self.index)

                image_reader = QImageReader(file)
                if image_reader.imageCount() > 1:
                    # Animated image
                    movie = QMovie(file)
                    movie.setCacheMode(QMovie.CacheAll)
                    movie.jumpToFrame(0)
                    movie_size = movie.currentPixmap().size()
                    self.image.setMovie(movie)
                    self.image.resize(movie_size)
                    movie.start()
                else:
                    self.image.setPixmap(QPixmap(file))
                    self.image.resize(self.image.pixmap().size())

                # fit image
                if self.action_fit_screen.isChecked():
                    self.fit_screen()
                elif self.action_fit_horizontal.isChecked():
                    self.fit_width()
                elif self.action_fit_vertical.isChecked():
                    self.fit_height()

                else:
                    self.ratio = 1.0

                self.action_zoom_in.setEnabled(True)
                self.action_zoom_out.setEnabled(True)

                # scrollbar position
                self.scroll_area.verticalScrollBar().setSliderPosition(0)
                self.scroll_area.horizontalScrollBar().setSliderPosition(0)

    def resize_image(self):
        if self.action_fit_screen.isChecked():
            self.fit_screen()
        elif self.action_fit_horizontal.isChecked():
            self.fit_width()
        elif self.action_fit_vertical.isChecked():
            self.fit_height()
        elif self.image.pixmap():
            self.image.resize(self.ratio * self.image.pixmap().size())
        elif movie := self.image.movie():
            movie.jumpToFrame(0)
            movie_size = movie.currentPixmap().size()
            self.image.resize(self.ratio * movie_size)
import sys
from PySide6.QtWidgets import QApplication, QLabel

if __name__ == "__main__":
    app = QApplication([])
    label = QLabel("Hello World!")
    label.resize(400, 400)
    label.show()
    sys.exit(app.exec())