Beispiel #1
0
class TimebaseBox(QGroupBox):
    def __init__(self, controller, parent=None):
        super().__init__("Timebase", parent=parent)
        self.controller = controller

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.timebase_options = [
            "100 us",
            "200 us",
            "500 us",
            "1 ms",
            "2 ms",
            "5 ms",
            "10 ms",
            "20 ms",
        ]
        self.combobox_timebase = QComboBox()
        self.combobox_timebase.addItems(self.timebase_options)
        self.combobox_timebase.setCurrentIndex(7)

        layout.addWidget(QLabel("time/div (1 div = 1/10 graph)"))
        layout.addWidget(self.combobox_timebase)

        self.combobox_timebase.currentTextChanged.connect(self.set_timebase)

    def set_timebase(self):
        timebase = self.combobox_timebase.currentText()
        self.controller.set_timebase(timebase)
Beispiel #2
0
 def createEditor(self, parent, option, index):
     editor = QComboBox(parent)
     if isinstance(self.items, QStringListModel):
         editor.setModel(self.items)
     else:
         editor.addItems(self.items)
     return editor
Beispiel #3
0
class MainWindowUI:
    def setup_ui(self, win: QMainWindow) -> None:
        # ui widgets
        self.toolbar = QToolBar("main", parent=win)
        self.port_combobox1 = PortCombobox("")
        self.port_combobox2 = PortCombobox("")
        self.baudrate_combobox = QComboBox()
        self.monitor1 = QPlainTextEdit("")
        self.monitor2 = QPlainTextEdit("")
        self.btn_clear_monitor1 = QPushButton("Clear")
        self.btn_clear_monitor2 = QPushButton("Clear")
        self.group_monitor1 = QGroupBox("Monitor 1")
        self.group_monitor2 = QGroupBox("Monitor 2")

        # setup widgets
        self.monitor1.setReadOnly(True)
        self.monitor1.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.monitor1.setUndoRedoEnabled(False)
        self.monitor2.setReadOnly(True)
        self.monitor2.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.monitor2.setUndoRedoEnabled(False)
        self.baudrate_combobox.addItems([
            "300",
            "1200",
            "2400",
            "4800",
            "9600",
            "19200",
            "38400",
            "57600",
            "74880",
            "115200",
            "230400",
            "250000",
            "500000",
            "1000000",
            "2000000",
        ])
        self.baudrate_combobox.setCurrentText("9600")

        # setup layout
        win.addToolBar(self.toolbar)

        v_layout = QVBoxLayout()  # type:ignore
        v_layout.addWidget(self.monitor1)
        v_layout.addWidget(self.btn_clear_monitor1)
        self.group_monitor1.setLayout(v_layout)

        v_layout = QVBoxLayout()  # type:ignore
        v_layout.addWidget(self.monitor2)
        v_layout.addWidget(self.btn_clear_monitor2)
        self.group_monitor2.setLayout(v_layout)

        h_layout = QHBoxLayout()  # type:ignore
        h_layout.addWidget(self.group_monitor1)
        h_layout.addWidget(self.group_monitor2)
        central_widget = QWidget()
        central_widget.setLayout(h_layout)
        win.setCentralWidget(central_widget)
Beispiel #4
0
    def setup_ui(self):
        super(SettingUI, self).setup_ui()
        max_width_label = QLabel(text="最大宽度",
                                 alignment=QtCore.Qt.AlignRight
                                 | QtCore.Qt.AlignVCenter)
        max_width_combo = QComboBox()
        max_width_combo.addItems(Globals.max_width_arr)
        max_width_combo.setCurrentIndex(self.max_width_index)
        max_width_combo.currentIndexChanged.connect(self.on_combo_changed)

        size_label = QLabel(text="输出字号",
                            alignment=QtCore.Qt.AlignRight
                            | QtCore.Qt.AlignVCenter)
        size_spin = QSpinBox()
        size_spin.setRange(10, 64)
        size_spin.setValue(Globals.config.get(Globals.UserData.font_size))
        size_spin.valueChanged.connect(self.on_save_font_size)

        output_name_label = QLabel(text="输出名称",
                                   alignment=QtCore.Qt.AlignRight
                                   | QtCore.Qt.AlignVCenter)
        output_name_edit = QLineEdit(
            Globals.config.get(Globals.UserData.font_save_name))
        output_name_edit.textEdited.connect(self.on_output_name_edited)

        output_label = QLabel(text="输出目录",
                              alignment=QtCore.Qt.AlignRight
                              | QtCore.Qt.AlignVCenter)
        output_line_edit = QLineEdit(
            Globals.config.get(Globals.UserData.output_dir))
        output_line_edit.setReadOnly(True)
        output_line_edit.cursorPositionChanged.connect(
            self.on_output_choose_clicked)

        mode_1_radio = QRadioButton("图集模式")
        mode_2_radio = QRadioButton("字体模式")
        mode_1_radio.setChecked(True)
        mode_1_radio.toggled.connect(self.on_mode_1_radio_toggled)
        mode_radio_group = QButtonGroup(self)
        mode_radio_group.addButton(mode_1_radio, 0)
        mode_radio_group.addButton(mode_2_radio, 1)

        self.main_layout.setColumnStretch(1, 1)
        self.main_layout.setColumnStretch(3, 1)
        self.main_layout.addWidget(mode_1_radio, 0, 0, 1, 1)
        self.main_layout.addWidget(mode_2_radio, 0, 1, 1, 1)
        self.main_layout.addWidget(output_name_label, 1, 0, 1, 1)
        self.main_layout.addWidget(output_name_edit, 1, 1, 1, 1)
        self.main_layout.addWidget(max_width_label, 1, 2, 1, 1)
        self.main_layout.addWidget(max_width_combo, 1, 3, 1, 1)
        self.main_layout.addWidget(output_label, 2, 0, 1, 1)
        self.main_layout.addWidget(output_line_edit, 2, 1, 1, 1)
        self.main_layout.addWidget(size_label, 2, 2, 1, 1)
        self.main_layout.addWidget(size_spin, 2, 3, 1, 1)

        self.max_width_combo = max_width_combo
        self.size_spin = size_spin
        self.output_name_edit = output_name_edit
        self.output_line_edit = output_line_edit
Beispiel #5
0
class DeviceConnectingManager(QDialog):
    def __init__(
        self,
        parent: QWidget,
        lcrmeter: LCRMeterIM3536,
        lcrmeter_status: DeviceStatus,
        stage_controller: StageControllerShot702,
        stage_controller_status: DeviceStatus,
    ) -> None:
        super().__init__(parent=parent)
        self._lcrmeter = lcrmeter
        self._lcrmeter_status = lcrmeter_status
        self._stage_controller = stage_controller
        self._stage_controller_status = stage_controller_status

        self._lcr_combobox_port = PortCombobox(LCRMeterIM3536.PORT_FILTER)
        self._lcr_combobox_baudrate = QComboBox()
        self._lcr_t_btn_connect = create_tool_button(is_text_beside_icon=True)
        self._stage_combobox_port = PortCombobox("")
        self._stage_t_btn_connect = create_tool_button(
            is_text_beside_icon=True)

        self._action_connect_lcr = create_action(
            self,
            text="Connect Port",
            icon=create_qicon(IconNames.ADD_GREEN),
            triggered=self._connect_lcr,
        )
        self._action_disconnect_lcr = create_action(
            self,
            text="Disconnect Port",
            icon=create_qicon(IconNames.REMOVE_RED),
            triggered=self._disconnect_lcr,
        )
        self._action_connect_stage_controller = create_action(
            self,
            text="Connect Port",
            icon=create_qicon(IconNames.ADD_GREEN),
            triggered=self._connect_stage_controller,
        )
        self._action_disconnect_stage_controller = create_action(
            self,
            text="Disconnect Port",
            icon=create_qicon(IconNames.REMOVE_RED),
            triggered=self._disconnect_stage_controller,
        )

        self._setup()

    def _setup(self):
        self._lcr_combobox_baudrate.addItems(LCRMeterIM3536.BAUDRATES)
        self._lcr_combobox_baudrate.setCurrentText(
            str(self._lcrmeter_status.baudrate))
        if (description := self._lcrmeter_status.description) is not None:
            self._lcr_combobox_port.setItemText(0, description)
        if (description :=
                self._stage_controller_status.description) is not None:
            self._stage_combobox_port.setItemText(0, description)
class SetSyncTimeWidget(QWidget):
    Sg_view_changed = Signal()

    def __init__(self, model: SettingsModel, parent=None):
        super(SetSyncTimeWidget, self).__init__(parent)

        self._time_list = ["5s", "10s", "15s", "15m", "30m", "45m"]
        self._time_in_sec = []
        for curr_time in self._time_list:
            time_int = int(re.search(r'\d+', curr_time).group())
            if 'm' in curr_time:
                time_int = time_int * 60
            if 'h' in curr_time:
                time_int = time_int * 3600
            self._time_in_sec.append(time_int)

        self._model = model
        self.setAccessibleName('InfoBox')
        self._titolo = QLabel()
        self._titolo.setText("Finestra Temporale")
        self._titolo.setAccessibleName('Title2')

        self.sottotitolo = QLabel()
        self.sottotitolo.setAccessibleName('Sottotitolo')
        self.sottotitolo.setText("Seleziona finestra temporale per la sincronizzazione")

        self.spaceLabel = QLabel(" ")

        self.time_box = QComboBox()
        self.time_box.wheelEvent = lambda event: None
        self.time_box.addItems(self._time_list)
        self.Sl_model_changed()

        layout = QVBoxLayout()
        layout.addWidget(self._titolo)
        layout.addWidget(self.sottotitolo)
        layout.addWidget(self.spaceLabel)
        layout.addWidget(self.time_box)

        self.setLayout(layout)

        # connect signal
        self.time_box.currentIndexChanged.connect(self.Sl_time_checked)

    @Slot()
    def Sl_time_checked(self):
        self.Sg_view_changed.emit()

    @Slot()
    def Sl_model_changed(self):
        time = self._model.get_sync_time()
        i: int = 0
        for el in self._time_in_sec:
            if time == el:
                self.time_box.setCurrentIndex(i)
            i += 1
Beispiel #7
0
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("My App")
        box = QComboBox()
        box.addItems(["One", "Two", "Three"])

        box.currentIndexChanged.connect(self.index_changed)
        box.currentTextChanged.connect(self.text_changed)

        self.setCentralWidget(box)
Beispiel #8
0
class InterpolateBadsDialog(QDialog):
    def __init__(self, parent):
        super().__init__(parent)
        self.setWindowTitle("Interpolate bad channels")
        vbox = QVBoxLayout(self)
        grid = QGridLayout()
        grid.addWidget(QLabel("Reset bads:"), 0, 0)
        self.reset_bads_checkbox = QCheckBox()
        self.reset_bads_checkbox.setChecked(True)
        grid.addWidget(self.reset_bads_checkbox, 0, 1)
        grid.addWidget(QLabel("Mode:"), 1, 0)
        self.mode_select = QComboBox()
        self.modes = {"Accurate": "accurate", "Fast": "fast"}
        self.mode_select.addItems(self.modes.keys())
        self.mode_select.setCurrentText("Accurate")
        grid.addWidget(self.mode_select, 1, 1)
        grid.addWidget(QLabel("Origin (x, y, z):"), 2, 0)
        hbox = QHBoxLayout()
        self.x = QDoubleSpinBox()
        self.x.setValue(0)
        self.x.setDecimals(3)
        hbox.addWidget(self.x)
        self.y = QDoubleSpinBox()
        self.y.setValue(0)
        self.y.setDecimals(3)
        hbox.addWidget(self.y)
        self.z = QDoubleSpinBox()
        self.z.setValue(0.04)
        self.z.setDecimals(3)
        hbox.addWidget(self.z)
        grid.addLayout(hbox, 2, 1)

        vbox.addLayout(grid)
        buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        vbox.addWidget(buttonbox)
        buttonbox.accepted.connect(self.accept)
        buttonbox.rejected.connect(self.reject)
        vbox.setSizeConstraint(QVBoxLayout.SetFixedSize)

    @property
    def origin(self):
        x = float(self.x.value())
        y = float(self.y.value())
        z = float(self.z.value())
        return x, y, z

    @property
    def mode(self):
        return self.mode_select.currentText()

    @property
    def reset_bads(self):
        return self.reset_bads_checkbox.isChecked()
    def setupWidgets(self):
        """
        Set up the widgets and layouts for interface.
        """
        dir_label = QLabel("Choose Directory:")
        self.dir_line_edit = QLineEdit()

        dir_button = QPushButton('...')
        dir_button.setToolTip("Select file directory.")
        dir_button.clicked.connect(self.setDirectory)

        self.change_name_edit = QLineEdit()
        self.change_name_edit.setToolTip(
            "Files will be appended with numerical values.For example: filename <b> 01 </b >.jpg")
        self.change_name_edit.setPlaceholderText("Change file names to...")

        rename_button = QPushButton("Rename Files")
        rename_button.setToolTip("Begin renaming files in directory.")
        rename_button.clicked.connect(self.renameFiles)

        file_exts = [".jpg", ".jpeg", ".png", ".gif", ".txt"]

        # Create combo box for selecting file extensions.
        ext_cb = QComboBox()
        self.cb_value = file_exts[0]
        ext_cb.setToolTip("Only files with this extension will be changed.")
        ext_cb.addItems(file_exts)
        ext_cb.currentTextChanged.connect(self.updateCbValue)

        # Text edit is for displaying the file names as they are updated.
        self.display_files_edit = QTextEdit()
        self.display_files_edit.setReadOnly(True)
        self.progress_bar = QProgressBar()
        self.progress_bar.setValue(0)

        # Set layout and widgets.
        grid = QGridLayout()
        grid.addWidget(dir_label, 0, 0)
        grid.addWidget(self.dir_line_edit, 1, 0, 1, 2)
        grid.addWidget(dir_button, 1, 2)
        grid.addWidget(self.change_name_edit, 2, 0)
        grid.addWidget(ext_cb, 2, 1)
        grid.addWidget(rename_button, 2, 2)
        grid.addWidget(self.display_files_edit, 3, 0, 1, 3)
        grid.addWidget(self.progress_bar, 4, 0, 1, 3)
        self.setLayout(grid)
Beispiel #10
0
class FindEventsDialog(QDialog):
    def __init__(self, parent, channels, default_stim):
        super().__init__(parent)
        self.setWindowTitle("Find Events")
        vbox = QVBoxLayout(self)
        grid = QGridLayout()

        grid.addWidget(QLabel("Stim channel:"), 0, 0)
        self.stimchan = QComboBox()
        self.stimchan.addItems(channels)
        self.stimchan.setCurrentIndex(default_stim)
        grid.addWidget(self.stimchan, 0, 1)

        grid.addWidget(QLabel("Consecutive"), 1, 0)
        self.consecutive = QCheckBox()
        self.consecutive.setChecked(True)
        grid.addWidget(self.consecutive, 1, 1)

        grid.addWidget(QLabel("Initial event"), 2, 0)
        self.initial_event = QCheckBox()
        self.initial_event.setChecked(True)
        grid.addWidget(self.initial_event, 2, 1)

        grid.addWidget(QLabel("Cast to unsigned integer"), 3, 0)
        self.uint_cast = QCheckBox()
        self.uint_cast.setChecked(True)
        grid.addWidget(self.uint_cast, 3, 1)

        grid.addWidget(QLabel("Minimum duration:"), 4, 0)
        self.minduredit = QSpinBox()
        self.minduredit.setMaximum(MAX_INT)
        grid.addWidget(self.minduredit, 4, 1)

        grid.addWidget(QLabel("Shortest event:"), 5, 0)
        self.shortesteventedit = QSpinBox()
        self.shortesteventedit.setMaximum(MAX_INT)
        grid.addWidget(self.shortesteventedit, 5, 1)

        vbox.addLayout(grid)
        buttonbox = QDialogButtonBox(QDialogButtonBox.Ok
                                     | QDialogButtonBox.Cancel)
        vbox.addWidget(buttonbox)
        buttonbox.accepted.connect(self.accept)
        buttonbox.rejected.connect(self.reject)
        vbox.setSizeConstraint(QVBoxLayout.SetFixedSize)
Beispiel #11
0
class KeyPressWidget(StepBaseWidget):
    def __init__(self, step: Steps.KeyPress, timeline):
        super(KeyPressWidget, self).__init__(step, timeline)

        detail_layout = self.ui.detailFrame.layout()

        # Key input
        self.key_label = QLabel("Key: ", self)
        self.key_line_edit = QLineEdit(self)
        self.key_line_edit.setMaxLength(1)
        self.key_line_edit.setText(self.step.key)
        self.key_line_edit.textChanged.connect(self.update_key)

        # Mod Input
        self.mod_label = QLabel("Mod: ", self)
        self.mod_combo = QComboBox(self)
        mod_list = ["None", "Ctrl", "Shift", "Alt", "Super"]
        self.mod_combo.addItems(mod_list)

        if self.step.mod:
            current_mod_index = mod_list.index(self.step.mod.capitalize())
            self.mod_combo.setCurrentIndex(current_mod_index)

        self.mod_combo.currentIndexChanged.connect(self.update_mod)

        # Add to layout
        detail_layout.addWidget(self.key_label)
        detail_layout.addWidget(self.key_line_edit)
        detail_layout.addWidget(self.mod_label)
        detail_layout.addWidget(self.mod_combo)

    def update_key(self):
        if not self.key_line_edit.text():
            self.key_line_edit.setText(" ")
        self.step.key = self.key_line_edit.text()

    def update_mod(self):
        if self.mod_combo.currentText() == "None":
            self.step.mod = None
        else:
            self.step.mod = self.mod_combo.currentText().lower()
Beispiel #12
0
class TriggerBox(QGroupBox):
    def __init__(self, controller, parent=None):
        super().__init__("Trigger", parent=parent)
        self.controller = controller

        self.setCheckable(True)
        self.setChecked(False)

        layout = QHBoxLayout()
        self.setLayout(layout)

        self.combobox_slope = QComboBox()
        self.combobox_slope.addItems(["Rising", "Falling", "Any"])
        self.combobox_slope.setCurrentIndex(0)

        layout.addWidget(QLabel("Trigger slope"))
        layout.addWidget(self.combobox_slope)

        self.toggled.connect(self.controller.set_trigger_state)
        self.combobox_slope.currentTextChanged.connect(
            self.controller.set_trigger_slope)
Beispiel #13
0
class DeviceBox(QGroupBox):
    def __init__(self, controller, parent=None):
        super().__init__("Device", parent=parent)
        self.controller = controller

        self.is_connected = False

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.button_refresh = QPushButton("Refresh")
        self.combobox_ports = QComboBox()
        self.button_connect = QPushButton("Connect")

        layout.addWidget(self.button_refresh)
        layout.addWidget(self.combobox_ports)
        layout.addWidget(self.button_connect)

        self.button_refresh.clicked.connect(self.refresh_ports)
        self.button_connect.clicked.connect(self.connect_to_device)

    def refresh_ports(self):
        self.combobox_ports.clear()
        self.combobox_ports.addItems(self.controller.get_ports_names())

    def connect_to_device(self):

        if not self.is_connected:
            port = self.combobox_ports.currentText()
            self.controller.connect_to_device(port)
        else:
            self.controller.disconnect_device()

        self.is_connected = self.controller.is_device_connected()
        if self.is_connected:
            self.button_connect.setText("Disconnect")
        else:
            self.button_connect.setText("Connect")
Beispiel #14
0
class Page1Widget(QWidget):
    
    def __init__(self):
        super().__init__()

        # Create Widgets
        self.dropdown_quest = QComboBox()
        self.dropdown_quest.addItems(MODES)
        self.dropdown_quest.setCurrentText("Romaji")
        self.dropdown_ans = QComboBox()
        self.dropdown_ans.addItems(MODES)
        self.dropdown_also = QComboBox()
        self.dropdown_also.addItem("----")
        self.dropdown_also.addItems(MODES)
        self.spinbox_level = QSpinBox(Minimum=1, Maximum=2)

        self.list_groups = QListWidget(FixedWidth=W * .6)
        for group_name in GROUPS:
            item = QListWidgetItem(group_name)
            item.setCheckState(QtCore.Qt.Unchecked)
            self.list_groups.addItem(item)

        # Make Layout
        self.sub_layout = QVBoxLayout()
        self.sub_layout.addWidget(QLabel('Question:'))
        self.sub_layout.addWidget(self.dropdown_quest)
        self.sub_layout.addWidget(QLabel('Answer:'))
        self.sub_layout.addWidget(self.dropdown_ans)
        self.sub_layout.addWidget(QLabel('Also:'))
        self.sub_layout.addWidget(self.dropdown_also)
        self.sub_layout.addWidget(QLabel('Level:'))
        self.sub_layout.addWidget(self.spinbox_level)

        self.layout = QHBoxLayout(self)
        self.layout.addLayout(self.sub_layout)
        self.layout.addWidget(self.list_groups)
Beispiel #15
0
class UIDrawROIWindow:
    def setup_ui(self, draw_roi_window_instance, rois, dataset_rtss,
                 signal_roi_drawn):
        """
        this function is responsible for setting up the UI
        for DrawROIWindow
        param draw_roi_window_instance: the current drawing
        window instance.
        :param rois: the rois to be drawn
        :param dataset_rtss: the rtss to be written to
        :param signal_roi_drawn: the signal to be triggered
        when roi is drawn
        """
        self.patient_dict_container = PatientDictContainer()

        self.rois = rois
        self.dataset_rtss = dataset_rtss
        self.signal_roi_drawn = signal_roi_drawn
        self.drawn_roi_list = {}
        self.standard_organ_names = []
        self.standard_volume_names = []
        self.standard_names = []  # Combination of organ and volume
        self.ROI_name = None  # Selected ROI name
        self.target_pixel_coords = []  # This will contain the new pixel
        # coordinates specified by the min and max
        self.drawingROI = None
        self.slice_changed = False
        self.drawing_tool_radius = INITIAL_DRAWING_TOOL_RADIUS
        self.keep_empty_pixel = False
        # pixel density
        self.target_pixel_coords_single_array = []  # 1D array
        self.draw_roi_window_instance = draw_roi_window_instance
        self.colour = None
        self.ds = None
        self.zoom = 1.0

        self.upper_limit = None
        self.lower_limit = None

        # is_four_view is set to True to stop the SUV2ROI button from appearing
        self.dicom_view = DicomAxialView(is_four_view=True)
        self.current_slice = self.dicom_view.slider.value()
        self.dicom_view.slider.valueChanged.connect(self.slider_value_changed)
        self.init_layout()

        QtCore.QMetaObject.connectSlotsByName(draw_roi_window_instance)

    def retranslate_ui(self, draw_roi_window_instance):
        """
            this function retranslate the ui for draw roi window

            :param draw_roi_window_instance: the current drawing
            window instance.
            """
        _translate = QtCore.QCoreApplication.translate
        draw_roi_window_instance.setWindowTitle(
            _translate("DrawRoiWindowInstance",
                       "OnkoDICOM - Draw Region Of Interest"))
        self.roi_name_label.setText(
            _translate("ROINameLabel", "Region of Interest: "))
        self.roi_name_line_edit.setText(_translate("ROINameLineEdit", ""))
        self.image_slice_number_label.setText(
            _translate("ImageSliceNumberLabel", "Slice Number: "))
        self.image_slice_number_line_edit.setText(
            _translate("ImageSliceNumberLineEdit",
                       str(self.dicom_view.current_slice_number)))
        self.image_slice_number_transect_button.setText(
            _translate("ImageSliceNumberTransectButton", "Transect"))
        self.image_slice_number_box_draw_button.setText(
            _translate("ImageSliceNumberBoxDrawButton", "Set Bounds"))
        self.image_slice_number_draw_button.setText(
            _translate("ImageSliceNumberDrawButton", "Draw"))
        self.image_slice_number_move_forward_button.setText(
            _translate("ImageSliceNumberMoveForwardButton", ""))
        self.image_slice_number_move_backward_button.setText(
            _translate("ImageSliceNumberMoveBackwardButton", ""))
        self.draw_roi_window_instance_save_button.setText(
            _translate("DrawRoiWindowInstanceSaveButton", "Save"))
        self.draw_roi_window_instance_cancel_button.setText(
            _translate("DrawRoiWindowInstanceCancelButton", "Cancel"))
        self.internal_hole_max_label.setText(
            _translate("InternalHoleLabel",
                       "Maximum internal hole size (pixels): "))
        self.internal_hole_max_line_edit.setText(
            _translate("InternalHoleInput", "9"))
        self.isthmus_width_max_label.setText(
            _translate("IsthmusWidthLabel",
                       "Maximum isthmus width size (pixels): "))
        self.isthmus_width_max_line_edit.setText(
            _translate("IsthmusWidthInput", "5"))
        self.min_pixel_density_label.setText(
            _translate("MinPixelDensityLabel", "Minimum density (pixels): "))
        self.min_pixel_density_line_edit.setText(
            _translate("MinPixelDensityInput", ""))
        self.max_pixel_density_label.setText(
            _translate("MaxPixelDensityLabel", "Maximum density (pixels): "))
        self.max_pixel_density_line_edit.setText(
            _translate("MaxPixelDensityInput", ""))
        self.toggle_keep_empty_pixel_label.setText(
            _translate("ToggleKeepEmptyPixelLabel", "Keep empty pixel: "))

        self.draw_roi_window_viewport_zoom_label.setText(
            _translate("DrawRoiWindowViewportZoomLabel", "Zoom: "))
        self.draw_roi_window_cursor_radius_change_label.setText(
            _translate("DrawRoiWindowCursorRadiusChangeLabel",
                       "Cursor Radius: "))

        self.draw_roi_window_instance_action_reset_button.setText(
            _translate("DrawRoiWindowInstanceActionClearButton", "Reset"))

    def init_layout(self):
        """
        Initialize the layout for the DICOM View tab.
        Add the view widget and the slider in the layout.
        Add the whole container 'tab2_view' as a tab in the main page.
        """

        # Initialise a DrawROIWindow
        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)
        self.draw_roi_window_instance.setObjectName("DrawRoiWindowInstance")
        self.draw_roi_window_instance.setWindowIcon(window_icon)

        # Creating a form box to hold all buttons and input fields
        self.draw_roi_window_input_container_box = QFormLayout()
        self.draw_roi_window_input_container_box. \
            setObjectName("DrawRoiWindowInputContainerBox")
        self.draw_roi_window_input_container_box. \
            setLabelAlignment(Qt.AlignLeft)

        # Create a label for denoting the ROI name
        self.roi_name_label = QLabel()
        self.roi_name_label.setObjectName("ROINameLabel")
        self.roi_name_line_edit = QLineEdit()
        # Create an input box for ROI name
        self.roi_name_line_edit.setObjectName("ROINameLineEdit")
        self.roi_name_line_edit.setSizePolicy(QSizePolicy.Minimum,
                                              QSizePolicy.Minimum)
        self.roi_name_line_edit.resize(
            self.roi_name_line_edit.sizeHint().width(),
            self.roi_name_line_edit.sizeHint().height())
        self.roi_name_line_edit.setEnabled(False)
        self.draw_roi_window_input_container_box. \
            addRow(self.roi_name_label, self.roi_name_line_edit)

        # Create horizontal box to store image slice number and backward,
        # forward buttons
        self.image_slice_number_box = QHBoxLayout()
        self.image_slice_number_box.setObjectName("ImageSliceNumberBox")

        # Create a label for denoting the Image Slice Number
        self.image_slice_number_label = QLabel()
        self.image_slice_number_label.setObjectName("ImageSliceNumberLabel")
        self.image_slice_number_box.addWidget(self.image_slice_number_label)
        # Create a line edit for containing the image slice number
        self.image_slice_number_line_edit = QLineEdit()
        self.image_slice_number_line_edit. \
            setObjectName("ImageSliceNumberLineEdit")
        self.image_slice_number_line_edit. \
            setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.image_slice_number_line_edit.resize(
            self.image_slice_number_line_edit.sizeHint().width(),
            self.image_slice_number_line_edit.sizeHint().height())

        self.image_slice_number_line_edit.setCursorPosition(0)
        self.image_slice_number_line_edit.setEnabled(False)
        self.image_slice_number_box. \
            addWidget(self.image_slice_number_line_edit)
        # Create a button to move backward to the previous image
        self.image_slice_number_move_backward_button = QPushButton()
        self.image_slice_number_move_backward_button. \
            setObjectName("ImageSliceNumberMoveBackwardButton")
        self.image_slice_number_move_backward_button.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.image_slice_number_move_backward_button.resize(QSize(24, 24))
        self.image_slice_number_move_backward_button.clicked. \
            connect(self.onBackwardClicked)
        icon_move_backward = QtGui.QIcon()
        icon_move_backward.addPixmap(
            QtGui.QPixmap(
                resource_path('res/images/btn-icons/backward_slide_icon.png')))
        self.image_slice_number_move_backward_button.setIcon(
            icon_move_backward)
        self.image_slice_number_box. \
            addWidget(self.image_slice_number_move_backward_button)
        # Create a button to move forward to the next image
        self.image_slice_number_move_forward_button = QPushButton()
        self.image_slice_number_move_forward_button. \
            setObjectName("ImageSliceNumberMoveForwardButton")
        self.image_slice_number_move_forward_button.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.image_slice_number_move_forward_button.resize(QSize(24, 24))
        self.image_slice_number_move_forward_button.clicked. \
            connect(self.onForwardClicked)
        icon_move_forward = QtGui.QIcon()
        icon_move_forward.addPixmap(
            QtGui.QPixmap(
                resource_path('res/images/btn-icons/forward_slide_icon.png')))
        self.image_slice_number_move_forward_button.setIcon(icon_move_forward)
        self.image_slice_number_box. \
            addWidget(self.image_slice_number_move_forward_button)

        self.draw_roi_window_input_container_box. \
            addRow(self.image_slice_number_box)

        # Create a horizontal box for containing the zoom function
        self.draw_roi_window_viewport_zoom_box = QHBoxLayout()
        self.draw_roi_window_viewport_zoom_box.setObjectName(
            "DrawRoiWindowViewportZoomBox")
        # Create a label for zooming
        self.draw_roi_window_viewport_zoom_label = QLabel()
        self.draw_roi_window_viewport_zoom_label. \
            setObjectName("DrawRoiWindowViewportZoomLabel")
        # Create an input box for zoom factor
        self.draw_roi_window_viewport_zoom_input = QLineEdit()
        self.draw_roi_window_viewport_zoom_input. \
            setObjectName("DrawRoiWindowViewportZoomInput")
        self.draw_roi_window_viewport_zoom_input. \
            setText("{:.2f}".format(self.zoom * 100) + "%")
        self.draw_roi_window_viewport_zoom_input.setCursorPosition(0)
        self.draw_roi_window_viewport_zoom_input.setEnabled(False)
        self.draw_roi_window_viewport_zoom_input. \
            setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.draw_roi_window_viewport_zoom_input.resize(
            self.draw_roi_window_viewport_zoom_input.sizeHint().width(),
            self.draw_roi_window_viewport_zoom_input.sizeHint().height())
        # Create 2 buttons for zooming in and out
        # Zoom In Button
        self.draw_roi_window_viewport_zoom_in_button = QPushButton()
        self.draw_roi_window_viewport_zoom_in_button. \
            setObjectName("DrawRoiWindowViewportZoomInButton")
        self.draw_roi_window_viewport_zoom_in_button.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.draw_roi_window_viewport_zoom_in_button.resize(QSize(24, 24))
        self.draw_roi_window_viewport_zoom_in_button. \
            setProperty("QPushButtonClass", "zoom-button")
        icon_zoom_in = QtGui.QIcon()
        icon_zoom_in.addPixmap(
            QtGui.QPixmap(
                resource_path('res/images/btn-icons/zoom_in_icon.png')))
        self.draw_roi_window_viewport_zoom_in_button.setIcon(icon_zoom_in)
        self.draw_roi_window_viewport_zoom_in_button.clicked. \
            connect(self.onZoomInClicked)
        # Zoom Out Button
        self.draw_roi_window_viewport_zoom_out_button = QPushButton()
        self.draw_roi_window_viewport_zoom_out_button. \
            setObjectName("DrawRoiWindowViewportZoomOutButton")
        self.draw_roi_window_viewport_zoom_out_button.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.draw_roi_window_viewport_zoom_out_button.resize(QSize(24, 24))
        self.draw_roi_window_viewport_zoom_out_button. \
            setProperty("QPushButtonClass", "zoom-button")
        icon_zoom_out = QtGui.QIcon()
        icon_zoom_out.addPixmap(
            QtGui.QPixmap(
                resource_path('res/images/btn-icons/zoom_out_icon.png')))
        self.draw_roi_window_viewport_zoom_out_button.setIcon(icon_zoom_out)
        self.draw_roi_window_viewport_zoom_out_button.clicked. \
            connect(self.onZoomOutClicked)
        self.draw_roi_window_viewport_zoom_box. \
            addWidget(self.draw_roi_window_viewport_zoom_label)
        self.draw_roi_window_viewport_zoom_box. \
            addWidget(self.draw_roi_window_viewport_zoom_input)
        self.draw_roi_window_viewport_zoom_box. \
            addWidget(self.draw_roi_window_viewport_zoom_out_button)
        self.draw_roi_window_viewport_zoom_box. \
            addWidget(self.draw_roi_window_viewport_zoom_in_button)
        self.draw_roi_window_input_container_box. \
            addRow(self.draw_roi_window_viewport_zoom_box)

        self.init_cursor_radius_change_box()
        # Create field to toggle two options: Keep empty pixel or fill empty
        # pixel when using draw cursor
        self.toggle_keep_empty_pixel_box = QHBoxLayout()
        self.toggle_keep_empty_pixel_label = QLabel()
        self.toggle_keep_empty_pixel_label. \
            setObjectName("ToggleKeepEmptyPixelLabel")
        # Create input for min pixel size
        self.toggle_keep_empty_pixel_combo_box = QComboBox()
        self.toggle_keep_empty_pixel_combo_box.addItems(["Off", "On"])
        self.toggle_keep_empty_pixel_combo_box.setCurrentIndex(0)
        self.toggle_keep_empty_pixel_combo_box.setEnabled(False)
        self.toggle_keep_empty_pixel_combo_box. \
            setObjectName("ToggleKeepEmptyPixelComboBox")
        self.toggle_keep_empty_pixel_combo_box. \
            setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.toggle_keep_empty_pixel_combo_box.resize(
            self.toggle_keep_empty_pixel_combo_box.sizeHint().width(),
            self.toggle_keep_empty_pixel_combo_box.sizeHint().height())
        self.toggle_keep_empty_pixel_combo_box.currentIndexChanged.connect(
            self.toggle_keep_empty_pixel_box_index_changed)
        self.toggle_keep_empty_pixel_box. \
            addWidget(self.toggle_keep_empty_pixel_label)
        self.toggle_keep_empty_pixel_box. \
            addWidget(self.toggle_keep_empty_pixel_combo_box)
        self.draw_roi_window_input_container_box. \
            addRow(self.toggle_keep_empty_pixel_box)

        # Create a horizontal box for transect and draw button
        self.draw_roi_window_transect_draw_box = QHBoxLayout()
        self.draw_roi_window_transect_draw_box. \
            setObjectName("DrawRoiWindowTransectDrawBox")
        # Create a transect button
        self.image_slice_number_transect_button = QPushButton()
        self.image_slice_number_transect_button. \
            setObjectName("ImageSliceNumberTransectButton")
        self.image_slice_number_transect_button.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum))
        self.image_slice_number_transect_button.resize(
            self.image_slice_number_transect_button.sizeHint().width(),
            self.image_slice_number_transect_button.sizeHint().height())
        self.image_slice_number_transect_button.clicked. \
            connect(self.transect_handler)
        icon_transect = QtGui.QIcon()
        icon_transect.addPixmap(
            QtGui.QPixmap(
                resource_path('res/images/btn-icons/transect_icon.png')))
        self.image_slice_number_transect_button.setIcon(icon_transect)
        self.draw_roi_window_transect_draw_box. \
            addWidget(self.image_slice_number_transect_button)
        # Create a bounding box button
        self.image_slice_number_box_draw_button = QPushButton()
        self.image_slice_number_box_draw_button. \
            setObjectName("ImageSliceNumberBoxDrawButton")
        self.image_slice_number_box_draw_button.setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)
        self.image_slice_number_box_draw_button.resize(
            self.image_slice_number_box_draw_button.sizeHint().width(),
            self.image_slice_number_box_draw_button.sizeHint().height())
        self.image_slice_number_box_draw_button.clicked. \
            connect(self.onBoxDrawClicked)
        icon_box_draw = QtGui.QIcon()
        icon_box_draw.addPixmap(
            QtGui.QPixmap(
                resource_path('res/images/btn-icons/draw_bound_icon.png')))
        self.image_slice_number_box_draw_button.setIcon(icon_box_draw)
        self.draw_roi_window_transect_draw_box. \
            addWidget(self.image_slice_number_box_draw_button)
        # Create a draw button
        self.image_slice_number_draw_button = QPushButton()
        self.image_slice_number_draw_button. \
            setObjectName("ImageSliceNumberDrawButton")
        self.image_slice_number_draw_button.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum))
        self.image_slice_number_draw_button.resize(
            self.image_slice_number_draw_button.sizeHint().width(),
            self.image_slice_number_draw_button.sizeHint().height())
        self.image_slice_number_draw_button.clicked.connect(self.onDrawClicked)
        icon_draw = QtGui.QIcon()
        icon_draw.addPixmap(
            QtGui.QPixmap(resource_path('res/images/btn-icons/draw_icon.png')))
        self.image_slice_number_draw_button.setIcon(icon_draw)
        self.draw_roi_window_transect_draw_box. \
            addWidget(self.image_slice_number_draw_button)
        self.draw_roi_window_input_container_box. \
            addRow(self.draw_roi_window_transect_draw_box)

        # Create a contour preview button
        self.row_preview_layout = QtWidgets.QHBoxLayout()
        self.button_contour_preview = QtWidgets.QPushButton("Preview contour")
        self.button_contour_preview.clicked.connect(self.onPreviewClicked)
        self.row_preview_layout.addWidget(self.button_contour_preview)
        self.draw_roi_window_input_container_box. \
            addRow(self.row_preview_layout)
        icon_preview = QtGui.QIcon()
        icon_preview.addPixmap(
            QtGui.QPixmap(
                resource_path('res/images/btn-icons/preview_icon.png')))
        self.button_contour_preview.setIcon(icon_preview)

        # Create input line edit for alpha value
        self.label_alpha_value = QtWidgets.QLabel("Alpha value:")
        self.input_alpha_value = QtWidgets.QLineEdit("0.2")
        self.input_alpha_value. \
            setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)
        self.input_alpha_value.resize(
            self.input_alpha_value.sizeHint().width(),
            self.input_alpha_value.sizeHint().height())
        self.input_alpha_value.setValidator(
            QRegularExpressionValidator(
                QRegularExpression("^[0-9]*[.]?[0-9]*$")))
        self.draw_roi_window_input_container_box. \
            addRow(self.label_alpha_value, self.input_alpha_value)

        # Create a label for denoting the max internal hole size
        self.internal_hole_max_label = QLabel()
        self.internal_hole_max_label.setObjectName("InternalHoleLabel")

        # Create input for max internal hole size
        self.internal_hole_max_line_edit = QLineEdit()
        self.internal_hole_max_line_edit.setObjectName("InternalHoleInput")
        self.internal_hole_max_line_edit. \
            setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)
        self.internal_hole_max_line_edit.resize(
            self.internal_hole_max_line_edit.sizeHint().width(),
            self.internal_hole_max_line_edit.sizeHint().height())
        self.internal_hole_max_line_edit.setValidator(
            QRegularExpressionValidator(
                QRegularExpression("^[0-9]*[.]?[0-9]*$")))
        self.draw_roi_window_input_container_box.addRow(
            self.internal_hole_max_label, self.internal_hole_max_line_edit)

        # Create a label for denoting the isthmus width size
        self.isthmus_width_max_label = QLabel()
        self.isthmus_width_max_label.setObjectName("IsthmusWidthLabel")
        # Create input for max isthmus width size
        self.isthmus_width_max_line_edit = QLineEdit()
        self.isthmus_width_max_line_edit.setObjectName("IsthmusWidthInput")
        self.isthmus_width_max_line_edit.setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)
        self.isthmus_width_max_line_edit.resize(
            self.isthmus_width_max_line_edit.sizeHint().width(),
            self.isthmus_width_max_line_edit.sizeHint().height())
        self.isthmus_width_max_line_edit.setValidator(
            QRegularExpressionValidator(
                QRegularExpression("^[0-9]*[.]?[0-9]*$")))
        self.draw_roi_window_input_container_box.addRow(
            self.isthmus_width_max_label, self.isthmus_width_max_line_edit)

        # Create a label for denoting the minimum pixel density
        self.min_pixel_density_label = QLabel()
        self.min_pixel_density_label.setObjectName("MinPixelDensityLabel")
        # Create input for min pixel size
        self.min_pixel_density_line_edit = QLineEdit()
        self.min_pixel_density_line_edit.setObjectName("MinPixelDensityInput")
        self.min_pixel_density_line_edit.setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)
        self.min_pixel_density_line_edit.resize(
            self.min_pixel_density_line_edit.sizeHint().width(),
            self.min_pixel_density_line_edit.sizeHint().height())
        self.min_pixel_density_line_edit.setValidator(
            QRegularExpressionValidator(
                QRegularExpression("^[0-9]*[.]?[0-9]*$")))
        self.draw_roi_window_input_container_box.addRow(
            self.min_pixel_density_label, self.min_pixel_density_line_edit)

        # Create a label for denoting the minimum pixel density
        self.max_pixel_density_label = QLabel()
        self.max_pixel_density_label.setObjectName("MaxPixelDensityLabel")
        # Create input for min pixel size
        self.max_pixel_density_line_edit = QLineEdit()
        self.max_pixel_density_line_edit.setObjectName("MaxPixelDensityInput")
        self.max_pixel_density_line_edit. \
            setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)
        self.max_pixel_density_line_edit.resize(
            self.max_pixel_density_line_edit.sizeHint().width(),
            self.max_pixel_density_line_edit.sizeHint().height())
        self.max_pixel_density_line_edit.setValidator(
            QRegularExpressionValidator(
                QRegularExpression("^[0-9]*[.]?[0-9]*$")))
        self.draw_roi_window_input_container_box.addRow(
            self.max_pixel_density_label, self.max_pixel_density_line_edit)

        # Create a button to clear the draw
        self.draw_roi_window_instance_action_reset_button = QPushButton()
        self.draw_roi_window_instance_action_reset_button. \
            setObjectName("DrawRoiWindowInstanceActionClearButton")
        self.draw_roi_window_instance_action_reset_button.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum))

        reset_button = self.draw_roi_window_instance_action_reset_button
        self.draw_roi_window_instance_action_reset_button.resize(
            reset_button.sizeHint().width(),
            reset_button.sizeHint().height())
        self.draw_roi_window_instance_action_reset_button.clicked. \
            connect(self.onResetClicked)
        self.draw_roi_window_instance_action_reset_button. \
            setProperty("QPushButtonClass", "fail-button")
        icon_clear_roi_draw = QtGui.QIcon()
        icon_clear_roi_draw.addPixmap(
            QtGui.QPixmap(
                resource_path('res/images/btn-icons/reset_roi_draw_icon.png')))
        self.draw_roi_window_instance_action_reset_button. \
            setIcon(icon_clear_roi_draw)
        self.draw_roi_window_input_container_box. \
            addRow(self.draw_roi_window_instance_action_reset_button)

        # Create a horizontal box for saving and cancel the drawing
        self.draw_roi_window_cancel_save_box = QHBoxLayout()
        self.draw_roi_window_cancel_save_box. \
            setObjectName("DrawRoiWindowCancelSaveBox")
        # Create an exit button to cancel the drawing
        # Add a button to go back/exit from the application
        self.draw_roi_window_instance_cancel_button = QPushButton()
        self.draw_roi_window_instance_cancel_button. \
            setObjectName("DrawRoiWindowInstanceCancelButton")
        self.draw_roi_window_instance_cancel_button.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum))
        self.draw_roi_window_instance_cancel_button.resize(
            self.draw_roi_window_instance_cancel_button.sizeHint().width(),
            self.draw_roi_window_instance_cancel_button.sizeHint().height())
        self.draw_roi_window_instance_cancel_button. \
            setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.draw_roi_window_instance_cancel_button.clicked. \
            connect(self.onCancelButtonClicked)
        self.draw_roi_window_instance_cancel_button. \
            setProperty("QPushButtonClass", "fail-button")
        icon_cancel = QtGui.QIcon()
        icon_cancel.addPixmap(
            QtGui.QPixmap(
                resource_path('res/images/btn-icons/cancel_icon.png')))
        self.draw_roi_window_instance_cancel_button.setIcon(icon_cancel)
        self.draw_roi_window_cancel_save_box. \
            addWidget(self.draw_roi_window_instance_cancel_button)
        # Create a save button to save all the changes
        self.draw_roi_window_instance_save_button = QPushButton()
        self.draw_roi_window_instance_save_button. \
            setObjectName("DrawRoiWindowInstanceSaveButton")
        self.draw_roi_window_instance_save_button.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum))
        self.draw_roi_window_instance_save_button.resize(
            self.draw_roi_window_instance_save_button.sizeHint().width(),
            self.draw_roi_window_instance_save_button.sizeHint().height())
        self.draw_roi_window_instance_save_button. \
            setProperty("QPushButtonClass", "success-button")
        icon_save = QtGui.QIcon()
        icon_save.addPixmap(
            QtGui.QPixmap(resource_path('res/images/btn-icons/save_icon.png')))
        self.draw_roi_window_instance_save_button.setIcon(icon_save)
        self.draw_roi_window_instance_save_button.clicked. \
            connect(self.onSaveClicked)
        self.draw_roi_window_cancel_save_box. \
            addWidget(self.draw_roi_window_instance_save_button)

        self.draw_roi_window_input_container_box. \
            addRow(self.draw_roi_window_cancel_save_box)

        # Creating a horizontal box to hold the ROI view and slider
        self.draw_roi_window_instance_view_box = QHBoxLayout()
        self.draw_roi_window_instance_view_box. \
            setObjectName("DrawRoiWindowInstanceViewBox")
        # Add View and Slider into horizontal box
        self.draw_roi_window_instance_view_box.addWidget(self.dicom_view)
        # Create a widget to hold the image slice box
        self.draw_roi_window_instance_view_widget = QWidget()
        self.draw_roi_window_instance_view_widget.setObjectName(
            "DrawRoiWindowInstanceActionWidget")
        self.draw_roi_window_instance_view_widget.setLayout(
            self.draw_roi_window_instance_view_box)

        # Create a horizontal box for containing the input fields and the
        # viewport
        self.draw_roi_window_main_box = QHBoxLayout()
        self.draw_roi_window_main_box.setObjectName("DrawRoiWindowMainBox")
        self.draw_roi_window_main_box. \
            addLayout(self.draw_roi_window_input_container_box, 1)
        self.draw_roi_window_main_box. \
            addWidget(self.draw_roi_window_instance_view_widget, 11)

        # Create a new central widget to hold the vertical box layout
        self.draw_roi_window_instance_central_widget = QWidget()
        self.draw_roi_window_instance_central_widget. \
            setObjectName("DrawRoiWindowInstanceCentralWidget")
        self.draw_roi_window_instance_central_widget.setLayout(
            self.draw_roi_window_main_box)

        self.retranslate_ui(self.draw_roi_window_instance)
        self.draw_roi_window_instance.setStyleSheet(stylesheet)
        self.draw_roi_window_instance. \
            setCentralWidget(self.draw_roi_window_instance_central_widget)
        QtCore.QMetaObject.connectSlotsByName(self.draw_roi_window_instance)

    def slider_value_changed(self):
        """
        actions to be taken when slider value changes

        """
        image_slice_number = self.current_slice
        # save progress
        self.save_drawing_progress(image_slice_number)
        self.set_current_slice(self.dicom_view.slider.value())

    def set_current_slice(self, slice_number):
        """
            set the current slice
            :param slice_number: the slice number to be set
        """
        self.image_slice_number_line_edit.setText(str(slice_number + 1))
        self.current_slice = slice_number
        self.dicom_view.update_view()

        # check if this slice has any drawings before
        if self.drawn_roi_list.get(self.current_slice) is not None:
            self.drawingROI = self.drawn_roi_list[
                self.current_slice]['drawingROI']
            self.ds = self.drawn_roi_list[self.current_slice]['ds']
            self.dicom_view.view.setScene(self.drawingROI)
            self.enable_cursor_radius_change_box()
            self.drawingROI.clear_cursor(self.drawing_tool_radius)

        else:
            self.disable_cursor_radius_change_box()
            self.ds = None

    def onZoomInClicked(self):
        """
        This function is used for zooming in button
        """
        self.dicom_view.zoom *= 1.05
        self.dicom_view.update_view(zoom_change=True)
        if self.drawingROI \
                and self.drawingROI.current_slice == self.current_slice:
            self.dicom_view.view.setScene(self.drawingROI)
        self.draw_roi_window_viewport_zoom_input.setText(
            "{:.2f}".format(self.dicom_view.zoom * 100) + "%")
        self.draw_roi_window_viewport_zoom_input.setCursorPosition(0)

    def onZoomOutClicked(self):
        """
        This function is used for zooming out button
        """
        self.dicom_view.zoom /= 1.05
        self.dicom_view.update_view(zoom_change=True)
        if self.drawingROI \
                and self.drawingROI.current_slice == self.current_slice:
            self.dicom_view.view.setScene(self.drawingROI)
        self.draw_roi_window_viewport_zoom_input. \
            setText("{:.2f}".format(self.dicom_view.zoom * 100) + "%")
        self.draw_roi_window_viewport_zoom_input.setCursorPosition(0)

    def toggle_keep_empty_pixel_box_index_changed(self):
        self.keep_empty_pixel = self.toggle_keep_empty_pixel_combo_box. \
                                    currentText() == "On"
        self.drawingROI.keep_empty_pixel = self.keep_empty_pixel

    def onCancelButtonClicked(self):
        """
        This function is used for canceling the drawing
        """
        self.closeWindow()

    def onBackwardClicked(self):
        """
        This function is used when backward button is clicked
        """
        image_slice_number = self.current_slice
        # save progress
        if self.save_drawing_progress(image_slice_number):
            # Backward will only execute if current image slice is above 0.
            if int(image_slice_number) > 0:
                # decrements slice by 1 and update slider to move to correct
                # position
                self.dicom_view.slider.setValue(image_slice_number - 1)

    def onForwardClicked(self):
        """
        This function is used when forward button is clicked
        """
        image_slice_number = self.current_slice
        # save progress
        if self.save_drawing_progress(image_slice_number):
            pixmaps = self.patient_dict_container.get("pixmaps_axial")
            total_slices = len(pixmaps)

            # Forward will only execute if current image slice is below the
            # total number of slices.
            if int(image_slice_number) < total_slices:
                # increments slice by 1 and update slider to move to correct
                # position
                self.dicom_view.slider.setValue(image_slice_number + 1)

    def onResetClicked(self):
        """
        This function is used when reset button is clicked
        """
        self.dicom_view.image_display()
        self.dicom_view.update_view()
        self.isthmus_width_max_line_edit.setText("5")
        self.internal_hole_max_line_edit.setText("9")
        self.min_pixel_density_line_edit.setText("")
        self.max_pixel_density_line_edit.setText("")
        if hasattr(self, 'bounds_box_draw'):
            delattr(self, 'bounds_box_draw')
        if hasattr(self, 'drawingROI'):
            delattr(self, 'drawingROI')
        self.ds = None

    def transect_handler(self):
        """
        Function triggered when the Transect button is pressed from the menu.
        """

        pixmaps = self.patient_dict_container.get("pixmaps_axial")
        id = self.current_slice
        dt = self.patient_dict_container.dataset[id]
        rowS = dt.PixelSpacing[0]
        colS = dt.PixelSpacing[1]
        dt.convert_pixel_data()
        MainPageCallClass().run_transect(
            self.draw_roi_window_instance,
            self.dicom_view.view,
            pixmaps[id],
            dt._pixel_array.transpose(),
            rowS,
            colS,
            is_roi_draw=True,
        )

    def save_drawing_progress(self, image_slice_number):
        """
        this function saves the drawing progress on current slice
        :param image_slice_number: the slice number to be saved
        """
        if self.slice_changed:
            if hasattr(self, 'drawingROI') and self.drawingROI \
                    and self.ds is not None \
                    and len(self.drawingROI.target_pixel_coords) != 0:
                alpha = float(self.input_alpha_value.text())
                pixel_hull_list = calculate_concave_hull_of_points(
                    self.drawingROI.target_pixel_coords, alpha)
                coord_list = []
                for pixel_hull in pixel_hull_list:
                    coord_list.append(pixel_hull)
                self.drawn_roi_list[image_slice_number] = {
                    'coords': coord_list,
                    'ds': self.ds,
                    'drawingROI': self.drawingROI
                }
                self.slice_changed = False
                return True
        else:
            return True

        return True

    def on_transect_close(self):
        """
        Function triggered when transect is closed
        """
        if self.upper_limit and self.lower_limit:
            self.min_pixel_density_line_edit.setText(str(self.lower_limit))
            self.max_pixel_density_line_edit.setText(str(self.upper_limit))

        self.dicom_view.update_view()

    def onDrawClicked(self):
        """
        Function triggered when the Draw button is pressed from the menu.
        """
        pixmaps = self.patient_dict_container.get("pixmaps_axial")

        if self.min_pixel_density_line_edit.text() == "" \
                or self.max_pixel_density_line_edit.text() == "":
            QMessageBox.about(self.draw_roi_window_instance, "Not Enough Data",
                              "Not all values are specified or correct.")
        else:
            # Getting most updated selected slice
            id = self.current_slice

            dt = self.patient_dict_container.dataset[id]
            dt.convert_pixel_data()

            # Path to the selected .dcm file
            location = self.patient_dict_container.filepaths[id]
            self.ds = pydicom.dcmread(location)

            min_pixel = self.min_pixel_density_line_edit.text()
            max_pixel = self.max_pixel_density_line_edit.text()

            # If they are number inputs
            if min_pixel.isdecimal() and max_pixel.isdecimal():

                min_pixel = int(min_pixel)
                max_pixel = int(max_pixel)

                if min_pixel >= max_pixel:
                    QMessageBox.about(
                        self.draw_roi_window_instance, "Incorrect Input",
                        "Please ensure maximum density is "
                        "atleast higher than minimum density.")

                self.drawingROI = Drawing(
                    pixmaps[id], dt._pixel_array.transpose(), min_pixel,
                    max_pixel, self.patient_dict_container.dataset[id],
                    self.draw_roi_window_instance, self.slice_changed,
                    self.current_slice, self.drawing_tool_radius,
                    self.keep_empty_pixel, set())
                self.slice_changed = True
                self.dicom_view.view.setScene(self.drawingROI)
                self.enable_cursor_radius_change_box()
            else:
                QMessageBox.about(self.draw_roi_window_instance,
                                  "Not Enough Data",
                                  "Not all values are specified or correct.")

    def onBoxDrawClicked(self):
        """
        Function triggered when bounding box button is pressed
        """
        id = self.current_slice
        dt = self.patient_dict_container.dataset[id]
        dt.convert_pixel_data()
        pixmaps = self.patient_dict_container.get("pixmaps_axial")

        self.bounds_box_draw = DrawBoundingBox(pixmaps[id], dt)
        self.dicom_view.view.setScene(self.bounds_box_draw)
        self.disable_cursor_radius_change_box()

    def onSaveClicked(self):
        """
            Function triggered when Save button is clicked
        """
        # Make sure the user has clicked Draw first
        if self.save_drawing_progress(image_slice_number=self.current_slice):
            self.saveROIList()

    def saveROIList(self):
        """
            Function triggered when saving ROI list
        """
        roi_list = ROI.convert_hull_list_to_contours_data(
            self.drawn_roi_list, self.patient_dict_container)
        if len(roi_list) == 0:
            QMessageBox.about(self.draw_roi_window_instance, "No ROI Detected",
                              "Please ensure you have drawn your ROI first.")
            return

        # The list of points will need to be converted into a
        # single-dimensional array, as RTSTRUCT contour data is stored in
        # such a way. i.e. [x, y, z, x, y, z, x, y, z, ..., ...] Create a
        # popup window that modifies the RTSTRUCT and tells the user that
        # processing is happening.
        connectSaveROIProgress(self, roi_list, self.dataset_rtss,
                               self.ROI_name, self.roi_saved)

    def roi_saved(self, new_rtss):
        """
            Function to call save ROI and display progress
        """
        self.signal_roi_drawn.emit((new_rtss, {"draw": self.ROI_name}))
        QMessageBox.about(self.draw_roi_window_instance, "Saved",
                          "New contour successfully created!")
        self.closeWindow()

    def onPreviewClicked(self):
        """
        function triggered when Preview button is clicked
        """
        if hasattr(self, 'drawingROI') and self.drawingROI and len(
                self.drawingROI.target_pixel_coords) > 0:
            alpha = float(self.input_alpha_value.text())
            polygon_list = calculate_concave_hull_of_points(
                self.drawingROI.target_pixel_coords, alpha)
            self.drawingROI.draw_contour_preview(polygon_list)
        else:
            QMessageBox.about(self.draw_roi_window_instance, "Not Enough Data",
                              "Please ensure you have drawn your ROI first.")

    def set_selected_roi_name(self, roi_name):
        """
        function to set selected roi name
        :param roi_name: roi name selected
        """
        roi_exists = False

        patient_dict_container = PatientDictContainer()
        existing_rois = patient_dict_container.get("rois")
        number_of_rois = len(existing_rois)

        # Check to see if the ROI already exists
        for key, value in existing_rois.items():
            if roi_name in value['name']:
                roi_exists = True

        if roi_exists:
            QMessageBox.about(self.draw_roi_window_instance,
                              "ROI already exists in RTSS",
                              "Would you like to continue?")

        self.ROI_name = roi_name
        self.roi_name_line_edit.setText(self.ROI_name)

    def onRadiusReduceClicked(self):
        """
        function triggered when user reduce cursor radius
        """
        self.drawing_tool_radius = max(self.drawing_tool_radius - 1, 4)
        self.draw_roi_window_cursor_radius_change_input.setText(
            str(self.drawing_tool_radius))
        self.draw_roi_window_cursor_radius_change_input.setCursorPosition(0)
        self.draw_cursor_when_radius_changed()

    def onRadiusIncreaseClicked(self):
        """
        function triggered when user increase cursor radius
        """
        self.drawing_tool_radius = min(self.drawing_tool_radius + 1, 25)
        self.draw_roi_window_cursor_radius_change_input.setText(
            str(self.drawing_tool_radius))
        self.draw_cursor_when_radius_changed()

    def draw_cursor_when_radius_changed(self):
        """
        function to update drawing cursor when radius changed
        """
        if self.drawingROI.cursor:
            self.drawingROI.draw_cursor(
                self.drawingROI.current_cursor_x + self.drawing_tool_radius,
                self.drawingROI.current_cursor_y + self.drawing_tool_radius,
                self.drawing_tool_radius)
        else:
            self.drawingROI.draw_cursor(
                (self.drawingROI.min_x + self.drawingROI.max_x) / 2,
                (self.drawingROI.min_y + self.drawingROI.max_y) / 2,
                self.drawing_tool_radius, True)

    def init_cursor_radius_change_box(self):
        """
        function to init cursor radius change box
        """
        # Create a horizontal box for containing the cursor radius changing
        # function
        self.draw_roi_window_cursor_radius_change_box = QHBoxLayout()
        self.draw_roi_window_cursor_radius_change_box.setObjectName(
            "DrawRoiWindowCursorRadiusChangeBox")
        # Create a label for cursor radius change
        self.draw_roi_window_cursor_radius_change_label = QLabel()
        self.draw_roi_window_cursor_radius_change_label.setObjectName(
            "DrawRoiWindowCursorRadiusChangeLabel")
        # Create an input box for cursor radius
        self.draw_roi_window_cursor_radius_change_input = QLineEdit()
        self.draw_roi_window_cursor_radius_change_input.setObjectName(
            "DrawRoiWindowCursorRadiusChangeInput")
        self.draw_roi_window_cursor_radius_change_input.setText(str(19))
        self.draw_roi_window_cursor_radius_change_input.setCursorPosition(0)
        self.draw_roi_window_cursor_radius_change_input.setEnabled(False)
        self.draw_roi_window_cursor_radius_change_input.setSizePolicy(
            QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.draw_roi_window_cursor_radius_change_input.resize(
            self.draw_roi_window_cursor_radius_change_input.sizeHint().width(),
            self.draw_roi_window_cursor_radius_change_input.sizeHint().height(
            ))
        # Create 2 buttons for increasing and reducing cursor radius
        # Increase Button
        self.draw_roi_window_cursor_radius_change_increase_button = \
            QPushButton()
        self.draw_roi_window_cursor_radius_change_increase_button. \
            setObjectName("DrawRoiWindowCursorRadiusIncreaseButton")
        self.draw_roi_window_cursor_radius_change_increase_button. \
            setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.draw_roi_window_cursor_radius_change_increase_button.resize(
            QSize(24, 24))
        self.draw_roi_window_cursor_radius_change_increase_button.setProperty(
            "QPushButtonClass", "zoom-button")
        icon_zoom_in = QtGui.QIcon()
        icon_zoom_in.addPixmap(
            QtGui.QPixmap(
                resource_path('res/images/btn-icons/zoom_in_icon.png')))
        self.draw_roi_window_cursor_radius_change_increase_button.setIcon(
            icon_zoom_in)
        self.draw_roi_window_cursor_radius_change_increase_button.clicked. \
            connect(self.onRadiusIncreaseClicked)
        # Reduce Button
        self.draw_roi_window_cursor_radius_change_reduce_button = QPushButton()
        self.draw_roi_window_cursor_radius_change_reduce_button.setObjectName(
            "DrawRoiWindowCursorRadiusReduceButton")
        self.draw_roi_window_cursor_radius_change_reduce_button.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.draw_roi_window_cursor_radius_change_reduce_button.resize(
            QSize(24, 24))
        self.draw_roi_window_cursor_radius_change_reduce_button.setProperty(
            "QPushButtonClass", "zoom-button")
        icon_zoom_out = QtGui.QIcon()
        icon_zoom_out.addPixmap(
            QtGui.QPixmap(
                resource_path('res/images/btn-icons/zoom_out_icon.png')))
        self.draw_roi_window_cursor_radius_change_reduce_button.setIcon(
            icon_zoom_out)
        self.draw_roi_window_cursor_radius_change_reduce_button.clicked. \
            connect(self.onRadiusReduceClicked)
        self.draw_roi_window_cursor_radius_change_box.addWidget(
            self.draw_roi_window_cursor_radius_change_label)
        self.draw_roi_window_cursor_radius_change_box.addWidget(
            self.draw_roi_window_cursor_radius_change_input)
        self.draw_roi_window_cursor_radius_change_box.addWidget(
            self.draw_roi_window_cursor_radius_change_reduce_button)
        self.draw_roi_window_cursor_radius_change_box.addWidget(
            self.draw_roi_window_cursor_radius_change_increase_button)
        self.draw_roi_window_input_container_box.addRow(
            self.draw_roi_window_cursor_radius_change_box)
        self.draw_roi_window_cursor_radius_change_increase_button.setEnabled(
            False)
        self.draw_roi_window_cursor_radius_change_reduce_button.setEnabled(
            False)

    def disable_cursor_radius_change_box(self):
        """
        function  to disable cursor radius change box
        """
        self.draw_roi_window_cursor_radius_change_reduce_button.setEnabled(
            False)
        self.draw_roi_window_cursor_radius_change_increase_button.setEnabled(
            False)
        self.toggle_keep_empty_pixel_combo_box.setEnabled(False)

    def enable_cursor_radius_change_box(self):
        """
        function  to enable cursor radius change box
        """
        self.draw_roi_window_cursor_radius_change_reduce_button.setEnabled(
            True)
        self.draw_roi_window_cursor_radius_change_increase_button.setEnabled(
            True)
        self.toggle_keep_empty_pixel_combo_box.setEnabled(True)

    def closeWindow(self):
        """
        function to close draw roi window
        """
        self.drawn_roi_list = {}
        if hasattr(self, 'bounds_box_draw'):
            delattr(self, 'bounds_box_draw')
        if hasattr(self, 'drawingROI'):
            delattr(self, 'drawingROI')
        self.ds = None
        self.close()
Beispiel #16
0
class ImageManipulation(QWidget):
    def __init__(self, img):
        super().__init__()

        # Declare Widgets
        self.edit_label = QLabel('Change your image')

        # set up list and combo box option
        self.my_list = [
            "Pick a value", "Luminosity", "Contrast", "Colorize", "Sepia",
            "Negative", "Grayscale", "None"
        ]
        self.my_combo_box = QComboBox()
        self.my_combo_box.addItems(self.my_list)

        self.edit_btn = QPushButton("Edit")

        # Create U.I. Layout
        mbox = QHBoxLayout()

        vbox = QVBoxLayout()
        vbox.addWidget(self.edit_label)
        vbox.addWidget(self.my_combo_box)
        vbox.addWidget(self.edit_btn)

        mbox.addLayout(vbox)
        image = Image.open(requests.get(img['urls']['thumb'], stream=True).raw)
        editpath = "./editing/edit.jpg"
        image.save(editpath)
        self.lbl = QLabel()
        pix = QPixmap(editpath)
        self.lbl.setPixmap(pix)
        mbox.addWidget(self.lbl)

        self.setLayout(mbox)  # apply layout to this class

        # when button is clicked send lineedit and combo box info to on_submit
        self.edit_btn.clicked.connect(self.on_edit)

    @Slot()
    def on_edit(self):

        # set up im_edit as which filter the user chose
        im_edit = self.my_combo_box.currentText()

        # take the image to edit and load it
        input_image = Image.open("./editing/edit.jpg")
        input_pixels = input_image.load()

        output_image = Image.new("RGB", input_image.size)
        draw = ImageDraw.Draw(output_image)

        # Options are: ["Pick a value", "Luminosity", "Contrast", "Colorize", "Sepia", "Negative", "Grayscale", "None"]
        # Luminostity brightens the image overall
        if (im_edit == "Luminosity"):
            luminosity = 80

            # Generate image
            for x in range(output_image.width):
                for y in range(output_image.height):
                    r, g, b = input_pixels[x, y]
                    r = int(r + luminosity)
                    g = int(g + luminosity)
                    b = int(b + luminosity)
                    draw.point((x, y), (r, g, b))

            output_image.show()
        # Contrast makes the image slightly darker overall
        elif (im_edit == "Contrast"):
            # Find minimum and maximum luminosity
            imin = 255
            imax = 0
            for x in range(input_image.width):
                for y in range(input_image.height):
                    r, g, b = input_pixels[x, y]
                    i = (r + g + b) / 3
                    imin = min(imin, i)
                    imax = max(imax, i)

            # Generate image
            for x in range(output_image.width):
                for y in range(output_image.height):
                    r, g, b = input_pixels[x, y]
                    # Current luminosity
                    i = (r + g + b) / 3
                    # New luminosity
                    ip = 255 * (i - imin) / (imax - imin)
                    r = int(r * ip / i)
                    g = int(g * ip / i)
                    b = int(b * ip / i)
                    draw.point((x, y), (r, g, b))

            output_image.show()
        # Colorize increases one color in the image
        elif (im_edit == "Colorize"):
            # Square distance between 2 colors
            def distance2(color1, color2):
                r1, g1, b1 = color1
                r2, g2, b2 = color2
                return (r1 - r2)**2 + (g1 - g2)**2 + (b1 - b2)**2

            color_to_change = (0, 0, 255)
            threshold = 220

            # Generate image
            for x in range(output_image.width):
                for y in range(output_image.height):
                    r, g, b = input_pixels[x, y]
                    if distance2(color_to_change,
                                 input_pixels[x, y]) < threshold**2:
                        r = int(r * .5)
                        g = int(g * 1.25)
                        b = int(b * .5)
                    draw.point((x, y), (r, g, b))

            output_image.show()
        # Sepia increases the red and decreases the blue value depending on the intensity
        elif (im_edit == "Sepia"):

            def sepia(pixel):
                if pixel[0] < 63:
                    r, g, b = int(pixel[0] * 1.1), pixel[1], int(pixel[2] * .9)
                elif pixel[0] > 62 and pixel[0] < 192:
                    r, g, b = int(pixel[0] * 1.15), pixel[1], int(pixel[2] *
                                                                  .85)
                else:
                    r = int(pixel[0] * 1.08)
                    if r > 255: r = 255
                    g, b = pixel[1], pixel[2] // 2
                return r, g, b

            sepia_list = map(sepia, input_image.getdata())
            output_image.putdata(list(sepia_list))
            output_image.show()
        # Negative swaps the rgb values to their opposite counterparts
        elif (im_edit == "Negative"):
            negative_list = [(255 - p[0], 255 - p[1], 255 - p[2])
                             for p in input_image.getdata()]
            output_image.putdata(negative_list)
            output_image.show()
        # Grayscale averages the rgb values and creates the gray version of the image
        elif (im_edit == "Grayscale"):
            new_list = [((a[0] + a[1] + a[2]) // 3, ) * 3
                        for a in input_image.getdata()]
            output_image.putdata(new_list)
            output_image.show()
        else:  #"Pick a value" or "None"
            input_image.show()
Beispiel #17
0
 def createEditor(self, parent, option, index):
     editor = QComboBox(parent)
     editor.addItems(channel_types)
     editor.currentIndexChanged.connect(self.commit_data)
     return editor
Beispiel #18
0
 def startTable(self):
     for col in range(self.Tabela.columnCount()):
         combo = QComboBox()
         combo.addItems(["Selecionar","Data & Hora","Prec. Observada","Data","Hora","Nível do Rio"])
         self.Tabela.setCellWidget(0, col, combo)
Beispiel #19
0
class RunICADialog(QDialog):
    def __init__(self, parent, nchan, methods):
        super().__init__(parent)
        self.setWindowTitle("Run ICA")

        vbox = QVBoxLayout(self)
        grid = QGridLayout()
        grid.addWidget(QLabel("Method:"), 0, 0)
        self.method = QComboBox()
        self.method.addItems(methods)
        self.method.setCurrentIndex(0)
        self.method.currentIndexChanged.connect(self.toggle_options)
        grid.addWidget(self.method, 0, 1)

        self.extended_label = QLabel("Extended:")
        grid.addWidget(self.extended_label, 1, 0)
        self.extended = QCheckBox()
        self.extended.setChecked(True)
        grid.addWidget(self.extended, 1, 1)

        self.ortho_label = QLabel("Orthogonal:")
        grid.addWidget(self.ortho_label, 2, 0)
        self.ortho = QCheckBox()
        self.ortho.setChecked(False)
        grid.addWidget(self.ortho, 2, 1)
        if "Picard" not in methods:
            self.ortho_label.hide()
            self.ortho.hide()

        grid.addWidget(QLabel("Number of components:"), 3, 0)
        self.n_components = QSpinBox()
        self.n_components.setRange(0, nchan)
        self.n_components.setValue(nchan)
        self.n_components.setAlignment(Qt.AlignRight)
        grid.addWidget(self.n_components, 3, 1)

        grid.addWidget(QLabel("Exclude bad segments:"), 4, 0)
        self.exclude_bad_segments = QCheckBox()
        self.exclude_bad_segments.setChecked(True)
        grid.addWidget(self.exclude_bad_segments, 4, 1)

        vbox.addLayout(grid)

        buttonbox = QDialogButtonBox(QDialogButtonBox.Ok
                                     | QDialogButtonBox.Cancel)
        vbox.addWidget(buttonbox)
        buttonbox.accepted.connect(self.accept)
        buttonbox.rejected.connect(self.reject)
        vbox.setSizeConstraint(QVBoxLayout.SetFixedSize)

        self.toggle_options()

    @Slot()
    def toggle_options(self):
        """Toggle extended options."""
        if self.method.currentText() == "Picard":  # enable extended and ortho
            self.extended_label.setEnabled(True)
            self.extended.setEnabled(True)
            self.ortho_label.setEnabled(True)
            self.ortho.setEnabled(True)
        elif self.method.currentText() == "Infomax":  # enable extended
            self.extended_label.setEnabled(True)
            self.extended.setEnabled(True)
            self.ortho_label.setEnabled(False)
            self.ortho.setChecked(False)
            self.ortho.setEnabled(False)
        else:
            self.extended_label.setEnabled(False)
            self.extended.setChecked(False)
            self.extended.setEnabled(False)
            self.ortho_label.setEnabled(False)
            self.ortho.setChecked(False)
            self.ortho.setEnabled(False)
Beispiel #20
0
class PredictionWindow(QWidget):
    """Subwindow dedicated to random forest prediction functions."""

    # Private Instance Attributes:
    # - _predict_btn: Button that signals for a prediction to be made.
    # - _predict_btn: Button that signals for the selected model to be deleted.
    # - _model: The RandomForest model currently loaded.
    # - _model_info: QPlainTextEdit widget displaying information about the selected model.
    # - _target_date: Calendar widget for the user to select a target prediction date.
    # -_plot_window: Window for displaying historical information with a prediction.
    _predict_btn: QDialogButtonBox
    _delete_btn: QDialogButtonBox
    _model: QComboBox
    _model_info: QPlainTextEdit
    _target_date: QCalendarWidget
    _plot_window: QMainWindow

    def __init__(self) -> None:
        super().__init__()

        main_layout = QGridLayout()
        button_box = self._create_button_box()
        main_layout.addWidget(self._create_options_group_box(), 0, 0)
        main_layout.addWidget(button_box, 1, 0)

        main_layout.setSizeConstraint(QLayout.SetMinimumSize)

        self.setLayout(main_layout)

        self._refresh_model_info()
        self.setWindowTitle('Predict')
        self._plot_window = QMainWindow()

    def show(self) -> None:
        """Override of QWidget's show() function.

        Refreshes window and then shows the window.
        """
        self._refresh_lists()
        return super().show()

    @property
    def _selected_model(self) -> Union[RandomForest, None]:
        """Gets the currently selected model."""
        model_name = self._model.currentText()
        if model_name != '':
            try:
                return load_model(model_name)
            except pickle.UnpicklingError:
                self._error_event(f'{model_name} is an invalid model.')
                return None
        else:
            return None

    def _create_button_box(self) -> QDialogButtonBox:
        """Creates the lower control buttons at the bottom of the window."""
        button_box = QDialogButtonBox()

        self._predict_btn = button_box.addButton('Predict',
                                                 QDialogButtonBox.ActionRole)
        self._delete_btn = button_box.addButton('Delete Model',
                                                QDialogButtonBox.ActionRole)
        refresh_btn = button_box.addButton('Refresh &Options',
                                           QDialogButtonBox.ActionRole)

        self._predict_btn.clicked.connect(self._predict)
        refresh_btn.clicked.connect(self._refresh_lists)
        self._delete_btn.clicked.connect(self._delete)

        return button_box

    def _create_options_group_box(self) -> QGroupBox:
        """Returns the group of prediction options."""
        options_group_box = QGroupBox("Options")

        options_layout = QGridLayout()
        left_options = QGridLayout()
        right_options = QGridLayout()

        date_label = QLabel("Target Date:")
        self._target_date = QCalendarWidget()

        left_options.addWidget(date_label, 0, 0)
        left_options.addWidget(self._target_date, 1, 0, 1, 3)

        left_options.setColumnStretch(0, 1)

        self._model = QComboBox()
        self._model_info = QPlainTextEdit()
        self._model_info.setReadOnly(True)

        self._model.currentTextChanged.connect(self._refresh_model_info)

        self._refresh_lists()

        models_label = QLabel("Models:")
        info_label = QLabel("Model Information:")

        right_options.addWidget(models_label, 0, 0)
        right_options.addWidget(self._model, 1, 0)

        right_options.addWidget(info_label, 2, 0)
        right_options.addWidget(self._model_info, 3, 0)

        options_layout.addLayout(left_options, 0, 0)
        options_layout.addLayout(right_options, 0, 1)

        options_group_box.setLayout(options_layout)

        return options_group_box

    def _delete(self) -> None:
        """Deletes the currently selected dataset."""
        self.setEnabled(False)
        name = self._model.currentText()

        warning = f'Are you sure you want to delete {name}?'

        response = QMessageBox.warning(self, self.tr("Delete Model"), warning,
                                       QMessageBox.Yes, QMessageBox.No)

        if response == QMessageBox.Yes:
            data_ingest.delete_data(name, file_type='model')
            self._refresh_lists()

        self.setEnabled(True)

    def _refresh_lists(self) -> None:
        """Refreshes avaliable datasets for training."""
        self._model.clear()

        data_list = data_ingest.get_avaliable_data(search_type='model')

        self._model.addItems(data_list)

    def _refresh_model_info(self) -> None:
        """Refreshes avaliable features for the selected target."""
        self._predict_btn.setEnabled(False)
        self._target_date.setEnabled(False)
        self._model_info.clear()

        model_name = self._model.currentText()

        model = self._selected_model
        if model is None:
            self._delete_btn.setEnabled(False)
            return None

        self._delete_btn.setEnabled(True)

        self._display_model_info(model)

        req_features = model.window.req_features

        avaliable_sym = data_ingest.get_avaliable_sym()

        if len(req_features - avaliable_sym) != 0:
            self._error_event(
                f'Missing required data for {model_name}: {req_features - avaliable_sym}'
            )
            return None

        dfs = load_corresponding_dataframes(model)
        grouped_dataframe = data_ingest.create_grouped_dataframe(dfs)

        date_offset = pd.DateOffset(days=model.window.target_shift)

        self._target_date.setMaximumDate(grouped_dataframe.index.max() +
                                         date_offset)
        self._target_date.setMinimumDate(grouped_dataframe.index.min() +
                                         date_offset)

        self._target_date.setEnabled(True)
        self._predict_btn.setEnabled(True)

        return None

    def _display_model_info(self, model: RandomForest) -> None:
        """Updates model info box to display current model's information."""
        self._model_info.appendPlainText(
            f'Target Feature Name: \n{model.window.target_lbl}')
        self._model_info.appendPlainText('Window Information:')
        self._model_info.appendPlainText(
            f'\t- Window Size: {model.window.window_size}')
        self._model_info.appendPlainText(
            f'\t- Target Shift: {model.window.target_shift}')
        self._model_info.appendPlainText(
            f'\t- Required Features: {model.window.req_features}')
        self._model_info.appendPlainText('Forest Information:')
        self._model_info.appendPlainText(
            f'\t- Number of Trees: {model.forest.n_trees}')
        self._model_info.appendPlainText(
            f'\t- Tree Max Depth: {model.forest.max_depth}')
        self._model_info.appendPlainText(f'\t- Seed: {model.forest.seed}')

    def _predict(self) -> None:
        """Creates a model prediction using the selected target date and model."""
        self.setEnabled(False)
        self._predict_btn.setEnabled(False)
        model = self._selected_model
        if model is None:
            self.setEnabled(True)
            return None

        target_date = self._target_date.selectedDate().toPython()

        try:
            dfs = load_corresponding_dataframes(model)
            prediction_input = data_ingest.create_input(
                model.window.window_size, model.window.target_shift,
                target_date, dfs)
        except ce.MissingData:
            self._error_event(
                'Missing required data. Could be that loaded datasets have holes.'
            )
            self.setEnabled(True)
            return None

        prediction = model.predict(prediction_input)

        historical_dfs = load_corresponding_dataframes(model, 'target')
        if len(historical_dfs) == 0:
            self._prediction_historical_error(prediction)
        else:
            self._plot_prediction(historical_dfs, model, prediction,
                                  target_date)

        self._predict_btn.setEnabled(True)
        self.setEnabled(True)
        return None

    def _plot_prediction(self, historical_dfs: list[pd.DataFrame],
                         model: RandomForest, prediction: ndarray,
                         target_date: datetime.date) -> None:
        """Opens a window with a plot of the historical target data as well as the prediction
        the model made."""
        hdf = historical_dfs[0]
        for frame in historical_dfs[1:]:
            hdf = hdf.combine_first(frame)
        window_end = target_date - \
            pd.DateOffset(days=model.window.target_shift)
        window_start = window_end - pd.DateOffset(days=30 - 1)
        hdf = pd.Series(
            hdf.loc[window_end:window_start][model.window.target_lbl])

        hdf_data = hdf.to_list()
        hdf_dates = hdf.index

        hdf_dates = [ts.to_pydatetime().timestamp() for ts in hdf_dates]

        b_axis = pg.DateAxisItem(orientation='bottom')
        b_axis.setLabel('Date')
        plot = PlotWidget(axisItems={'bottom': b_axis})

        target_time = datetime.combine(target_date, datetime.min.time())

        plot.addLegend()
        plot.plot(x=hdf_dates,
                  y=hdf_data,
                  name=f'Historical {model.window.target_lbl}')
        plot.plot(x=[target_time.timestamp()],
                  y=prediction,
                  pen=None,
                  symbol='o',
                  name=f'Predicted Value: {prediction[0]}')
        model_name = self._model.currentText()
        self._plot_window.setWindowTitle(f'{model_name} Prediction')
        self._plot_window.setCentralWidget(plot)
        self._plot_window.show()

    def _prediction_historical_error(self, prediction: list) -> None:
        """Displays a message for when historical target is unavalable such that
        a graph can't be made."""
        QMessageBox.information(
            self, self.tr("Information"), f'Prediction was: {prediction}. \n '
            'Unable to display graph due to missing historical data.',
            QtWidgets.QMessageBox.Ok)

    def _error_event(
        self,
        error: str,
        choice: bool = False,
        btn: QMessageBox = QMessageBox.Abort
    ) -> Union[QMessageBox.Ignore, QMessageBox.Abort, None]:
        """Displays an error message with the given error."""
        if choice:
            response = QMessageBox.critical(self, self.tr("Error"), error, btn,
                                            QMessageBox.Ignore)
            return response
        else:
            QMessageBox.critical(self, self.tr("Error"), error, QMessageBox.Ok)
            return None
class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.init_ui()

        self.combobox.currentTextChanged.connect(self.slot_combo_textchanged)
        self.btn_open_conn.clicked.connect(self.slot_conn_clicked)
        self.btn_close_conn.clicked.connect(self.slot_conn_close)
        self.btn_status.clicked.connect(self.slot_send_status_packet)
        self.btn_head.clicked.connect(self.slot_send_head_packet)
        self.btn_motion.clicked.connect(self.slof_send_motion_packet)

    def slot_conn_close(self):
        #TODO 关闭其他窗口
        self.fd.close()
        self.set_send_btn_statu(False)

    def slot_send_status_packet(self):
        statuswidget = StatusWidget(self.fd)
        statuswidget.show()

    def slot_send_head_packet(self):
        headwidget = HeadWidget(self.fd)
        headwidget.show()

    def slof_send_motion_packet(self):
        motionwidget = MotionWidget(self.fd)
        motionwidget.show()
        pass

    def init_ui(self):
        self.tuple_method = ("Connect to Server", "Connect to /dev")
        self.combobox = QComboBox()
        self.combobox.addItems(self.tuple_method)
        self.addr_edit = QLineEdit()
        self.port_edit = QLineEdit()
        self.btn_open_conn = QPushButton("Connect/Open")
        self.btn_close_conn = QPushButton("Close Conn")
        self.fd = None
        self.method_layout = QVBoxLayout()
        self.method_layout.addWidget(self.combobox)
        self.method_layout.addWidget(self.addr_edit)
        self.method_layout.addWidget(self.port_edit)
        self.method_layout.addWidget(self.btn_open_conn)
        self.method_layout.addWidget(self.btn_close_conn)
        self.btn_status = QPushButton("Send Status Packet")
        self.btn_head = QPushButton("Send Head Packet")
        self.btn_motion = QPushButton("Send Motion Packet")
        self.packet_layout = QVBoxLayout()
        self.packet_layout.addWidget(self.btn_status)
        self.packet_layout.addWidget(self.btn_head)
        self.packet_layout.addWidget(self.btn_motion)
        self.main_layout = QVBoxLayout()
        self.main_layout.addLayout(self.method_layout)
        self.main_layout.addLayout(self.packet_layout)
        self.setLayout(self.main_layout)
        self.set_send_btn_statu(False)

    def set_send_btn_statu(self, statu):
        self.btn_motion.setEnabled(statu)
        self.btn_head.setEnabled(statu)
        self.btn_status.setEnabled(statu)
        self.btn_close_conn.setEnabled(statu)
        self.btn_open_conn.setEnabled(True if statu == False else False)

    def slot_combo_textchanged(self, current_text):
        if current_text == "Connect to /dev":
            self.port_edit.setVisible(False)
        else:
            self.port_edit.setVisible(True)

    def slot_conn_clicked(self):
        # try:
        if self.combobox.currentText() == "Connect to /dev":
            self.fd = open(self.addr_edit.text(), "wb")

        elif self.combobox.currentText() == "Connect to Server":
            self.fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.fd.connect(("127.0.0.1", int(self.port_edit.text())))
        # except :
        #     pass

        # TODO except

        QMessageBox.information(self, "success", "connected")
        self.set_send_btn_statu(True)
Beispiel #22
0
class SetQuotaDiskWidget(QWidget):
    Sg_view_changed = Signal()

    def __init__(self, model: SettingsModel, parent=None):
        super(SetQuotaDiskWidget, self).__init__(parent)

        self._model = model

        self.setAccessibleName("InfoBox")

        self.title = QLabel()
        self.title.setText("Spazio di archiviazione")
        self.title.setAccessibleName("Title2")

        self.sottotitolo = QLabel()
        self.sottotitolo.setAccessibleName('Sottotitolo')
        self.sottotitolo.setText(
            "Cambia lo spazio di archiviazione destinato alla cartella sincronizzata"
        )

        # Barra riempimento disco
        self.progress_label = QLabel()
        self.progress_label.setText("Spazio occupato:")

        self.disk_progress = QProgressBar()
        self.disk_progress.setFormat("")

        self.disk_quota = QLabel()

        # Modifica spazio dedicato
        self.spaceLabel = QLabel(" ")

        self.dedicated_space = QLineEdit()
        self.dedicated_space.setValidator(QDoubleValidator())

        self.sizes_box = QComboBox()
        self.sizes_box.wheelEvent = lambda event: None
        _path_size = bitmath.parse_string(model.convert_size(model.get_size()))
        _disk_free = bitmath.parse_string(
            model.convert_size(model.get_free_disk()))

        self.populate_size_box(_path_size, _disk_free)

        self.change_quota_button = QPushButton("Cambia quota disco")
        self.change_quota_button.setMaximumWidth(150)

        self.change_quota_button.clicked.connect(
            self.Sl_dedicated_space_changed)
        self.dedicated_space.returnPressed.connect(
            self.Sl_dedicated_space_changed)

        self.buttonLayout = QHBoxLayout()
        self.buttonLayout.addWidget(self.spaceLabel)
        self.buttonLayout.addWidget(self.change_quota_button)
        self.buttonLayout.addWidget(self.spaceLabel)

        set_space_layout = QHBoxLayout()
        set_space_layout.addWidget(self.dedicated_space)
        set_space_layout.addWidget(self.sizes_box)

        quota_layout = QHBoxLayout()
        quota_layout.setAlignment(Qt.AlignLeft)
        quota_layout.addWidget(self.progress_label)
        quota_layout.addWidget(self.disk_quota)

        # layout
        disk_layout = QVBoxLayout()
        disk_layout.setAlignment(Qt.AlignLeft)
        disk_layout.addWidget(self.title)
        disk_layout.addWidget(self.sottotitolo)
        disk_layout.addWidget(self.spaceLabel)
        disk_layout.addLayout(quota_layout)
        disk_layout.addWidget(self.disk_progress)
        disk_layout.addWidget(self.spaceLabel)
        disk_layout.addLayout(set_space_layout)
        disk_layout.addLayout(self.buttonLayout)

        self.setLayout(disk_layout)
        self.Sl_model_changed()

    @Slot()
    def Sl_dedicated_space_changed(self):
        self.Sg_view_changed.emit()

    @Slot()
    def Sl_model_changed(self):
        """
        Slot collegato ai segnali del model, aggiorna la vista con i nuovi valori
        :return: None
        """

        # Prendo quota disco con unità e il peso della cartella senza unità (Byte default)
        new_max_quota = self._model.get_quota_disco()
        _folder_size = self._model.get_size()

        # Converto ad oggetto bitmath il peso della cartella e la quota disco
        folder_size_parsed = bitmath.parse_string(
            self._model.convert_size(_folder_size))
        quota_disco_parsed = bitmath.parse_string(new_max_quota)

        # Imposto la textbox che mi dice quanto peso ho occupato su quello disponibile
        self.disk_quota.setText(
            f"{folder_size_parsed} su {new_max_quota} in uso")

        free_disk_parsed = bitmath.parse_string(
            self._model.convert_size(self._model.get_free_disk()))

        # Imposto la textbox che richiede input
        if not self.dedicated_space.hasFocus():
            self.dedicated_space.setText(str(quota_disco_parsed.value))
            # Creo i nuovi valori della combobox
            if not self.sizes_box.hasFocus():
                self.populate_size_box(folder_size_parsed, free_disk_parsed)
                # Imposto l'item in focus della combobox
                self.sizes_box.setCurrentText(quota_disco_parsed.unit)

        # Prendo dimensione corrente della sync folder e della quota disco
        # e metto in proporzione con quotadisco:100=syncfolder:x
        _progress_bar_max_value = 100
        _tmp = folder_size_parsed.to_Byte().value * _progress_bar_max_value
        _progress_bar_current_percentage = _tmp / quota_disco_parsed.to_Byte(
        ).value

        # Inserisco nuovi valori nella progress bar
        self.disk_progress.setRange(0, _progress_bar_max_value)
        self.disk_progress.setValue(_progress_bar_current_percentage)

        # Se la cartella occupa più spazio di quanto voluto allora la porto a quanto occupa
        if quota_disco_parsed < folder_size_parsed and not self.dedicated_space.hasFocus(
        ):
            self.dedicated_space.setText(str(folder_size_parsed.value))
            self.sizes_box.setCurrentText(folder_size_parsed.unit)
            self.Sg_view_changed.emit()

    def populate_size_box(
        self,
        _min: str,
        _max: str,
    ) -> None:
        """
        This method populates the size box with only the available units
        ex hdd has only <1gb so gb will not be used, the current folder is
        heavier than 1mb so kb will not be used.
        :param _min: minimum value with unit ex 10 KiB or just 'KiB'
        :param _max: maximum value with unit ex 10 KiB or just 'KiB'
        :return: None
        """
        _sizes = "Byte", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"
        # Converto in ogni caso a string, in caso in cui venga passato un oggetto
        # tipo bitmath

        _min = str(_min)
        _max = str(_max)

        # Rimuovo eventuali numeri e caratteri extra, tengo solo l'unità di misura
        _min = ''.join(i for i in _min if not i.isdigit() and i != '.')
        _max = ''.join(i for i in _max if not i.isdigit() and i != '.')

        # Rimuovo possibili spazi ad inizio e fine stringa
        _min = _min.strip()
        _max = _max.strip()

        # Rimuovo dal vettore di possibili unità di misura tutte le unità sotto il lower bound
        lower_bound = _sizes[_sizes.index(_min):]
        # Rimuovo dal vettore di possibili unità di misura tutte le unità sopra l'upper bound
        upper_bound = lower_bound[:lower_bound.index(_max) + 1]

        # Pulisco il vecchio combo box
        self.sizes_box.clear()

        # Inserisco nuovi valori
        self.sizes_box.addItems(upper_bound)
Beispiel #23
0
class ApplicationWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)

        self.column_names = ["Column A", "Column B", "Column C"]

        # Central widget
        self._main = QWidget()
        self.setCentralWidget(self._main)

        # Main menu bar
        self.menu = self.menuBar()
        self.menu_file = self.menu.addMenu("File")
        exit = QAction("Exit", self, triggered=qApp.quit)
        self.menu_file.addAction(exit)

        self.menu_about = self.menu.addMenu("&About")
        about = QAction("About Qt",
                        self,
                        shortcut=QKeySequence(QKeySequence.HelpContents),
                        triggered=qApp.aboutQt)
        self.menu_about.addAction(about)

        # Figure (Left)
        self.fig = Figure(figsize=(5, 3))
        self.canvas = FigureCanvas(self.fig)

        # Sliders (Left)
        self.slider_azim = QSlider(minimum=0,
                                   maximum=360,
                                   orientation=Qt.Horizontal)
        self.slider_elev = QSlider(minimum=0,
                                   maximum=360,
                                   orientation=Qt.Horizontal)

        self.slider_azim_layout = QHBoxLayout()
        self.slider_azim_layout.addWidget(
            QLabel("{}".format(self.slider_azim.minimum())))
        self.slider_azim_layout.addWidget(self.slider_azim)
        self.slider_azim_layout.addWidget(
            QLabel("{}".format(self.slider_azim.maximum())))

        self.slider_elev_layout = QHBoxLayout()
        self.slider_elev_layout.addWidget(
            QLabel("{}".format(self.slider_elev.minimum())))
        self.slider_elev_layout.addWidget(self.slider_elev)
        self.slider_elev_layout.addWidget(
            QLabel("{}".format(self.slider_elev.maximum())))

        # Table (Right)
        self.table = QTableWidget()
        header = self.table.horizontalHeader()
        header.setSectionResizeMode(QHeaderView.Stretch)

        # ComboBox (Right)
        self.combo = QComboBox()
        self.combo.addItems(
            ["Wired", "Surface", "Triangular Surface", "Sphere"])

        # Right layout
        rlayout = QVBoxLayout()
        rlayout.setContentsMargins(1, 1, 1, 1)
        rlayout.addWidget(QLabel("Plot type:"))
        rlayout.addWidget(self.combo)
        rlayout.addWidget(self.table)

        # Left layout
        llayout = QVBoxLayout()
        rlayout.setContentsMargins(1, 1, 1, 1)
        llayout.addWidget(self.canvas, 88)
        llayout.addWidget(QLabel("Azimuth:"), 1)
        llayout.addLayout(self.slider_azim_layout, 5)
        llayout.addWidget(QLabel("Elevation:"), 1)
        llayout.addLayout(self.slider_elev_layout, 5)

        # Main layout
        layout = QHBoxLayout(self._main)
        layout.addLayout(llayout, 70)
        layout.addLayout(rlayout, 30)

        # Signal and Slots connections
        self.combo.currentTextChanged.connect(self.combo_option)
        self.slider_azim.valueChanged.connect(self.rotate_azim)
        self.slider_elev.valueChanged.connect(self.rotate_elev)

        # Initial setup
        self.plot_wire()
        self._ax.view_init(30, 30)
        self.slider_azim.setValue(30)
        self.slider_elev.setValue(30)
        self.fig.canvas.mpl_connect("button_release_event", self.on_click)

    # Matplotlib slot method
    def on_click(self, event):
        azim, elev = self._ax.azim, self._ax.elev
        self.slider_azim.setValue(azim + 180)
        self.slider_elev.setValue(elev + 180)

    # Utils methods

    def set_table_data(self, X, Y, Z):
        for i in range(len(X)):
            self.table.setItem(i, 0, QTableWidgetItem("{:.2f}".format(X[i])))
            self.table.setItem(i, 1, QTableWidgetItem("{:.2f}".format(Y[i])))
            self.table.setItem(i, 2, QTableWidgetItem("{:.2f}".format(Z[i])))

    def set_canvas_table_configuration(self, row_count, data):
        self.fig.set_canvas(self.canvas)
        self._ax = self.canvas.figure.add_subplot(projection="3d")

        self._ax.set_xlabel(self.column_names[0])
        self._ax.set_ylabel(self.column_names[1])
        self._ax.set_zlabel(self.column_names[2])

        self.table.setRowCount(row_count)
        self.table.setColumnCount(3)
        self.table.setHorizontalHeaderLabels(self.column_names)
        self.set_table_data(data[0], data[1], data[2])

    # Plot methods

    def plot_wire(self):
        # Data
        self.X, self.Y, self.Z = axes3d.get_test_data(0.03)

        self.set_canvas_table_configuration(len(self.X[0]),
                                            (self.X[0], self.Y[0], self.Z[0]))
        self._ax.plot_wireframe(self.X,
                                self.Y,
                                self.Z,
                                rstride=10,
                                cstride=10,
                                cmap="viridis")
        self.canvas.draw()

    def plot_surface(self):
        # Data
        self.X, self.Y = np.meshgrid(np.linspace(-6, 6, 30),
                                     np.linspace(-6, 6, 30))
        self.Z = np.sin(np.sqrt(self.X**2 + self.Y**2))

        self.set_canvas_table_configuration(len(self.X[0]),
                                            (self.X[0], self.Y[0], self.Z[0]))
        self._ax.plot_surface(self.X,
                              self.Y,
                              self.Z,
                              rstride=1,
                              cstride=1,
                              cmap="viridis",
                              edgecolor="none")
        self.canvas.draw()

    def plot_triangular_surface(self):
        # Data
        radii = np.linspace(0.125, 1.0, 8)
        angles = np.linspace(0, 2 * np.pi, 36, endpoint=False)[..., np.newaxis]
        self.X = np.append(0, (radii * np.cos(angles)).flatten())
        self.Y = np.append(0, (radii * np.sin(angles)).flatten())
        self.Z = np.sin(-self.X * self.Y)

        self.set_canvas_table_configuration(len(self.X),
                                            (self.X, self.Y, self.Z))
        self._ax.plot_trisurf(self.X,
                              self.Y,
                              self.Z,
                              linewidth=0.2,
                              antialiased=True)
        self.canvas.draw()

    def plot_sphere(self):
        # Data
        u = np.linspace(0, 2 * np.pi, 100)
        v = np.linspace(0, np.pi, 100)
        self.X = 10 * np.outer(np.cos(u), np.sin(v))
        self.Y = 10 * np.outer(np.sin(u), np.sin(v))
        self.Z = 9 * np.outer(np.ones(np.size(u)), np.cos(v))

        self.set_canvas_table_configuration(len(self.X),
                                            (self.X[0], self.Y[0], self.Z[0]))
        self._ax.plot_surface(self.X, self.Y, self.Z)
        self.canvas.draw()

    # Slots

    @Slot()
    def combo_option(self, text):
        if text == "Wired":
            self.plot_wire()
        elif text == "Surface":
            self.plot_surface()
        elif text == "Triangular Surface":
            self.plot_triangular_surface()
        elif text == "Sphere":
            self.plot_sphere()

    @Slot()
    def rotate_azim(self, value):
        self._ax.view_init(self._ax.elev, value)
        self.fig.set_canvas(self.canvas)
        self.canvas.draw()

    @Slot()
    def rotate_elev(self, value):
        self._ax.view_init(value, self._ax.azim)
        self.fig.set_canvas(self.canvas)
        self.canvas.draw()
Beispiel #24
0
class ImageManipulation(QWidget):
    def __init__(self):
        super().__init__()

        # Declare Widgets
        self.edit_label = QLabel('Change your image')

        # set up list and combo box option
        self.my_list = ["Pick a value", "Luminosity", "Contrast", "Colorize", "Sepia", "Negative", "Grayscale", "None"]
        self.my_combo_box = QComboBox()
        self.my_combo_box.addItems(self.my_list)

        self.edit_btn = QPushButton("Edit")
        self.cancel_btn = QPushButton("Back")

        # Create U.I. Layout
        vbox = QVBoxLayout()
        vbox.addWidget(self.edit_label)
        vbox.addWidget(self.my_combo_box)
        vbox.addWidget(self.edit_btn)
        vbox.addWidget(self.cancel_btn)
        self.setLayout(vbox) # apply layout to this class

        # when button is clicked send lineedit and combo box info to on_submit
        self.edit_btn.clicked.connect(self.on_edit)
        self.cancel_btn.clicked.connect(self.on_back)

    @Slot()
    def on_edit(self):

        # set up im_edit as which filter the user chose
        im_edit = self.my_combo_box.currentText()

        ##TODO change to correct image
        input_image = Image.open("image.png")
        input_pixels = input_image.load()

        output_image = Image.new("RGB", input_image.size)
        draw = ImageDraw.Draw(output_image)

        # Options are: ["Pick a value", "Luminosity", "Contrast", "Colorize", "Sepia", "Negative", "Grayscale", "None"]
        if (im_edit == "Luminosity"):
            luminosity = 80

            # Generate image
            for x in range(output_image.width):
                for y in range(output_image.height):
                    r, g, b, a = input_pixels[x, y]
                    r = int(r + luminosity)
                    g = int(g + luminosity)
                    b = int(b + luminosity)
                    draw.point((x, y), (r, g, b))

            #output_image.save("output.png")
            output_image.show()

        elif (im_edit == "Contrast"):
            # Find minimum and maximum luminosity
            imin = 255
            imax = 0
            for x in range(input_image.width):
                for y in range(input_image.height):
                    r, g, b, a = input_pixels[x, y]
                    i = (r + g + b) / 3
                    imin = min(imin, i)
                    imax = max(imax, i)

            # Generate image
            for x in range(output_image.width):
                for y in range(output_image.height):
                    r, g, b, a = input_pixels[x, y]
                    # Current luminosity
                    i = (r + g + b) / 3
                    # New luminosity
                    ip = 255 * (i - imin) / (imax - imin)
                    r = int(r * ip / i)
                    g = int(g * ip / i)
                    b = int(b * ip / i)
                    draw.point((x, y), (r, g, b))

            output_image.show()
        elif (im_edit == "Colorize"):
            # Square distance between 2 colors
            def distance2(color1, color2):
                r1, g1, b1 = color1
                r2, g2, b2, a2 = color2
                return (r1 - r2) ** 2 + (g1 - g2) ** 2 + (b1 - b2) ** 2

            color_to_change = (0, 0, 255)
            threshold = 220

            # Generate image
            for x in range(output_image.width):
                for y in range(output_image.height):
                    r, g, b, a = input_pixels[x, y]
                    if distance2(color_to_change, input_pixels[x, y]) < threshold ** 2:
                        r = int(r * .5)
                        g = int(g * 1.25)
                        b = int(b * .5)
                    draw.point((x, y), (r, g, b))

            #output_image.save("output.png")
            output_image.show()
        elif (im_edit == "Sepia"):
            def sepia(pixel):
                if pixel[0] < 63:
                    r,g,b = int(pixel[0]*1.1), pixel[1], int(pixel[2]*.9)
                elif pixel[0]>62 and pixel[0]<192:
                    r,g,b = int(pixel[0]*1.15), pixel[1], int(pixel[2]*.85)
                else:
                    r = int(pixel[0]*1.08)
                    if r>255: r=255
                    g,b = pixel[1], pixel[2]//2  
                return r,g,b
            sepia_list = map(sepia, input_image.getdata())
            output_image.putdata(list(sepia_list))
            #output_image.save("output.png")
            output_image.show()
        elif (im_edit == "Negative"):
            negative_list = [(255-p[0], 255-p[1], 255-p[2])
                                for p in input_image.getdata()]
            output_image.putdata(negative_list)
            #output_image.save("output.png")
            output_image.show()
        elif (im_edit == "Grayscale"):
            new_list = [ ( (a[0]+a[1]+a[2])//3, ) * 3
                                for a in input_image.getdata() ]
            output_image.putdata(new_list)
            #output_image.save("output.png")
            output_image.show()
        else: #"Pick a value" or "None"
            input_image.show()


    @Slot()
    def on_back(self):
        print("back")
Beispiel #25
0
class MainWindow(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)
        # Variaveis
        self.separador = ";" # Separador padrao de colunas em um arquivo txt ou csv
        self.selected = np.array([1, 24, 48, 96]).astype('timedelta64[h]') # selecionados ao iniciar o programa, modificavel.
        self.fileformat =  '' # Reservado para o formato do arquivo a ser aberto. Pode ser .xlsx ou .odf. ou .csv e assim vai.

        # facilita o acesso a variavel.
        self.timedeltastr = ("1 Hora","2 Horas", "3 Horas", "4 Horas","12 Horas",
         "24 Horas", "48 Horas", "72 horas", "96 horas", "30 Dias")
        self.timedeltas = np.array([1, 2, 3, 4, 12, 24, 48, 72, 96, 24*30]).astype('timedelta64[h]')
        self.linktimedelta = dict([(self.timedeltas[x], self.timedeltastr[x]) for x in range(len(self.timedeltastr))])

        self.datastring = ["DD/MM/AAAA",'AAAA/MM/DD', "AAAA-MM-DD", "DD-MM-AAAA"]
        self.dataformat = ["%d/%m/%Y", "%Y/%m/%d", "%Y-%m-%d", "%d-%m-%Y"]
        self.linkdata = dict([(self.datastring[x], self.dataformat[x]) for x in range(len(self.dataformat))])

        self.timestring = ["hh:mm", "hh:mm:ss", "hh:mm:ss.ms"]
        self.timeformat = ["%H:%M", "%H:%M:%S", "%H:%M:%S.%f"]
        self.linktime = dict([(self.timestring[x], self.timeformat[x]) for x in range(len(self.timeformat))])

        #Janela Principal
        widget = QWidget()
        self.setCentralWidget(widget)

        # Inicializa os Widgets
        self.folder = QLineEdit("Salvar Como...")
        self.path = QLineEdit("Abrir arquivo...")
        #
        buttonOpen = QPushButton('Abrir')
        buttonSave = QPushButton("Destino")
        Processar = QPushButton('Executar')
        Ajuda = QPushButton('Informações')
        #
        groupBox2 = QGroupBox("Delimitador")
        self.delimitador1 = QRadioButton("Ponto-Vírgula")
        self.delimitador2 = QRadioButton("Vírgula")
        self.delimitador3 = QRadioButton("Ponto")
        self.delimitador4 = QRadioButton("Tabulação")
        #
        checkGroup = QGroupBox("Mais opções")
        text3 = QPushButton("Configurações")
        text2 = QLabel("Formato da Data")
        text1 = QLabel("Formato da Hora")
        self.FormatoTime = QComboBox()
        self.FormatoTime.addItems(self.timestring)
        self.FormatoData = QComboBox()
        self.FormatoData.addItems(self.datastring)
        #
        text = QLabel("Por favor, selecione na tabela abaixo as colunas a utilizar:")
        self.ignore = QRadioButton("Possui Cabeçalho") # True se estiver selecionado, False caso nao
        #
        self.Tabela = QTableWidget(15,15)
        self.startTable()

        # Layouts
        MainLayout = QVBoxLayout()

        Gridlayout = QGridLayout()
        Gridlayout.addWidget(self.path, 0, 0)
        Gridlayout.addWidget(self.folder, 1, 0)
        Gridlayout.addWidget(buttonOpen, 0, 1)
        Gridlayout.addWidget(buttonSave, 1, 1)
        Gridlayout.addWidget(Processar, 0, 3)
        Gridlayout.addWidget(Ajuda, 1, 3)
        Gridlayout.setColumnStretch(0, 2)
        Gridlayout.setColumnStretch(3, 1)
        Gridlayout.setColumnMinimumWidth(2, 20)

        SecondLayout = QHBoxLayout()
        SecondLayout.addWidget(groupBox2)
        SecondLayout.addSpacing(40)
        SecondLayout.addWidget(checkGroup)
        #
        SepLayout = QVBoxLayout()
        SepLayout.addWidget(self.delimitador1)
        SepLayout.addWidget(self.delimitador2)
        SepLayout.addWidget(self.delimitador3)
        SepLayout.addWidget(self.delimitador4)
        #
        OptionsLayout = QVBoxLayout()
        OptionsLayout.addWidget(text3)
        OptionsLayout.addWidget(text2)
        OptionsLayout.addWidget(self.FormatoData)
        OptionsLayout.addWidget(text1)
        OptionsLayout.addWidget(self.FormatoTime)

        ThirdLayout = QVBoxLayout()
        ThirdLayout.addWidget(self.ignore)
        ThirdLayout.addWidget(text)

        MainLayout.addLayout(Gridlayout)
        MainLayout.addLayout(SecondLayout)
        MainLayout.addLayout(ThirdLayout)
        MainLayout.addWidget(self.Tabela)

        # Coloca o Layout principal na Janela
        widget.setLayout(MainLayout)

        # Comandos dos Widgets e edicoes.
        groupBox2.setLayout(SepLayout)
        self.delimitador1.setChecked(True)
        self.folder.setReadOnly(True)
        self.path.setReadOnly(True)
        checkGroup.setLayout(OptionsLayout)

        buttonOpen.clicked.connect(self.searchFile)
        buttonSave.clicked.connect(self.getNewFile)
        self.delimitador1.clicked.connect(self.updateDelimiter)
        self.delimitador2.clicked.connect(self.updateDelimiter)
        self.delimitador3.clicked.connect(self.updateDelimiter)
        self.delimitador4.clicked.connect(self.updateDelimiter)
        Ajuda.clicked.connect(self.help)
        Processar.clicked.connect(self.taskStart)
        text3.clicked.connect(self.openSubWindow)

        # Propriedades da janela principal
        height = 480
        width = 640
        myappid = 'GePlu.release1_0.0' # arbitrary string
        ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
        self.setWindowIcon(QIcon(r'images\icon6.ico'))
        self.setFixedSize(width, height)
        self.setWindowTitle("GePlu")

    def openSubWindow(self):

        dialog = MyDialog(self)
        dialog.show()
        dialog.exec_()

    def taskStart(self):
        ''' Inicia a execucao do programa, se houver algum erro durante o processo
        notifica o usuario e deixa a funcao imediatamente'''
        if self.folder.isModified() and self.path.isModified(): # o usuario entrou com os enderecos?
            start = time.time()

            # Conhece do que se trata cada coluna na tabela e armazena essa informacao.
            header = {}
            for col in range(15):
                header[self.Tabela.cellWidget(0, col).currentText()] = col

            boolean = 0 if self.ignore.isChecked() else None

            # Le o arquivo e retorna um dataframe de strings
            df_master = utils.read_file(self, header = boolean)
            df_master = dt.data_filter(self, df_master, header)
            df_master = dt.convert_dtype(self, df_master)

            # Computa os acumulados para cada intervalo de tempo (key).
            for key in self.selected:
                array = dt.compute(df_master.index.to_numpy(), df_master['Observado'].to_numpy(), key)
                df_master[self.linktimedelta[key]] = pd.Series(array, df_master.index)

            # salva o arquivo final.
            utils.save_file(self, df_master)

            # Fim do processo
            end = time.time()
            # Notifica o usuario
            QMessageBox.information(self, "Notificação", "Tarefa realizada com sucesso!\nTempo de execução: {} s.".format(round(end-start, 2)))
            # Reseta a tabela e os endereço do arquivo aberto e onde salvar, na janela principal.
            self.resetProgram()

        else:
            QMessageBox.warning(self, "Notificação", "Houve um erro no arquivo ou diretório especificado.\nPor favor, selecione um caminho válido.")


    def help(self):
        x = 'Caso tenha alguma dúvida, abra o documento em PDF presente\nna pasta do programa ou entre em contato.\n\nGeplu\n1.0.0'
        msgBox = QMessageBox.information(self, "Informação", x)

    def resetProgram(self):
        self.Tabela.clearContents()
        self.startTable()
        self.folder.setText("Salvar Como...")
        self.path.setText("Selecionar o arquivo...")
        self.folder.setModified(False)
        self.folder.setModified(False)

    def updateDelimiter(self):
        separadores = {"Ponto-Vírgula": ';', "Vírgula":",", "Ponto":".", "Tabulação":"\t"}
        for x in [self.delimitador1, self.delimitador3, self.delimitador2, self.delimitador4]:
            if x.isChecked():
                self.separador = separadores[x.text()]
                break

        if self.path.isModified():
            self.updateTable()

    def startTable(self):
        for col in range(self.Tabela.columnCount()):
            combo = QComboBox()
            combo.addItems(["Selecionar","Data & Hora","Prec. Observada","Data","Hora","Nível do Rio"])
            self.Tabela.setCellWidget(0, col, combo)

    def updateTable(self):
        # Guarda a primeira linha
        n_col = self.Tabela.columnCount()
        textos = [0]*n_col
        for col in range(n_col): textos[col] = self.Tabela.cellWidget(0, col).currentText()

        self.Tabela.clearContents()
        self.startTable()

        for col in range(n_col): self.Tabela.cellWidget(0, col).setCurrentText(textos[col])

        # Mostra na tabela as primeiras 14 linhas do arquivo que o usuario deseja abrir/utilizar.
        data_df = utils.read_file(self, 14).to_numpy()
        for row in range(data_df.shape[0]):
            for col in range(data_df.shape[1]):
                self.Tabela.setItem(row+1, col, QTableWidgetItem(data_df[row][col]))


    def searchFile(self):
        address, x = QFileDialog.getOpenFileName(self, "Selecione um arquivo",
            filter = "Text files (*.txt *.csv *.xlsx)"
            )
        if len(address) > 0:
            self.path.setText(address)
            self.path.setModified(True)
            self.fileformat = address[address.index('.'):]
            self.updateTable()

    def getNewFile(self):
        address, x = QFileDialog.getSaveFileName(self, "Salvar como",
            filter = "Text files (*.csv);; Text files (*.txt);; Planilha do Microsoft Excel (*.xlsx)"
            )
        if len(address) > 0:
            self.folder.setText(address)
            self.folder.setModified(True)
Beispiel #26
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        ## declared variables
        self.dir_path = "None selected"
        self.filelist = ["Select Folder"]
        self.filelistindex = None

        self.setWindowTitle("Ephys-Quick Analysis")

        layout = QGridLayout()

        toolbar = QToolBar("Function toolbar")
        self.addToolBar(toolbar)
        self.folderbuttonsetup()
        toolbar.addAction(self.folderbutton)
        self.setStatusBar(QStatusBar(self))

        self.filebox = QComboBox()
        self.filebox.addItems(self.filelist)
        layout.addWidget(self.filebox, 0, 0, 1, 2)

        self.tracelabel = QLabel("Sweep number :")
        layout.addWidget(self.tracelabel, 0, 2)

        self.sweepslider = QSpinBox()
        self.sweepslider.setMinimum(0)
        self.sweepslider.setSingleStep(1)
        layout.addWidget(self.sweepslider, 0, 3, 1, 2)

        self.pw = pg.PlotWidget(name='Clamp')  ## giving the plots names allows us to link their axes together
        layout.addWidget(self.pw, 1, 0, 2, 5)
        self.pw2 = pg.PlotWidget(name='ClampZoom')  ## giving the plots names allows us to link their axes together
        layout.addWidget(self.pw2, 1, 6, 2, 5)
        self.pw3 = pg.PlotWidget(name='Stim')
        layout.addWidget(self.pw3, 6, 0, 2, 5)
        self.pw3.setXLink(self.pw)
        self.pw4 = pg.PlotWidget(name='StimZoom')
        layout.addWidget(self.pw4, 6, 6, 2, 5)
        self.pw4.setXLink(self.pw2)

        self.pw.setBackground('w')
        self.pw2.setBackground('w')
        self.pw3.setBackground('w')
        self.pw4.setBackground('w')

        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

    def folderbuttonsetup(self):
        self.folderbutton = QAction("Folder", self)
        self.folderbutton.setStatusTip(self.dir_path)
        self.folderbutton.triggered.connect(self.folderselect)

    def folderselect(self):
        print("click")
        print(self.dir_path)
        self.dir_path = QFileDialog.getExistingDirectory()
        self.folderbutton.setStatusTip(self.dir_path)
        print(self.dir_path)
        self.fileboxlist()

    def fileboxlist(self):
        print('Files within experiment date folder')
        print('ISOLATING ABF FILES...')
        self.dir_path_1 = self.dir_path[2:] + "/"
        self.fileinfolder = os.listdir(self.dir_path_1)
        self.abffiles = [extension for extension in self.fileinfolder if re.search("\.abf$", extension)]
        self.abffiles.sort()
        print('*.abf files in folder:')
        print(self.abffiles)
        self.filebox.clear()
        self.filebox.currentTextChanged.connect(self.fileselected)

        self.filelist = self.abffiles
        self.filebox.addItems(self.filelist)

    def fileselected(self, s):
        print("yo")
        print(s)
        self.fileselected_1 = self.dir_path_1 + s
        print(self.fileselected_1)

        self.pw.clear()
        self.pw2.clear()
        self.pw3.clear()
        self.pw4.clear()

        self.loadabf(self.fileselected_1)

    def loadabf(self, filetoload):
        print("load file")
        self.abf = pyabf.ABF(filetoload)
        self.numsweep = self.abf.sweepCount - 1
        self.sweepslider.cleanText()
        self.sweepslider.setMaximum(self.numsweep)
        self.sweepslider.valueChanged.connect(self.setsweep)

        self.pw.setLabel('left', self.abf.sweepLabelY)
        self.pw.setLabel('bottom', self.abf.sweepLabelX)
        self.pw2.setLabel('left', self.abf.sweepLabelY)
        self.pw2.setLabel('bottom', self.abf.sweepLabelX)
        self.pw3.setLabel('left', self.abf.sweepLabelY)
        self.pw3.setLabel('bottom', self.abf.sweepLabelX)
        self.pw4.setLabel('left', self.abf.sweepLabelY)
        self.pw4.setLabel('bottom', self.abf.sweepLabelX)

        self.zoomarea = pg.LinearRegionItem([0, 1])
        self.zoomarea.setZValue(-10)
        self.pw.addItem(self.zoomarea)

        for sweepnum in self.abf.sweepList:
            self.abf.setSweep(sweepnum, channel=0)
            self.pw.plot(self.abf.sweepX, self.abf.sweepY, pen=pg.mkPen('black', width=1))

        for sweepnum in self.abf.sweepList:
            self.abf.setSweep(sweepnum, channel=1)
            self.pw3.plot(self.abf.sweepX, self.abf.sweepC, pen=pg.mkPen('black', width=1))

        for sweepnum in self.abf.sweepList:
            self.abf.setSweep(sweepnum, channel=0)
            self.pw2.plot(self.abf.sweepX, self.abf.sweepY, pen=pg.mkPen('black', width=1))

        for sweepnum in self.abf.sweepList:
            self.abf.setSweep(sweepnum, channel=1)
            self.pw4.plot(self.abf.sweepX, self.abf.sweepC, pen=pg.mkPen('black', width=1))

        def updatePlot():
            self.pw2.setXRange(*self.zoomarea.getRegion(), padding=0)

        def updateRegion():
            self.zoomarea.setRegion(self.pw2.getViewBox().viewRange()[0])

        self.zoomarea.sigRegionChanged.connect(updatePlot)
        self.pw2.sigXRangeChanged.connect(updateRegion)
        updatePlot()

        self.currenttrace = self.pw.plot()
        self.currenttrace.setPen(pg.mkPen('r', width=2.5))
        self.currenttrace2 = self.pw2.plot()
        self.currenttrace2.setPen(pg.mkPen('r', width=2.5))
        self.currenttrace3 = self.pw3.plot()
        self.currenttrace3.setPen(pg.mkPen('r', width=2.5))
        self.currenttrace4 = self.pw4.plot()
        self.currenttrace4.setPen(pg.mkPen('r', width=2.5))

    def setsweep(self, numofsweep):
        print(numofsweep)
        self.currenttrace.clear()
        self.currenttrace2.clear()
        self.currenttrace3.clear()
        self.currenttrace4.clear()
        for sweepnum in self.abf.sweepList:
            self.abf.setSweep(sweepnum, channel=0)
            if sweepnum == numofsweep:
                self.currenttrace.setData(self.abf.sweepX, self.abf.sweepY)
        for sweepnum in self.abf.sweepList:
            self.abf.setSweep(sweepnum, channel=1)
            if sweepnum == numofsweep:
                self.currenttrace3.setData(self.abf.sweepX, self.abf.sweepC)
        for sweepnum in self.abf.sweepList:
            self.abf.setSweep(sweepnum, channel=0)
            if sweepnum == numofsweep:
                self.currenttrace2.setData(self.abf.sweepX, self.abf.sweepY)
        for sweepnum in self.abf.sweepList:
            self.abf.setSweep(sweepnum, channel=1)
            if sweepnum == numofsweep:
                self.currenttrace4.setData(self.abf.sweepX, self.abf.sweepC)
Beispiel #27
0
class Scraper(QWidget):
    def __init__(self):
        super().__init__()

        self.setup()
    
    def setup(self):
        #self.setGeometry(200, 200,  400, 300)
        self.setWindowTitle('Quizlet Scraper')

        layout = QHBoxLayout()
        layout.setSpacing(20)
        self.setLayout(layout)

        left = QWidget()        
        left_layout = QVBoxLayout()
        left.setLayout(left_layout)
        layout.addWidget(left)

        right = QWidget()
        right_layout = QVBoxLayout()
        right.setLayout(right_layout)
        layout.addWidget(right)

        url_text = QLabel('URL:')
        left_layout.addWidget(url_text)

        self.urlbox = QLineEdit(self)
        left_layout.addWidget(self.urlbox)

        self.add_deck = QWidget()
        add_deck_layout = QVBoxLayout()
        self.add_deck.setLayout(add_deck_layout)
        right_layout.addWidget(self.add_deck)
        self.add_deck.hide()

        add_deck_label = QLabel('Deck name:')
        add_deck_layout.addWidget(add_deck_label)

        self.add_deck_box = QLineEdit(self)
        add_deck_layout.addWidget(self.add_deck_box)

        self.combo = QComboBox()
        self.combo.addItems([
            '.csv (Comma separated)',
            '.txt (Tab separated)',
            '.xls (Excel)',
            '.apkg (Anki package)'
        ])
        self.combo.currentIndexChanged.connect(self.index_changed)
        right_layout.addWidget(self.combo)

        spreadsheet_button = QPushButton('Get Spreadsheet', self)
        spreadsheet_button.clicked.connect(self.get_spreadsheet)
        spreadsheet_button.resize(spreadsheet_button.sizeHint())
        right_layout.addWidget(spreadsheet_button)
    
    def index_changed(self, i):
        self.add_deck.show() if i == 3 else self.add_deck.hide()

    def get_spreadsheet(self):
        try:
            page = q.start_session(self.urlbox.text())
            print('got page')
            term_list = q.get_terms(page)
        except:
            print('Not a valid Quizlet URL.')
            term_list = []
        self.save_file(term_list)
    
    def save_file(self, term_list):
        filename = QFileDialog.getSaveFileName(
            self,
            'Save file',
            '',
            'All Files (*)'
        )[0]
        i = self.combo.currentIndex()
        if i == 0:
            s.write_csv(term_list, filename + '.csv')
        elif i == 1:
            s.write_txt(term_list, filename + '.txt')
        elif i == 2:
            s.write_xls(term_list, filename + '.xls')
        elif i == 3:
            s.write_anki(term_list, self.add_deck_box.text(), filename + '.apkg')
Beispiel #28
0
class App(QWidget):
    def __init__(self):

        #init
        super(App, self).__init__()

        #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
        #parameters for the resume generation.
        self.params = {
            "White": 1.0,
            "Black": 1.0,
            "Hispanic": 1.0,
            "Asian": 1.0,
            "GenderRatio": 0.5,
            "TestSection": '',
            "TestMode": 2,
            "WorkPath": "",
            "BeginYear": "",
            "EndYear": "",
            "BeginMonth": "",
            "EndMonth": "",
            "BeginYearEdu": "",
            "EndYearEdu": "",
            "BeginMonthEdu": "",
            "EndMonthEdu": ""
        }
        #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

        #Dictionaries for UI buttons

        self.testModes = {"Before": 1, "After": 2, "Replace": 3}

        self.testSections = {
            "Address": 1,
            "Education": 2,
            "Work History": 3,
            "Skills": 4
        }
        #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
        #Window sizing for application
        self.title = "COEHP Resume Generator"
        self.left = 10
        self.top = 10
        self.width = 100
        self.height = 300

        #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
        #Window is created here
        self.makeUI()

    #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
    #Function creates window and adds widgets

    def makeUI(self):

        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.createLayout()

        windowLayout = QGridLayout()

        windowLayout.addWidget(self.box0, 1, 1, 1, 1)
        windowLayout.addWidget(self.box4, 0, 0, 1, 1)
        windowLayout.addWidget(self.box6, 1, 0, 1, 1)
        windowLayout.addWidget(self.box7, 0, 1, 1, 1)
        windowLayout.addWidget(self.box5, 3, 0, 1, 2)
        windowLayout.addWidget(self.box8, 2, 0, 1, 2)

        windowLayout.setAlignment(QtCore.Qt.AlignTop)

        self.setLayout(windowLayout)
        self.show()

    #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
    #All QGroupBoxes for features are added here.
    def createLayout(self):
        self.box0 = QGroupBox("Timeframe")
        self.box4 = QGroupBox("Test Data")
        self.box6 = QGroupBox("Output Directory")
        self.box5 = QGroupBox("")
        self.box7 = QGroupBox("Demographic Settings")
        self.box8 = QGroupBox("Resume Layout")

        #Demographic Settings

        self.wPercent = QTextEdit("0.25")
        self.bPercent = QTextEdit("0.25")
        self.aPercent = QTextEdit("0.25")
        self.hPercent = QTextEdit("0.25")
        self.gPercent = QTextEdit("0.5")
        self.wLabel = QLabel("White %")
        self.bLabel = QLabel("Black %")
        self.aLabel = QLabel("Asian %")
        self.hLabel = QLabel("Hispanic %")
        self.gLabel = QLabel("       Gender Ratio")

        self.wPercent.setFixedSize(100, 30)
        self.bPercent.setFixedSize(100, 30)
        self.aPercent.setFixedSize(100, 30)
        self.hPercent.setFixedSize(100, 30)
        self.gPercent.setFixedSize(100, 30)

        #Resume Layout Settings

        self.testSectionLabel1 = QLabel("Test Location")
        self.testSectionLabel2 = QLabel("Section")
        self.testSectionLabel3 = QLabel("Location of Content")
        self.sectionSelect = QComboBox()
        self.sectionSelect.addItems(
            ["Address", "Education", "Work History", "Skills"])
        self.sectionSelect.setFixedSize(300, 30)

        self.modeSelect = QComboBox()
        self.modeSelect.addItems(["Before", "After", "Replace"])
        self.modeSelect.setFixedSize(300, 30)

        #Academic Year

        #First Semester
        self.monthBegin = QComboBox()
        self.monthBegin.addItems([
            "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "November", "December"
        ])
        self.monthBegin.setFixedSize(100, 30)

        self.yearBeginLabel = QLabel("First Semester")
        self.yearBegin = QComboBox()
        self.yearBegin.setFixedSize(100, 30)

        for year in range(1970, 2050):
            self.yearBegin.addItem(str(year))

        #Last Semester
        self.monthEnd = QComboBox()
        self.monthEnd.addItems([
            "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "November", "December"
        ])
        self.monthEnd.setFixedSize(100, 30)

        self.yearEnd = QComboBox()
        self.yearEndLabel = QLabel("Semester of Graduation")
        for year in range(1970, 2050):
            self.yearEnd.addItem(str(year))
        self.yearEnd.setFixedSize(100, 30)

        #Earliest relevant employment
        self.monthWorkBegin = QComboBox()
        self.monthWorkBegin.addItems([
            "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "November", "December"
        ])
        self.monthBegin.setFixedSize(100, 30)

        self.yearWorkBeginLabel = QLabel(
            "Earliest Possible Date of Employment")
        self.yearWorkBegin = QComboBox()
        self.yearWorkBegin.setFixedSize(100, 30)

        for year in range(1970, 2050):
            self.yearWorkBegin.addItem(str(year))

        #Latest relevant employment
        self.monthWorkEnd = QComboBox()
        self.monthWorkEnd.addItems([
            "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "November", "December"
        ])
        self.monthWorkEnd.setFixedSize(100, 30)

        self.yearWorkEnd = QComboBox()
        self.yearWorkEndLabel = QLabel("Latest Possible Date of Employment")
        for year in range(1970, 2050):
            self.yearWorkEnd.addItem(str(year))
        self.yearWorkEnd.setFixedSize(100, 30)

        currentYear = date.today().year
        index = currentYear - 1970
        self.yearEnd.setCurrentIndex(index)
        self.yearBegin.setCurrentIndex(index)
        self.yearWorkBegin.setCurrentIndex(index)
        self.yearWorkEnd.setCurrentIndex(index)

        #Output Directory
        self.dirLabel = QLabel("Output Directory")
        self.currentDir = QTextEdit()
        self.currentDir.setText("Not Selected")
        self.currentDir.layout()
        self.currentDir.setFixedSize(300, 30)
        self.currentDir.setReadOnly(True)
        self.outputName = QTextEdit()

        self.outputLabel = QLabel("Output Folder Name")
        self.outputName.setText("None written")
        self.outputName.setToolTip(
            "Type in the name of the new Folder you would like to make for your Resume batch. \n Otherwise, this will use the current timestamp."
        )
        self.outputName.setFixedSize(300, 30)
        #Select ouput folder button

        self.outputButton = QPushButton('Select Output Directory')
        self.outputButton.setToolTip(
            "Click here to tell the generator where to put this batch of Resumes when it is finished."
        )
        self.outputButton.clicked.connect(
            lambda: self.openDir(self.currentDir))
        self.currentTest = QTextEdit()
        self.currentTest.setText("SportsCollegeList.csv")

        #Output Directory
        self.workLabel = QLabel("Output Directory")
        self.currentWork = QTextEdit()
        self.currentWork.setText("SportsCollegeList.csv")
        self.currentWork.layout()
        self.currentWork.setFixedSize(300, 30)
        self.currentWork.setReadOnly(True)

        #Select work datafolder button
        self.workButton = QPushButton('Select Work Data (.CSV)')
        self.workButton.setToolTip(
            "Click here to select a source file for the employment information in this Resume Batch."
        )
        self.workButton.clicked.connect(lambda: self.openDir(self.currentWork))

        #Select School Data

        self.workLabel = QLabel("Output Directory")
        self.currentSchool = QTextEdit()
        self.currentSchool.setText("Not Selected")
        self.currentSchool.layout()
        self.currentSchool.setFixedSize(300, 30)
        self.currentSchool.setReadOnly(True)

        #Select work datafolder button
        self.schoolButton = QPushButton('Select Work Data (.CSV)')
        self.schoolButton.clicked.connect(
            lambda: self.openDir(self.currentWork))

        #Select test data

        self.testLabel = QLabel("Output Directory")
        self.currentTest = QTextEdit()
        self.currentTest.setText("SportsCollegeList.csv")
        self.currentTest.layout()
        self.currentTest.setFixedSize(300, 30)
        self.currentTest.setReadOnly(True)
        self.testButton = QPushButton('Select Test Data (.CSV)')
        self.testButton.clicked.connect(lambda: self.openDir(self.currentTest))

        #Generate Resumes button
        self.begin = QPushButton('Generate Resumes')
        self.begin.clicked.connect(
            lambda: self.beginTask(self.currentTest.toPlainText()))

        layout = QGridLayout()
        self.box0.setLayout(layout)
        layout.addWidget(self.yearBeginLabel, 0, 0, 1, 2)
        layout.addWidget(self.monthBegin, 1, 0, 1, 1)
        layout.addWidget(self.yearBegin, 1, 1, 1, 1)
        layout.addWidget(self.yearEndLabel, 2, 0, 1, 2)
        layout.addWidget(self.monthEnd, 3, 0, 1, 1)
        layout.addWidget(self.yearEnd, 3, 1, 1, 1)

        layout.addWidget(self.yearWorkBeginLabel, 4, 0, 1, 2)
        layout.addWidget(self.monthWorkBegin, 5, 0, 1, 1)
        layout.addWidget(self.yearWorkBegin, 5, 1, 1, 1)
        layout.addWidget(self.yearWorkEndLabel, 6, 0, 1, 2)
        layout.addWidget(self.monthWorkEnd, 7, 0, 1, 1)
        layout.addWidget(self.yearWorkEnd, 7, 1, 1, 1)

        layout1 = QGridLayout()
        self.box8.setLayout(layout1)
        layout1.addWidget(self.testSectionLabel1, 0, 0, 1, 1)
        layout1.addWidget(self.testSectionLabel3, 1, 0, 1, 1)
        layout1.addWidget(self.sectionSelect, 0, 1, 1, 1)
        layout1.addWidget(self.modeSelect, 1, 1, 1, 1)

        layout2 = QGridLayout()
        self.box7.setLayout(layout2)
        layout2.addWidget(self.wLabel, 0, 0, 1, 1)
        layout2.addWidget(self.bLabel, 1, 0, 1, 1)
        layout2.addWidget(self.hLabel, 0, 2, 1, 1)
        layout2.addWidget(self.aLabel, 2, 0, 1, 1)
        layout2.addWidget(self.wPercent, 0, 1, 1, 1)
        layout2.addWidget(self.bPercent, 1, 1, 1, 1)
        layout2.addWidget(self.hPercent, 0, 3, 1, 1)
        layout2.addWidget(self.aPercent, 2, 1, 1, 1)
        layout2.addWidget(self.gLabel, 3, 1, 1, 1)
        layout2.addWidget(self.gPercent, 3, 2, 1, 2)

        layout = QGridLayout()
        self.box5.setLayout(layout)
        layout.addWidget(self.begin, 0, 0, 1, 2)

        layout3 = QGridLayout()
        layout3.addWidget(self.testButton, 0, 0, 1, 2)
        layout3.addWidget(self.currentTest, 1, 0, 1, 2)
        self.box4.setLayout(layout3)

        layout4 = QGridLayout()

        layout4.addWidget(self.outputButton, 0, 0, 1, 2)
        layout4.addWidget(self.currentDir, 1, 0, 1, 2)
        layout4.addWidget(self.outputLabel, 2, 0, 1, 2)
        layout4.addWidget(self.outputName, 3, 0, 1, 2)
        self.box6.setLayout(layout4)

    #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
    #
    def openDir(self, target):
        fileName = QFileDialog()
        filenames = list()
        if fileName.exec_():
            fileNames = fileName.selectedFiles()
            target.setText(fileNames[0])

    #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
    #
    def beginTask(self, path):
        self.beginGen(path)

    def beginGen(self, path):

        self.params["White"] = self.wPercent.toPlainText()
        self.params["Black"] = self.bPercent.toPlainText()
        self.params["Hispanic"] = self.hPercent.toPlainText()
        self.params["Asian"] = self.aPercent.toPlainText()
        self.params["GenderRatio"] = self.gPercent.toPlainText()
        self.params["TestMode"] = str(self.modeSelect.currentText())
        self.params["TestSection"] = str(self.sectionSelect.currentText())
        self.params["BeginYear"] = str(self.yearWorkBegin.currentText())
        self.params["EndYear"] = str(self.yearWorkEnd.currentText())
        self.params["BeginMonth"] = str(self.monthWorkBegin.currentText())
        self.params["EndMonth"] = str(self.monthWorkEnd.currentText())
        self.params["workPath"] = "work.csv"
        self.params["BeginYearEdu"] = str(self.yearBegin.currentText())
        self.params["EndYearEdu"] = str(self.yearEnd.currentText())
        self.params["BeginMonthEdu"] = str(self.monthBegin.currentText())
        self.params["EndMonthEdu"] = str(self.monthEnd.currentText())

        print(self.params)
        Printer.begin(self.currentDir.toPlainText(), path,
                      self.outputName.toPlainText(), self.params)
Beispiel #29
0
class Dialog_Dose(QDialog):
    """
    This class creates the user input dialog for when Modifying or
    Adding a isodose level option for ISO2ROI functionality.
    """
    def __init__(self, dose, notes):
        super(Dialog_Dose, self).__init__()

        # Class variables
        self.dose = dose
        self.notes = notes
        self.setWindowIcon(
            QtGui.QIcon("res/images/btn-icons/onkodicom_icon.png"))
        buttonBox = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self)
        self.iso_dose = QLineEdit()
        self.iso_dose.setText(self.dose)
        self.iso_unit = QComboBox()
        self.iso_unit.addItems(["cGy", "%"])
        self.iso_notes = QLineEdit()
        self.iso_notes.setText(self.notes)

        # Input dialog layout
        layout = QFormLayout(self)
        layout.addRow(QLabel("Isodose Level:"), self.iso_dose)
        layout.addRow(QLabel("Unit:"), self.iso_unit)
        layout.addRow(QLabel("Notes:"), self.iso_notes)
        layout.addWidget(buttonBox)
        buttonBox.accepted.connect(self.accepting)
        buttonBox.rejected.connect(self.reject)
        self.setWindowTitle("Isodose Levels")

    def getInputs(self):
        """
        Return the inputs from the dialog box.
        :return: tuple of dialog inputs - (isodose level, isodose unit,
                 isodose name, isodose notes)
        """
        # Get appropriate name for unit selected
        if self.iso_unit.currentText() == "%":
            iso_name = str('ISOp_' + self.iso_dose.text())
        else:
            iso_name = str('ISO' + self.iso_dose.text())

        # Return inputs from dialog box
        return (self.iso_dose.text(), self.iso_unit.currentText(), iso_name,
                self.iso_notes.text())

    def accepting(self):
        """
        Process the event when the user clicks "ok" in the dialog box.
        """
        # Make sure the isodose level is a number
        if (self.iso_dose.text() != ''):
            if re.match(r'^\d+$', self.iso_dose.text()):
                self.accept()
            else:
                buttonReply = QMessageBox.warning(
                    self, "Error Message",
                    "The Isodose level should to be a number!", QMessageBox.Ok)
                if buttonReply == QMessageBox.Ok:
                    pass
        # Make sure the isodose level is not blank
        else:
            buttonReply = QMessageBox.warning(
                self, "Error Message",
                "The Isodose field should not be empty!", QMessageBox.Ok)
            if buttonReply == QMessageBox.Ok:
                pass