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
class TabMain(QWidget): def __init__(self) -> None: super().__init__() # member self.pathname_line = PathLine() self.checkbox_save_to_file = QCheckBox("Save to File") self.t_button_open_filedialog = create_tool_button( is_text_beside_icon=True) self.t_button_step_mode = create_tool_button(fixed_width=250) self.t_button_cycle_mode = create_tool_button(fixed_width=250) self.t_button_only_lcr_mode = create_tool_button(fixed_width=250) self.t_button_lcr_state = create_tool_button(fixed_width=250) self.spinbox_interval = QSpinBox() self.group_save = QGroupBox("Save") self.group_mode = QGroupBox("Mode") self.group_lcr_state = QGroupBox("LCR Meter") self.group_measure_interval = QGroupBox("Measurement Interval") # setup self.spinbox_interval.setRange(1, 100000) self.checkbox_save_to_file.setEnabled(False) # setup layout f_layout_save = QFormLayout() f_layout_save.addRow("File Path", self.pathname_line) f_layout_save.addWidget(self.t_button_open_filedialog) f_layout_save.addRow(self.checkbox_save_to_file) self.group_save.setLayout(f_layout_save) v_layout_mode = AVBoxLayout() v_layout_mode.addWidget(self.t_button_step_mode) v_layout_mode.addWidget(self.t_button_cycle_mode) v_layout_mode.addWidget(self.t_button_only_lcr_mode) v_layout_mode.setAlignment(Qt.AlignHCenter) self.group_mode.setLayout(v_layout_mode) v_layout_lcr_state = AVBoxLayout() v_layout_lcr_state.addWidget(self.t_button_lcr_state) v_layout_lcr_state.setAlignment(Qt.AlignHCenter) self.group_lcr_state.setLayout(v_layout_lcr_state) f_layout_repeat = QFormLayout() f_layout_repeat.addRow("Interval", add_unit(self.spinbox_interval, "msec")) self.group_measure_interval.setLayout(f_layout_repeat) v_layout = AVBoxLayout(self) v_layout.addWidget(self.group_save) v_layout.addWidget(self.group_mode) v_layout.addWidget(self.group_lcr_state) v_layout.addWidget(self.group_measure_interval)
class IntSlider(QWidget): """THe IntSlider class provides controller with a handle which can be pulled back and forth to change the **integer**. """ def __init__(self): super().__init__() self._slider = QSlider(Qt.Horizontal) self._spinbox = QSpinBox() # setup signal self._slider.valueChanged.connect(self._value_changed) # type: ignore self._spinbox.valueChanged.connect(self._value_changed) # type: ignore # setup layout h_layout = AHBoxLayout(self) h_layout.addWidget(self._slider) h_layout.addWidget(self._spinbox) @property def current_value(self) -> int: return self._spinbox.value() @property def range(self) -> tuple[int, int]: return (self._slider.minimum(), self._slider.maximum()) @range.setter def range(self, range: tuple[int, int]) -> None: self._slider.setRange(*range) self._spinbox.setRange(*range) @Slot(int) # type: ignore def _value_changed(self, value: int) -> None: sender = self.sender() if sender is self._slider: self._spinbox.blockSignals(True) self._spinbox.setValue(value) self._spinbox.blockSignals(False) elif sender is self._spinbox: self._slider.blockSignals(True) self._slider.setValue(value) self._slider.blockSignals(False) def update_current_value(self, num: int) -> None: """Update current number of this widget. This method changes the display of the gui. Parameters ---------- num : int Integer. """ self._spinbox.setValue(num)
class TabLCR(QWidget): def __init__(self) -> None: super().__init__() # member self.combobox_parameter1 = IM3536ParameterCombobox() self.combobox_parameter2 = IM3536ParameterCombobox() self.combobox_parameter3 = IM3536ParameterCombobox() self.combobox_parameter4 = IM3536ParameterCombobox() self.spinbox_measurements_num = QSpinBox() self.checkbox_parmanent = QCheckBox("Parmanent Measurement") self.checkbox_acquire_monitor_data = QCheckBox( "Acquire Voltage/Current Monitor Values") self.group_parameter = QGroupBox("Parameter") self.group_only_lcr = QGroupBox("Only LCR Meter Mode") self.group_option = QGroupBox("Option") # setup self.combobox_parameter1.setCurrentText( "Rs (Equivalent series resistance)") self.combobox_parameter1.set_none_disabled(True) self.spinbox_measurements_num.setRange(1, 1000000000) self.checkbox_acquire_monitor_data.setChecked(True) self.checkbox_parmanent.setChecked(True) self.spinbox_measurements_num.setEnabled(False) self.group_only_lcr.setEnabled(False) # stup layout f_layout_parameter = QFormLayout() f_layout_parameter.addRow("1", self.combobox_parameter1) f_layout_parameter.addRow("2", self.combobox_parameter2) f_layout_parameter.addRow("3", self.combobox_parameter3) f_layout_parameter.addRow("4", self.combobox_parameter4) self.group_parameter.setLayout(f_layout_parameter) f_layout_only_lcr = QFormLayout() f_layout_only_lcr.addRow(self.checkbox_parmanent) f_layout_only_lcr.addRow("Number of Measurements", self.spinbox_measurements_num) self.group_only_lcr.setLayout(f_layout_only_lcr) f_layout_option = QFormLayout() f_layout_option.addRow(self.checkbox_acquire_monitor_data) self.group_option.setLayout(f_layout_option) v_layout = AVBoxLayout(self) v_layout.addWidget(self.group_parameter) v_layout.addWidget(self.group_only_lcr) v_layout.addWidget(self.group_option)
class TabStageCycle(QWidget): def __init__(self) -> None: super().__init__() self.spinbox_distance = QSpinBox() self.spinbox_cycle_num = QSpinBox() self.int_slider = IntSlider() self.spinbox_stop_interval = QSpinBox() # setup self.spinbox_distance.setRange(1, 100000) self.spinbox_cycle_num.setRange(1, 100000) self.int_slider.range = 1, 50000 self.spinbox_stop_interval.setRange(0, 10000) # setup layout f_layout = QFormLayout(self) f_layout.addRow("Displacement", add_unit(self.spinbox_distance, "μm")) f_layout.addRow("Number of Cycle", add_unit(self.spinbox_cycle_num, "times")) f_layout.addRow("Speed", add_unit(self.int_slider, "μm/sec")) f_layout.addRow("Stop Interval", add_unit(self.spinbox_stop_interval, "msec"))
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)
class PomoTimer(QWidget, BaseTimer): """ PomoTimer: Pomodoro タイマーを提供する。 1 pomodoro: 25min short break: 5min long break: 15min long break after 4pomodoro. """ paused = Signal() def __init__(self): super().__init__() self.simple_timer = SimpleTimer(self) self.settings = { 'pomo': 25, 'short_break': 5, 'long_break': 15, 'long_break_after': 4 } self.state_dict = { 'work': 'Work!', 'break': 'Break.', 'pause': 'Pause', 'wait': "Let's start." } self.work_timer = QTimer(self) self.work_timer.setSingleShot(True) self.break_timer = QTimer(self) self.break_timer.setSingleShot(True) self.pomo_count = 0 self.pomo_count_lbl = QLabel(self) self.pomo_count_lbl.setText(f'{self.pomo_count} pomodoro finished.') self.state_lbl = QLabel(self) self.state_lbl.setText(self.state_dict['wait']) self.estimate_pomo = 0 self.estimate_label = QLabel(self) self.estimate_label.setText('Estimate: ') self.estimate_pomo_widget = QSpinBox(self) self.estimate_pomo_widget.setValue(4) self.estimate_pomo_widget.setSuffix(' pomo') self.estimate_pomo_widget.setRange(1, 20) self.set_ui() self.set_connection() def set_ui(self): layout = self.simple_timer.layout() i = layout.indexOf(self.simple_timer.timer_edit) layout.takeAt(i) hlayout = QHBoxLayout() hlayout.addWidget(self.estimate_label) hlayout.addWidget(self.estimate_pomo_widget) vlayout = QVBoxLayout() vlayout.addLayout(hlayout) vlayout.addWidget(self.pomo_count_lbl) vlayout.addWidget(self.state_lbl) vlayout.addWidget(self.simple_timer) self.setLayout(vlayout) def set_connection(self): self.work_timer.timeout.connect(self.timeout) self.break_timer.timeout.connect(self.start_work) def start(self): self.estimate_pomo = self.estimate_pomo_widget.value() self.start_work() def start_work(self): """ Start timer for working on the task. :return: """ self.state_lbl.setText(self.state_dict['work']) self.simple_timer.timer = self.work_timer self.simple_timer.timer_edit.setValue(self.settings['pomo']) self.simple_timer.start() self.started.emit() def start_break(self): """ Start timer for working on the rest. Short break is normal break, long break comes every some tasks(default 4). :return: """ self.state_lbl.setText(self.state_dict['break']) self.simple_timer.timer = self.break_timer if self.pomo_count % self.settings['long_break_after']: self.simple_timer.timer_edit.setValue(self.settings['short_break']) else: self.simple_timer.timer_edit.setValue(self.settings['long_break']) self.simple_timer.start() self.started.emit() def abort(self): self.reset() self.aborted.emit() def pause(self): self.state_lbl.setText(self.state_dict['pause']) self.simple_timer.pause() self.paused.emit() def resume(self): self.state_lbl.setText(self.state_dict['work']) self.simple_timer.resume() self.started.emit() def timeout(self): self.pomo_count += 1 if self.pomo_count >= self.estimate_pomo: self.reset() self.finished.emit() else: self.start_break() def reset(self): self.pomo_count = 0 self.simple_timer.reset() self.work_timer.stop() self.break_timer.stop() self.state_lbl.setText(self.state_dict['wait']) def get_notify_message(self): return '' @property def name(self): return 'Pomo Timer' def fake_start(self): self.simple_timer.setting_time = self.simple_timer.timer_edit.value() self.simple_timer.timer.start(self.simple_timer.setting_time * 1000) self.simple_timer.set_remain_update() self.simple_timer.started.emit()
class SimpleTimer(QWidget, BaseTimer): paused = Signal() def __init__(self, parent=None): super().__init__(parent) self.timer = QTimer(self) self.timer.setSingleShot(True) self.update_timer = QTimer(self) self.setting_time = 0 self.remaining = 0 self.remain_label = QLabel('00:00', self) self.remain_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.remain_label.setScaledContents(True) font = QFont() font.setPointSize(86) self.remain_label.setFont(font) self.timer_edit = QSpinBox(self) self.timer_edit.setRange(1, 99) self.timer_edit.setValue(25) self.set_ui() self.set_connection() self.show() def set_ui(self): vlayout = QVBoxLayout() vlayout.addWidget(self.remain_label, alignment=Qt.AlignHCenter) vlayout.addWidget(self.timer_edit) self.setLayout(vlayout) def set_connection(self): self.timer.timeout.connect(self.stop) self.update_timer.timeout.connect(self.remain_update) def start(self): self.setting_time = self.timer_edit.value() self.timer.start(self.setting_time * 60 * 1000) self.set_remain_update() self.started.emit() def set_remain_update(self): self.remain_update() self.update_timer.start(250) def stop(self): self.reset() self.finished.emit() def abort(self): self.reset() self.timer.stop() self.aborted.emit() def pause(self): self.update_timer.stop() self.remaining = self.timer.remainingTime() self.timer.stop() self.paused.emit() def resume(self): self.timer.start(self.remaining) self.set_remain_update() self.started.emit() def reset(self): self.timer.stop() self.update_timer.stop() self.remain_label.setText('00:00') self.remaining = 0 def get_notify_message(self): remaining = self.timer.remainingTime() / 1000 return '{0} minutes have passed.'.format(self.setting_time - int(remaining/60)) def remain_update(self): remaining = self.timer.remainingTime() / 1000 self.remain_label.setText('{min:02}:{sec:02}'.format( min=int(remaining / 60), sec=int(remaining % 60))) @property def name(self): return 'Simple Timer'
class Window(QWidget): def __init__(self): super(Window, self).__init__() self.renderArea = RenderArea() self.shapeComboBox = QComboBox() self.shapeComboBox.addItem("Polygon", RenderArea.Polygon) self.shapeComboBox.addItem("Rectangle", RenderArea.Rect) self.shapeComboBox.addItem("Rounded Rectangle", RenderArea.RoundedRect) self.shapeComboBox.addItem("Ellipse", RenderArea.Ellipse) self.shapeComboBox.addItem("Pie", RenderArea.Pie) self.shapeComboBox.addItem("Chord", RenderArea.Chord) self.shapeComboBox.addItem("Path", RenderArea.Path) self.shapeComboBox.addItem("Line", RenderArea.Line) self.shapeComboBox.addItem("Polyline", RenderArea.Polyline) self.shapeComboBox.addItem("Arc", RenderArea.Arc) self.shapeComboBox.addItem("Points", RenderArea.Points) self.shapeComboBox.addItem("Text", RenderArea.Text) self.shapeComboBox.addItem("Pixmap", RenderArea.Pixmap) shapeLabel = QLabel("&Shape:") shapeLabel.setBuddy(self.shapeComboBox) self.penWidthSpinBox = QSpinBox() self.penWidthSpinBox.setRange(0, 20) self.penWidthSpinBox.setSpecialValueText("0 (cosmetic pen)") penWidthLabel = QLabel("Pen &Width:") penWidthLabel.setBuddy(self.penWidthSpinBox) self.penStyleComboBox = QComboBox() self.penStyleComboBox.addItem("Solid", Qt.SolidLine) self.penStyleComboBox.addItem("Dash", Qt.DashLine) self.penStyleComboBox.addItem("Dot", Qt.DotLine) self.penStyleComboBox.addItem("Dash Dot", Qt.DashDotLine) self.penStyleComboBox.addItem("Dash Dot Dot", Qt.DashDotDotLine) self.penStyleComboBox.addItem("None", Qt.NoPen) penStyleLabel = QLabel("&Pen Style:") penStyleLabel.setBuddy(self.penStyleComboBox) self.penCapComboBox = QComboBox() self.penCapComboBox.addItem("Flat", Qt.FlatCap) self.penCapComboBox.addItem("Square", Qt.SquareCap) self.penCapComboBox.addItem("Round", Qt.RoundCap) penCapLabel = QLabel("Pen &Cap:") penCapLabel.setBuddy(self.penCapComboBox) self.penJoinComboBox = QComboBox() self.penJoinComboBox.addItem("Miter", Qt.MiterJoin) self.penJoinComboBox.addItem("Bevel", Qt.BevelJoin) self.penJoinComboBox.addItem("Round", Qt.RoundJoin) penJoinLabel = QLabel("Pen &Join:") penJoinLabel.setBuddy(self.penJoinComboBox) self.brushStyleComboBox = QComboBox() self.brushStyleComboBox.addItem("Linear Gradient", Qt.LinearGradientPattern) self.brushStyleComboBox.addItem("Radial Gradient", Qt.RadialGradientPattern) self.brushStyleComboBox.addItem("Conical Gradient", Qt.ConicalGradientPattern) self.brushStyleComboBox.addItem("Texture", Qt.TexturePattern) self.brushStyleComboBox.addItem("Solid", Qt.SolidPattern) self.brushStyleComboBox.addItem("Horizontal", Qt.HorPattern) self.brushStyleComboBox.addItem("Vertical", Qt.VerPattern) self.brushStyleComboBox.addItem("Cross", Qt.CrossPattern) self.brushStyleComboBox.addItem("Backward Diagonal", Qt.BDiagPattern) self.brushStyleComboBox.addItem("Forward Diagonal", Qt.FDiagPattern) self.brushStyleComboBox.addItem("Diagonal Cross", Qt.DiagCrossPattern) self.brushStyleComboBox.addItem("Dense 1", Qt.Dense1Pattern) self.brushStyleComboBox.addItem("Dense 2", Qt.Dense2Pattern) self.brushStyleComboBox.addItem("Dense 3", Qt.Dense3Pattern) self.brushStyleComboBox.addItem("Dense 4", Qt.Dense4Pattern) self.brushStyleComboBox.addItem("Dense 5", Qt.Dense5Pattern) self.brushStyleComboBox.addItem("Dense 6", Qt.Dense6Pattern) self.brushStyleComboBox.addItem("Dense 7", Qt.Dense7Pattern) self.brushStyleComboBox.addItem("None", Qt.NoBrush) brushStyleLabel = QLabel("&Brush Style:") brushStyleLabel.setBuddy(self.brushStyleComboBox) otherOptionsLabel = QLabel("Other Options:") self.antialiasingCheckBox = QCheckBox("&Antialiasing") self.transformationsCheckBox = QCheckBox("&Transformations") self.shapeComboBox.activated.connect(self.shapeChanged) self.penWidthSpinBox.valueChanged.connect(self.penChanged) self.penStyleComboBox.activated.connect(self.penChanged) self.penCapComboBox.activated.connect(self.penChanged) self.penJoinComboBox.activated.connect(self.penChanged) self.brushStyleComboBox.activated.connect(self.brushChanged) self.antialiasingCheckBox.toggled.connect( self.renderArea.setAntialiased) self.transformationsCheckBox.toggled.connect( self.renderArea.setTransformed) mainLayout = QGridLayout() mainLayout.setColumnStretch(0, 1) mainLayout.setColumnStretch(3, 1) mainLayout.addWidget(self.renderArea, 0, 0, 1, 4) mainLayout.setRowMinimumHeight(1, 6) mainLayout.addWidget(shapeLabel, 2, 1, Qt.AlignRight) mainLayout.addWidget(self.shapeComboBox, 2, 2) mainLayout.addWidget(penWidthLabel, 3, 1, Qt.AlignRight) mainLayout.addWidget(self.penWidthSpinBox, 3, 2) mainLayout.addWidget(penStyleLabel, 4, 1, Qt.AlignRight) mainLayout.addWidget(self.penStyleComboBox, 4, 2) mainLayout.addWidget(penCapLabel, 5, 1, Qt.AlignRight) mainLayout.addWidget(self.penCapComboBox, 5, 2) mainLayout.addWidget(penJoinLabel, 6, 1, Qt.AlignRight) mainLayout.addWidget(self.penJoinComboBox, 6, 2) mainLayout.addWidget(brushStyleLabel, 7, 1, Qt.AlignRight) mainLayout.addWidget(self.brushStyleComboBox, 7, 2) mainLayout.setRowMinimumHeight(8, 6) mainLayout.addWidget(otherOptionsLabel, 9, 1, Qt.AlignRight) mainLayout.addWidget(self.antialiasingCheckBox, 9, 2) mainLayout.addWidget(self.transformationsCheckBox, 10, 2) self.setLayout(mainLayout) self.shapeChanged() self.penChanged() self.brushChanged() self.antialiasingCheckBox.setChecked(True) self.setWindowTitle("Basic Drawing") def shapeChanged(self): shape = self.shapeComboBox.itemData(self.shapeComboBox.currentIndex(), IdRole) self.renderArea.setShape(shape) def penChanged(self): width = self.penWidthSpinBox.value() style = Qt.PenStyle( self.penStyleComboBox.itemData( self.penStyleComboBox.currentIndex(), IdRole)) cap = Qt.PenCapStyle( self.penCapComboBox.itemData(self.penCapComboBox.currentIndex(), IdRole)) join = Qt.PenJoinStyle( self.penJoinComboBox.itemData(self.penJoinComboBox.currentIndex(), IdRole)) self.renderArea.setPen(QPen(Qt.blue, width, style, cap, join)) def brushChanged(self): style = Qt.BrushStyle( self.brushStyleComboBox.itemData( self.brushStyleComboBox.currentIndex(), IdRole)) if style == Qt.LinearGradientPattern: linearGradient = QLinearGradient(0, 0, 100, 100) linearGradient.setColorAt(0.0, Qt.white) linearGradient.setColorAt(0.2, Qt.green) linearGradient.setColorAt(1.0, Qt.black) self.renderArea.setBrush(QBrush(linearGradient)) elif style == Qt.RadialGradientPattern: radialGradient = QRadialGradient(50, 50, 50, 70, 70) radialGradient.setColorAt(0.0, Qt.white) radialGradient.setColorAt(0.2, Qt.green) radialGradient.setColorAt(1.0, Qt.black) self.renderArea.setBrush(QBrush(radialGradient)) elif style == Qt.ConicalGradientPattern: conicalGradient = QConicalGradient(50, 50, 150) conicalGradient.setColorAt(0.0, Qt.white) conicalGradient.setColorAt(0.2, Qt.green) conicalGradient.setColorAt(1.0, Qt.black) self.renderArea.setBrush(QBrush(conicalGradient)) elif style == Qt.TexturePattern: self.renderArea.setBrush(QBrush(QPixmap(':/images/brick.png'))) else: self.renderArea.setBrush(QBrush(Qt.green, style))
class Window(QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) self.iconGroupBox = QGroupBox() self.iconLabel = QLabel() self.iconComboBox = QComboBox() self.showIconCheckBox = QCheckBox() self.messageGroupBox = QGroupBox() self.typeLabel = QLabel() self.durationLabel = QLabel() self.durationWarningLabel = QLabel() self.titleLabel = QLabel() self.bodyLabel = QLabel() self.typeComboBox = QComboBox() self.durationSpinBox = QSpinBox() self.titleEdit = QLineEdit() self.bodyEdit = QTextEdit() self.showMessageButton = QPushButton() self.minimizeAction = QAction() self.maximizeAction = QAction() self.restoreAction = QAction() self.quitAction = QAction() self.trayIcon = QSystemTrayIcon() self.trayIconMenu = QMenu() self.createIconGroupBox() self.createMessageGroupBox() self.iconLabel.setMinimumWidth(self.durationLabel.sizeHint().width()) self.createActions() self.createTrayIcon() self.showMessageButton.clicked.connect(self.showMessage) self.showIconCheckBox.toggled.connect(self.trayIcon.setVisible) self.iconComboBox.currentIndexChanged.connect(self.setIcon) self.trayIcon.messageClicked.connect(self.messageClicked) self.trayIcon.activated.connect(self.iconActivated) self.mainLayout = QVBoxLayout() self.mainLayout.addWidget(self.iconGroupBox) self.mainLayout.addWidget(self.messageGroupBox) self.setLayout(self.mainLayout) self.iconComboBox.setCurrentIndex(1) self.trayIcon.show() self.setWindowTitle("Systray") self.resize(400, 300) def setVisible(self, visible): self.minimizeAction.setEnabled(visible) self.maximizeAction.setEnabled(not self.isMaximized()) self.restoreAction.setEnabled(self.isMaximized() or not visible) super().setVisible(visible) def closeEvent(self, event): if not event.spontaneous() or not self.isVisible(): return if self.trayIcon.isVisible(): QMessageBox.information( self, "Systray", "The program will keep running in the system tray. " "To terminate the program, choose <b>Quit</b> in the context " "menu of the system tray entry.") self.hide() event.ignore() @Slot(int) def setIcon(self, index): icon = self.iconComboBox.itemIcon(index) self.trayIcon.setIcon(icon) self.setWindowIcon(icon) self.trayIcon.setToolTip(self.iconComboBox.itemText(index)) @Slot(str) def iconActivated(self, reason): if reason == QSystemTrayIcon.Trigger: pass if reason == QSystemTrayIcon.DoubleClick: self.iconComboBox.setCurrentIndex( (self.iconComboBox.currentIndex() + 1) % self.iconComboBox.count()) if reason == QSystemTrayIcon.MiddleClick: self.showMessage() @Slot() def showMessage(self): self.showIconCheckBox.setChecked(True) selectedIcon = self.typeComboBox.itemData( self.typeComboBox.currentIndex()) msgIcon = QSystemTrayIcon.MessageIcon(selectedIcon) if selectedIcon == -1: # custom icon icon = QIcon( self.iconComboBox.itemIcon(self.iconComboBox.currentIndex())) self.trayIcon.showMessage( self.titleEdit.text(), self.bodyEdit.toPlainText(), icon, self.durationSpinBox.value() * 1000, ) else: self.trayIcon.showMessage( self.titleEdit.text(), self.bodyEdit.toPlainText(), msgIcon, self.durationSpinBox.value() * 1000, ) @Slot() def messageClicked(self): QMessageBox.information( None, "Systray", "Sorry, I already gave what help I could.\n" "Maybe you should try asking a human?") def createIconGroupBox(self): self.iconGroupBox = QGroupBox("Tray Icon") self.iconLabel = QLabel("Icon:") self.iconComboBox = QComboBox() self.iconComboBox.addItem(QIcon(":/images/bad.png"), "Bad") self.iconComboBox.addItem(QIcon(":/images/heart.png"), "Heart") self.iconComboBox.addItem(QIcon(":/images/trash.png"), "Trash") self.showIconCheckBox = QCheckBox("Show icon") self.showIconCheckBox.setChecked(True) iconLayout = QHBoxLayout() iconLayout.addWidget(self.iconLabel) iconLayout.addWidget(self.iconComboBox) iconLayout.addStretch() iconLayout.addWidget(self.showIconCheckBox) self.iconGroupBox.setLayout(iconLayout) def createMessageGroupBox(self): self.messageGroupBox = QGroupBox("Balloon Message") self.typeLabel = QLabel("Type:") self.typeComboBox = QComboBox() self.typeComboBox.addItem("None", QSystemTrayIcon.NoIcon) self.typeComboBox.addItem( self.style().standardIcon(QStyle.SP_MessageBoxInformation), "Information", QSystemTrayIcon.Information, ) self.typeComboBox.addItem( self.style().standardIcon(QStyle.SP_MessageBoxWarning), "Warning", QSystemTrayIcon.Warning, ) self.typeComboBox.addItem( self.style().standardIcon(QStyle.SP_MessageBoxCritical), "Critical", QSystemTrayIcon.Critical, ) self.typeComboBox.addItem(QIcon(), "Custom icon", -1) self.typeComboBox.setCurrentIndex(1) self.durationLabel = QLabel("Duration:") self.durationSpinBox = QSpinBox() self.durationSpinBox.setRange(5, 60) self.durationSpinBox.setSuffix(" s") self.durationSpinBox.setValue(15) self.durationWarningLabel = QLabel( "(some systems might ignore this hint)") self.durationWarningLabel.setIndent(10) self.titleLabel = QLabel("Title:") self.titleEdit = QLineEdit("Cannot connect to network") self.bodyLabel = QLabel("Body:") self.bodyEdit = QTextEdit() self.bodyEdit.setPlainText( "Don't believe me. Honestly, I don't have a clue." "\nClick this balloon for details.") self.showMessageButton = QPushButton("Show Message") self.showMessageButton.setDefault(True) messageLayout = QGridLayout() messageLayout.addWidget(self.typeLabel, 0, 0) messageLayout.addWidget(self.typeComboBox, 0, 1, 1, 2) messageLayout.addWidget(self.durationLabel, 1, 0) messageLayout.addWidget(self.durationSpinBox, 1, 1) messageLayout.addWidget(self.durationWarningLabel, 1, 2, 1, 3) messageLayout.addWidget(self.titleLabel, 2, 0) messageLayout.addWidget(self.titleEdit, 2, 1, 1, 4) messageLayout.addWidget(self.bodyLabel, 3, 0) messageLayout.addWidget(self.bodyEdit, 3, 1, 2, 4) messageLayout.addWidget(self.showMessageButton, 5, 4) messageLayout.setColumnStretch(3, 1) messageLayout.setRowStretch(4, 1) self.messageGroupBox.setLayout(messageLayout) def createActions(self): self.minimizeAction = QAction("Minimize", self) self.minimizeAction.triggered.connect(self.hide) self.maximizeAction = QAction("Maximize", self) self.maximizeAction.triggered.connect(self.showMaximized) self.restoreAction = QAction("Restore", self) self.restoreAction.triggered.connect(self.showNormal) self.quitAction = QAction("Quit", self) self.quitAction.triggered.connect(qApp.quit) def createTrayIcon(self): self.trayIconMenu = QMenu(self) self.trayIconMenu.addAction(self.minimizeAction) self.trayIconMenu.addAction(self.maximizeAction) self.trayIconMenu.addAction(self.restoreAction) self.trayIconMenu.addSeparator() self.trayIconMenu.addAction(self.quitAction) self.trayIcon = QSystemTrayIcon(self) self.trayIcon.setContextMenu(self.trayIconMenu)
class ImageFusionOptions(object): """ UI class that can be used by the AddOnOptions Class to allow the user customise their input parameters for auto-registration. """ def __init__(self, window_options): self.auto_image_fusion_frame = QtWidgets.QFrame() self.window = window_options self.moving_image = None self.fixed_image = None self.dict = {} self.setupUi() self.create_view() self.get_patients_info() def set_value(self, key, value): """ Stores values into a dictionary to the corresponding key. Parameters ---------- key (Any): value (Any): """ self.dict[key] = value def create_view(self): """ Create a table to hold all the ROI creation by isodose entries. """ self.auto_image_fusion_frame.setVisible(False) def setVisible(self, visibility): """ Custom setVisible function that will set the visibility of the GUI. Args: visibility (bool): flag for setting the GUI to visible """ self.auto_image_fusion_frame.setVisible(visibility) def setupUi(self): """ Constructs the GUI and sets the limit of each input field. """ # Create a vertical Widget to hold Vertical Layout self.vertical_layout_widget = QWidget() self.vertical_layout = QtWidgets.QVBoxLayout() # Create a Widget and set layout to a GridLayout self.gridLayoutWidget = QWidget() self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget) self.gridLayout.setSizeConstraint(QLayout.SetDefaultConstraint) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setVerticalSpacing(0) # Create horizontal spacer in the middle of the grid hspacer = QtWidgets.QSpacerItem(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.gridLayout.addItem(hspacer, 0, 5, 16, 1) # Labels self.fixed_image_label = QLabel("Fixed Image: ") fixed_image_sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred) fixed_image_sizePolicy.setHorizontalStretch(0) fixed_image_sizePolicy.setVerticalStretch(0) fixed_image_sizePolicy.setHeightForWidth( self.fixed_image_label.sizePolicy().hasHeightForWidth()) self.fixed_image_label.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.fixed_image_placeholder \ = QLabel("This is a placeholder for fixed image") self.fixed_image_placeholder.setWordWrap(False) self.fixed_image_placeholder.setText(str(self.fixed_image)) self.fixed_image_placeholder.setMaximumSize(200, 50) self.moving_image_label = QLabel("Moving Image: ") moving_image_label_sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) moving_image_label_sizePolicy.setHorizontalStretch(0) moving_image_label_sizePolicy.setVerticalStretch(0) moving_image_label_sizePolicy.setHeightForWidth( self.moving_image_label.sizePolicy().hasHeightForWidth()) self.moving_image_label.setSizePolicy(moving_image_label_sizePolicy) self.moving_image_placeholder = QLabel("This is a placeholder") self.moving_image_placeholder.setWordWrap(False) self.moving_image_placeholder.setText(str(self.moving_image)) self.moving_image_placeholder.setMaximumSize(200, 50) self.gridLayout.addWidget(self.fixed_image_label, 0, 0) self.gridLayout.addWidget(self.fixed_image_placeholder, 0, 1) self.gridLayout.addWidget(self.moving_image_label, 0, 2) self.gridLayout.addWidget(self.moving_image_placeholder, 0, 3) # Default Numbers self.default_numbers_label = QLabel("Default Numbers") self.default_numbers_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing | Qt.AlignVCenter) self.gridLayout.addWidget(self.default_numbers_label, 1, 0) self.default_number_spinBox = QSpinBox(self.gridLayoutWidget) self.default_number_spinBox.setRange(-2147483648, 2147483647) self.default_number_spinBox.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.default_number_spinBox.setToolTip( "Default voxel value. Defaults to -1000.") self.gridLayout.addWidget(self.default_number_spinBox, 1, 1) # Final Interp self.interp_order_label = QLabel("Final Interp") self.interp_order_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing | Qt.AlignVCenter) self.gridLayout.addWidget(self.interp_order_label, 2, 0) self.interp_order_spinbox = QSpinBox(self.gridLayoutWidget) self.interp_order_spinbox.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.interp_order_spinbox.setToolTip("The final interpolation order.") self.gridLayout.addWidget(self.interp_order_spinbox, 2, 1) # Metric self.metric_label = QLabel("Metric") self.metric_label.setAlignment(QtCore.Qt.AlignLeft | Qt.AlignTrailing | Qt.AlignVCenter) self.gridLayout.addWidget(self.metric_label, 3, 0) self.metric_comboBox = QComboBox() self.metric_comboBox.addItem("correlation") self.metric_comboBox.addItem("mean_squares") self.metric_comboBox.addItem("mattes_mi") self.metric_comboBox.addItem("joint_hist_mi") self.metric_comboBox.setToolTip( "The metric to be optimised during image registration.") self.gridLayout.addWidget(self.metric_comboBox, 3, 1) # Number of Iterations self.no_of_iterations_label = QLabel("Number of Iterations") self.no_of_iterations_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing | Qt.AlignVCenter) self.gridLayout.addWidget(self.no_of_iterations_label, 4, 0) self.no_of_iterations_spinBox = QSpinBox(self.gridLayoutWidget) self.no_of_iterations_spinBox.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.no_of_iterations_spinBox.setRange(0, 100) self.no_of_iterations_spinBox.setToolTip( "Number of iterations in each multi-resolution step.") self.gridLayout.addWidget(self.no_of_iterations_spinBox, 4, 1) # Shrink Factor self.shrink_factor_label = QLabel("Shrink Factor") self.shrink_factor_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing | Qt.AlignVCenter) self.gridLayout.addWidget(self.shrink_factor_label, 5, 0) self.shrink_factor_qLineEdit = QLineEdit() self.shrink_factor_qLineEdit.resize( self.shrink_factor_qLineEdit.sizeHint().width(), self.shrink_factor_qLineEdit.sizeHint().height()) self.shrink_factor_qLineEdit.setValidator( QRegularExpressionValidator( QRegularExpression("^[0-9]*[,]?[0-9]*[,]?[0-9]"))) self.shrink_factor_qLineEdit.setToolTip( "The multi-resolution downsampling factors. Can be up to three " "integer elements in an array. Example [8, 2, 1]") self.gridLayout.addWidget(self.shrink_factor_qLineEdit, 5, 1) # Optimiser self.optimiser_label = QLabel("Optimiser") self.optimiser_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing | Qt.AlignVCenter) self.gridLayout.addWidget(self.optimiser_label, 1, 2) self.optimiser_comboBox = QComboBox(self.gridLayoutWidget) self.optimiser_comboBox.addItem("lbfgsb") self.optimiser_comboBox.addItem("gradient_descent") self.optimiser_comboBox.addItem("gradient_descent_line_search") self.optimiser_comboBox.setToolTip( "The optimiser algorithm used for image registration.") self.gridLayout.addWidget(self.optimiser_comboBox, 1, 3) # Reg Method self.reg_method_label = QLabel("Reg Method") self.reg_method_label.setAlignment(QtCore.Qt.AlignLeft | Qt.AlignTrailing | Qt.AlignVCenter) self.gridLayout.addWidget(self.reg_method_label, 2, 2) self.reg_method_comboBox = QComboBox() self.reg_method_comboBox.addItem("translation") self.reg_method_comboBox.addItem("rigid") self.reg_method_comboBox.addItem("similarity") self.reg_method_comboBox.addItem("affine") self.reg_method_comboBox.addItem("scaleversor") self.reg_method_comboBox.addItem("scaleskewversor") self.reg_method_comboBox.setToolTip( "The linear transformation model to be used for image " "registration.") self.gridLayout.addWidget(self.reg_method_comboBox, 2, 3) # Sampling Rate self.sampling_rate_label = QLabel("Sampling Rate") self.sampling_rate_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing | Qt.AlignVCenter) self.gridLayout.addWidget(self.sampling_rate_label, 3, 2) self.sampling_rate_spinBox = QDoubleSpinBox(self.gridLayoutWidget) self.sampling_rate_spinBox.setMinimum(0) self.sampling_rate_spinBox.setMaximum(1) self.sampling_rate_spinBox.setSingleStep(0.01) self.sampling_rate_spinBox.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.sampling_rate_spinBox.setToolTip("The fraction of voxels sampled " "during each iteration.") self.gridLayout.addWidget(self.sampling_rate_spinBox, 3, 3) # Smooth Sigmas self.smooth_sigma_label = QLabel("Smooth Sigma") self.smooth_sigma_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing | Qt.AlignVCenter) self.gridLayout.addWidget(self.smooth_sigma_label, 4, 2) self.smooth_sigmas_qLineEdit = QLineEdit() self.smooth_sigmas_qLineEdit.resize( self.smooth_sigmas_qLineEdit.sizeHint().width(), self.smooth_sigmas_qLineEdit.sizeHint().height()) self.smooth_sigmas_qLineEdit.setValidator( QRegularExpressionValidator( QRegularExpression("^[0-9]*[,]?[0-9]*[,]?[0-9]"))) self.smooth_sigmas_qLineEdit.setToolTip( "The multi-resolution smoothing kernal scale (Gaussian). Can be " "up to three integer elements in an array. Example [4, 2, 1]") self.gridLayout.addWidget(self.smooth_sigmas_qLineEdit, 4, 3) # Label to hold warning labels. self.warning_label = QLabel() # Button for fast mode self.fast_mode_button = QtWidgets.QPushButton("Fast Mode") self.fast_mode_button.setCursor( QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.fast_mode_button.clicked.connect(self.set_fast_mode) # Add Widgets to the vertical layout self.vertical_layout.addWidget(self.fast_mode_button) self.vertical_layout.addWidget(self.gridLayoutWidget) self.vertical_layout.addWidget(self.warning_label) # Set layout of frame to the gridlayout widget self.auto_image_fusion_frame.setLayout(self.vertical_layout) def set_gridLayout(self): """ Set the UI based on the values taken from the JSON """ msg = "" # If-Elif statements for setting the dict # this can only be done in if-else statements. if self.dict["reg_method"] == "translation": self.reg_method_comboBox.setCurrentIndex(0) elif self.dict["reg_method"] == "rigid": self.reg_method_comboBox.setCurrentIndex(1) elif self.dict["reg_method"] == "similarity": self.reg_method_comboBox.setCurrentIndex(2) elif self.dict["reg_method"] == "affine": self.reg_method_comboBox.setCurrentIndex(3) elif self.dict["reg_method"] == "scaleversor": self.reg_method_comboBox.setCurrentIndex(4) elif self.dict["reg_method"] == "scaleskewversor": self.reg_method_comboBox.setCurrentIndex(5) else: msg += 'There was an error setting the reg_method value.\n' self.warning_label.setText(msg) if self.dict["metric"] == "coorelation": self.metric_comboBox.setCurrentIndex(0) elif self.dict["metric"] == "mean_squares": self.metric_comboBox.setCurrentIndex(1) elif self.dict["metric"] == "mattes_mi": self.metric_comboBox.setCurrentIndex(2) elif self.dict["metric"] == "joint_hist_mi": self.metric_comboBox.setCurrentIndex(3) else: msg += 'There was an error setting the metric value.\n' self.warning_label.setText(msg) if self.dict["optimiser"] == "lbfgsb": self.optimiser_comboBox.setCurrentIndex(0) elif self.dict["optimiser"] == "gradient_descent": self.optimiser_comboBox.setCurrentIndex(1) elif self.dict["optimiser"] == "gradient_descent_line_search": self.optimiser_comboBox.setCurrentIndex(2) else: msg += 'There was an error setting the optimiser value.\n' self.warning_label.setText(msg) # Check if all elements in list are ints if all(isinstance(x, int) for x in self.dict["shrink_factors"]): # Shrink_factors is stored as a list in JSON convert the list into # a string. shrink_factor_list_json = ', '.join( str(e) for e in self.dict["shrink_factors"]) self.shrink_factor_qLineEdit.setText(shrink_factor_list_json) else: msg += 'There was an error setting the Shrink Factors value.\n' self.warning_label.setText(msg) # Check if all elements in list are ints if all(isinstance(x, int) for x in self.dict["smooth_sigmas"]): # Since smooth_sigma is stored as a list in JSON convert the list # into a string. smooth_sigma_list_json = ', '.join( str(e) for e in self.dict["smooth_sigmas"]) self.smooth_sigmas_qLineEdit.setText(smooth_sigma_list_json) else: msg += 'There was an error setting the Smooth Sigmas value.\n' self.warning_label.setText(msg) try: self.sampling_rate_spinBox.setValue( float(self.dict["sampling_rate"])) except ValueError: msg += 'There was an error setting the Sampling Rate value.\n' self.warning_label.setText(msg) try: self.interp_order_spinbox.setValue(int(self.dict["final_interp"])) except ValueError: msg += 'There was an error setting the Final Interp value.\n' self.warning_label.setText(msg) try: self.no_of_iterations_spinBox.setValue( int(self.dict["number_of_iterations"])) except ValueError: msg += 'There was an error setting the Number of iterations ' \ 'value.\n' self.warning_label.setText(msg) try: self.default_number_spinBox.setValue( int(self.dict["default_value"])) except ValueError: msg += 'There was an error setting the Default Number' self.warning_label.setText(msg) def get_patients_info(self): """ Retrieve the patient's study description of the fixed image and for the moving image (if it exists). """ patient_dict_container = PatientDictContainer() if not patient_dict_container.is_empty(): filename = patient_dict_container.filepaths[0] dicom_tree_slice = DicomTree(filename) dict_tree = dicom_tree_slice.dict try: self.fixed_image = dict_tree["Series Instance UID"][0] except: self.fixed_image = "" self.warning_label.setText( 'Couldn\'t find the series instance ' 'UID for the Fixed Image.') moving_dict_container = MovingDictContainer() if not moving_dict_container.is_empty(): filename = moving_dict_container.filepaths[0] dicom_tree_slice = DicomTree(filename) dict_tree = dicom_tree_slice.dict try: self.moving_image = dict_tree["Series Instance UID"][0] except: self.moving_image = "" self.warning_label.setText( 'Couldn\'t find the series instance ' 'UID for the Moving Image.') if moving_dict_container.is_empty() and self.moving_image != "": self.moving_image = "" self.fixed_image_placeholder.setText(str(self.fixed_image)) self.moving_image_placeholder.setText(str(self.moving_image)) def get_values_from_UI(self): """ Sets values from the GUI to the dict that will be used to store the relevant parameters to imageFusion.json. """ self.dict["reg_method"] = str(self.reg_method_comboBox.currentText()) self.dict["metric"] = str(self.metric_comboBox.currentText()) self.dict["optimiser"] = str(self.optimiser_comboBox.currentText()) a_string = self.shrink_factor_qLineEdit.text().split(",") a_int = list(map(int, a_string)) self.dict["shrink_factors"] = a_int a_string = self.smooth_sigmas_qLineEdit.text().split(",") a_int = list(map(int, a_string)) self.dict["smooth_sigmas"] = a_int self.dict["sampling_rate"] = self.sampling_rate_spinBox.value() self.dict["final_interp"] = self.interp_order_spinbox.value() self.dict[ "number_of_iterations"] = self.no_of_iterations_spinBox.value() self.dict["default_value"] = self.default_number_spinBox.value() return self.dict def check_parameter(self): """ Check the number of values of the smooth sigma and shrink factors of that are parameters used for images fusion. """ len_smooth_sigmas = len(self.dict["smooth_sigmas"]) len_shrink_factor = len(self.dict["shrink_factors"]) if len_smooth_sigmas != len_shrink_factor: raise ValueError def set_fast_mode(self): """These settings are customised to be fast for images fusion.""" self.reg_method_comboBox.setCurrentIndex(1) self.metric_comboBox.setCurrentIndex(1) self.optimiser_comboBox.setCurrentIndex(1) self.shrink_factor_qLineEdit.setText("8") self.smooth_sigmas_qLineEdit.setText("10") self.sampling_rate_spinBox.setValue(0.25) self.interp_order_spinbox.setValue(2) self.no_of_iterations_spinBox.setValue(50) self.default_number_spinBox.setValue(-1000)
class WindowNewExercise(QWidget): def __init__(self, parent): super().__init__(parent) self.setWindowFlag(Qt.Window) self.setWindowFlag(Qt.WindowStaysOnTopHint) self.setWindowTitle("Add New Exercise") self.setWindowModality(Qt.WindowModal) self.setLayout(QFormLayout()) self.label_name = QLabel("Exercise Name:", self) self.line_edit_name = QLineEdit(self) self.layout().addRow(self.label_name, self.line_edit_name) self.label_measures = QLabel("Number of Measures:", self) self.spin_box_measures = QSpinBox(self) self.min, self.max = 0, 5 self.spin_box_measures.setRange(self.min, self.max) self.spin_box_measures.valueChanged.connect( self.change_visibility_measure_widgets) self.layout().addRow(self.label_measures, self.spin_box_measures) self.labels_measure_type = [] self.comboboxes_type = [] self.labels_measure_name = [] self.line_edits_measure_name = [] for i in range(self.min, self.max): label_measure_type = QLabel(f"Type of Measure {i + 1}:", self) self.labels_measure_type.append(label_measure_type) combobox_type = QComboBox(self) self.comboboxes_type.append(combobox_type) self.layout().addRow(label_measure_type, combobox_type) combobox_type.hide() label_measure_type.hide() label_measure_name = QLabel(f"Name of Measure {i + 1}:", self) self.labels_measure_name.append(label_measure_name) line_edit_measure_name = QLineEdit(self) self.line_edits_measure_name.append(line_edit_measure_name) self.layout().addRow(label_measure_name, line_edit_measure_name) label_measure_name.hide() line_edit_measure_name.hide() self.button_discard = QPushButton("Discard Exercise", self) self.button_discard.clicked.connect(self.button_discard_action) self.button_add = QPushButton("Add Exercise", self) self.button_add.clicked.connect(self.button_add_action) self.layout().addRow(self.button_discard, self.button_add) def change_visibility_measure_widgets(self): number_measures = self.spin_box_measures.value() for i in range(self.min, self.max): if number_measures > i: self.labels_measure_type[i].show() self.comboboxes_type[i].show() self.labels_measure_name[i].show() self.line_edits_measure_name[i].show() else: self.labels_measure_type[i].hide() self.comboboxes_type[i].hide() self.labels_measure_name[i].hide() self.line_edits_measure_name[i].hide() def closeEvent(self, event: QCloseEvent) -> None: self.line_edit_name.setText("") self.spin_box_measures.setValue(0) for line_edit in self.line_edits_measure_name: line_edit.setText("") return super().closeEvent(event) def button_discard_action(self): self.close() def button_add_action(self): self.close()
class ParameterEditorItem(QWidget): onRemoveParameter = Signal(Parameter) onMoveParameterUp = Signal(Parameter) onMoveParameterDown = Signal(Parameter) onChanged = Signal() def __init__(self, parameter: Parameter): super().__init__() self.parameter = parameter deleteButton = QToolButton() deleteButton.setText("X") deleteButton.clicked.connect( lambda: self.onRemoveParameter.emit(self.parameter)) upButton = QToolButton() upButton.setText("\u2191") upButton.clicked.connect( lambda: self.onMoveParameterUp.emit(self.parameter)) downButton = QToolButton() downButton.setText("\u2193") downButton.clicked.connect( lambda: self.onMoveParameterDown.emit(self.parameter)) buttonsLayout = QVBoxLayout() buttonsLayout.setAlignment(Qt.AlignTop) buttonsLayout.addWidget(deleteButton) buttonsLayout.addWidget(upButton) buttonsLayout.addWidget(downButton) self._nameLabel = QLabel("Name") self._nameField = QLineEdit() self._nameField.textChanged.connect(self.OnChanged) self._dataTypeLabel = QLabel("Data Type") self._dataTypeField = QComboBox() for dataType in DataType: self._dataTypeField.addItem(dataType.ToString(), userData=dataType) self._dataTypeField.currentIndexChanged.connect(self.OnChanged) self._defaultValueLabel = QLabel("Default Value") self._defaultInteger = QSpinBox() self._defaultInteger.valueChanged.connect(self.OnChanged) self._defaultFloat = QDoubleSpinBox() self._defaultFloat.valueChanged.connect(self.OnChanged) self._defaultBoolean = QComboBox() self._defaultBoolean.addItem("True", True) self._defaultBoolean.addItem("False", False) self._defaultBoolean.currentIndexChanged.connect(self.OnChanged) self._defaultString = QLineEdit() self._defaultString.textChanged.connect(self.OnChanged) self._minimumLabel = QLabel("Minimum") self._minimumFloat = QDoubleSpinBox() self._minimumFloat.valueChanged.connect(self.OnChanged) self._minimumInteger = QSpinBox() self._minimumInteger.valueChanged.connect(self.OnChanged) self._maximumLabel = QLabel("Maximum") self._maximumFloat = QDoubleSpinBox() self._maximumFloat.valueChanged.connect(self.OnChanged) self._maximumInteger = QSpinBox() self._maximumInteger.valueChanged.connect(self.OnChanged) gridLayout = QGridLayout() gridLayout.setAlignment(Qt.AlignTop) gridLayout.addWidget(self._nameLabel, 0, 0) gridLayout.addWidget(self._nameField, 0, 1) gridLayout.addWidget(self._dataTypeLabel, 1, 0) gridLayout.addWidget(self._dataTypeField, 1, 1) gridLayout.addWidget(self._defaultValueLabel, 2, 0) for defaultField in [ self._defaultInteger, self._defaultFloat, self._defaultBoolean, self._defaultString ]: gridLayout.addWidget(defaultField, 2, 1) gridLayout.addWidget(self._minimumLabel, 3, 0) gridLayout.addWidget(self._minimumInteger, 3, 1) gridLayout.addWidget(self._minimumFloat, 3, 1) gridLayout.addWidget(self._maximumLabel, 4, 0) gridLayout.addWidget(self._maximumInteger, 4, 1) gridLayout.addWidget(self._maximumFloat, 4, 1) layout = QHBoxLayout() layout.addLayout(buttonsLayout) layout.addLayout(gridLayout) self.setLayout(layout) self.SetFieldsFromParameter() def SetFieldsFromParameter(self): self._nameField.setText(self.parameter.name) self._dataTypeField.setCurrentText(self.parameter.dataType.ToString()) minFloat, maxFloat = self.parameter.minimumFloat, self.parameter.maximumFloat minInt, maxInt = self.parameter.minimumInteger, self.parameter.maximumInteger self._minimumFloat.setRange(-2**30, maxFloat) self._maximumFloat.setRange(minFloat, 2**30) self._minimumInteger.setRange(-2**30, maxInt) self._maximumInteger.setRange(minInt, 2**30) if self._minimumFloat.value() != minFloat: self._minimumFloat.setValue(minFloat) if self._maximumFloat.value() != maxFloat: self._maximumFloat.setValue(maxFloat) if self._minimumInteger.value() != minInt: self._minimumInteger.setValue(minInt) if self._maximumInteger.value() != maxInt: self._maximumInteger.setValue(maxInt) self._defaultInteger.setRange(minInt, maxInt) self._defaultFloat.setRange(minFloat, maxFloat) if self._defaultInteger.value() != self.parameter.defaultValueDict[ DataType.INTEGER]: self._defaultInteger.setValue( self.parameter.defaultValueDict[DataType.INTEGER]) if self._defaultFloat.value() != self.parameter.defaultValueDict[ DataType.FLOAT]: self._defaultFloat.setValue( self.parameter.defaultValueDict[DataType.FLOAT]) if self._defaultBoolean.currentData( ) != self.parameter.defaultValueDict[DataType.BOOLEAN]: self._defaultBoolean.setCurrentText( str(self.parameter.defaultValueDict[DataType.BOOLEAN])) if self._defaultString.text() != self.parameter.defaultValueDict[ DataType.STRING]: self._defaultString.setText( self.parameter.defaultValueDict[DataType.STRING]) self.UpdateVisibility() def UpdateVisibility(self): self._defaultInteger.setVisible( self._dataTypeField.currentData() is DataType.INTEGER) self._defaultFloat.setVisible( self._dataTypeField.currentData() is DataType.FLOAT) self._defaultBoolean.setVisible( self._dataTypeField.currentData() is DataType.BOOLEAN) self._defaultString.setVisible( self._dataTypeField.currentData() is DataType.STRING) self._minimumLabel.setVisible(self._dataTypeField.currentData() in [DataType.INTEGER, DataType.FLOAT]) self._maximumLabel.setVisible(self._dataTypeField.currentData() in [DataType.INTEGER, DataType.FLOAT]) self._minimumInteger.setVisible( self._dataTypeField.currentData() is DataType.INTEGER) self._maximumInteger.setVisible( self._dataTypeField.currentData() is DataType.INTEGER) self._minimumFloat.setVisible( self._dataTypeField.currentData() is DataType.FLOAT) self._maximumFloat.setVisible( self._dataTypeField.currentData() is DataType.FLOAT) self._minimumLabel.setVisible(self._dataTypeField.currentData() in [DataType.INTEGER, DataType.FLOAT]) self._maximumLabel.setVisible(self._dataTypeField.currentData() in [DataType.INTEGER, DataType.FLOAT]) self._defaultValueLabel.setVisible(self._dataTypeField.currentData( ) not in [DataType.VALVE, DataType.PROGRAM, DataType.PROGRAM_PRESET]) def OnChanged(self): self.UpdateVisibility() self._minimumFloat.setMaximum(self._maximumFloat.value()) self._maximumFloat.setMinimum(self._minimumFloat.value()) self._minimumInteger.setMaximum(self._maximumInteger.value()) self._maximumInteger.setMinimum(self._minimumInteger.value()) self._defaultInteger.setRange(self._minimumInteger.value(), self._maximumInteger.value()) self._defaultFloat.setRange(self._minimumFloat.value(), self._maximumFloat.value()) self.onChanged.emit() def UpdateParameter(self): self.parameter.name = self._nameField.text() self.parameter.dataType = self._dataTypeField.currentData() self.parameter.defaultValueDict[ DataType.INTEGER] = self._defaultInteger.value() self.parameter.defaultValueDict[ DataType.FLOAT] = self._defaultFloat.value() self.parameter.defaultValueDict[ DataType.BOOLEAN] = self._defaultBoolean.currentData() self.parameter.defaultValueDict[ DataType.STRING] = self._defaultString.text() self.parameter.minimumInteger = self._minimumInteger.value() self.parameter.maximumInteger = self._maximumInteger.value() self.parameter.minimumFloat = self._minimumFloat.value() self.parameter.maximumFloat = self._maximumFloat.value() self.parameter.ValidateDefaultValues() self.SetFieldsFromParameter()