Exemplo n.º 1
0
class GameActions(QWidget):
    def __init__(self):
        super(GameActions, self).__init__()
        self.layout = QVBoxLayout()
        self.game_actions = QLabel("<h3>Game actions</h3>")
        self.layout.addWidget(self.game_actions)

        uninstall_layout = QHBoxLayout()
        self.uninstall_game = QLabel(self.tr("Uninstall game"))
        uninstall_layout.addWidget(self.uninstall_game)
        self.uninstall_button = QPushButton(self.tr("Uninstall"))
        self.uninstall_button.setFixedWidth(250)
        uninstall_layout.addWidget(self.uninstall_button)
        self.layout.addLayout(uninstall_layout)

        verify_layout = QHBoxLayout()
        self.verify_game = QLabel(self.tr("Verify Game"))
        verify_layout.addWidget(self.verify_game)
        self.verify_widget = QStackedWidget()
        self.verify_widget.setMaximumHeight(20)
        self.verify_widget.setFixedWidth(250)
        self.verify_button = QPushButton(self.tr("Verify"))
        self.verify_widget.addWidget(self.verify_button)
        self.verify_progress_bar = QProgressBar()
        self.verify_progress_bar.setMaximum(100)
        self.verify_widget.addWidget(self.verify_progress_bar)
        verify_layout.addWidget(self.verify_widget)
        self.layout.addLayout(verify_layout)

        repair_layout = QHBoxLayout()
        repair_info = QLabel(self.tr("Repair Game"))
        repair_layout.addWidget(repair_info)
        self.repair_button = QPushButton(self.tr("Repair"))
        self.repair_button.setFixedWidth(250)
        repair_layout.addWidget(self.repair_button)
        self.layout.addLayout(repair_layout)

        self.setLayout(self.layout)
Exemplo n.º 2
0
class DiameterTab(QDialog):
    def __init__(self, ctx, par, *args, **kwargs):
        super(DiameterTab, self).__init__(*args, **kwargs)
        self.baseon_items = [
            'Effective Diameter (Deff)', 'Water Equivalent Diameter (Dw)'
        ]
        self.src_method_items = {
            'Get from Image': ['Auto', 'Auto (Z-axis)', 'Manual'],
            'Input Manually': ['Manual'],
        }

        self.ctx = ctx
        self.par = par
        self.deff_auto_method = 'area'
        self.deff_manual_method = 'deff'
        self.d_3d_method = 'slice step'
        self.is_truncated = False
        self.is_largest_only = False
        self.is_no_roi = False
        self.is_no_table = False
        self.is_corr = [False, False]
        self.all_slices = False
        self.minimum_area = 500
        self.threshold = -300
        self.bone_limit = 250
        self.stissue_limit = -250

        self.initVar()
        self.initModel()
        self.initData()
        self.initUI()
        self.sigConnect()
        self.on_set_opts_panel()

    def initUI(self):
        self.figure = PlotDialog()
        self._menu_ui()
        self._opts_ui()
        self._set_layout()

    def initVar(self):
        self.lineAP = self.lineLAT = 0
        self.idxs = []
        self.d_vals = []
        self.show_graph = False

    def initModel(self):
        self.query_model = QSqlQueryModel()
        self.age_model = QSqlTableModel(db=self.ctx.database.deff_db)
        self.head_ap_model = QSqlTableModel(db=self.ctx.database.deff_db)
        self.head_lat_model = QSqlTableModel(db=self.ctx.database.deff_db)
        self.head_latap_model = QSqlTableModel(db=self.ctx.database.deff_db)
        self.thorax_ap_model = QSqlTableModel(db=self.ctx.database.deff_db)
        self.thorax_lat_model = QSqlTableModel(db=self.ctx.database.deff_db)
        self.thorax_latap_model = QSqlTableModel(db=self.ctx.database.deff_db)
        self.age_model.setTable("Age")
        self.head_ap_model.setTable("HeadAP")
        self.head_lat_model.setTable("HeadLAT")
        self.head_latap_model.setTable("HeadLATAP")
        self.thorax_ap_model.setTable("ThoraxAP")
        self.thorax_lat_model.setTable("ThoraxLAT")
        self.thorax_latap_model.setTable("ThoraxLATAP")

        self.age_model.select()
        self.head_ap_model.select()
        self.head_lat_model.select()
        self.head_latap_model.select()
        self.thorax_ap_model.select()
        self.thorax_lat_model.select()
        self.thorax_latap_model.select()

    def initData(self):
        self.age_data = self.getData(self.age_model)
        self.head_ap_data = self.getData(self.head_ap_model)
        self.head_lat_data = self.getData(self.head_lat_model)
        self.head_latap_data = self.getData(self.head_latap_model)
        self.thorax_ap_data = self.getData(self.thorax_ap_model)
        self.thorax_lat_data = self.getData(self.thorax_lat_model)
        self.thorax_latap_data = self.getData(self.thorax_latap_model)

        self.age_interp = interpolate.splrep(self.age_data[:, 0],
                                             self.age_data[:, 1])
        self.head_ap_interp = interpolate.splrep(self.head_ap_data[:, 0],
                                                 self.head_ap_data[:, 1])
        self.head_lat_interp = interpolate.splrep(self.head_lat_data[:, 0],
                                                  self.head_lat_data[:, 1])
        self.head_latap_interp = interpolate.splrep(self.head_latap_data[:, 0],
                                                    self.head_latap_data[:, 1])
        self.thorax_ap_interp = interpolate.splrep(self.thorax_ap_data[:, 0],
                                                   self.thorax_ap_data[:, 1])
        self.thorax_lat_interp = interpolate.splrep(self.thorax_lat_data[:, 0],
                                                    self.thorax_lat_data[:, 1])
        self.thorax_latap_interp = interpolate.splrep(
            self.thorax_latap_data[:, 0], self.thorax_latap_data[:, 1])

    def _menu_ui(self):
        self.baseon_cb = QComboBox()
        self.source_cb = QComboBox()
        self.method_cb = QComboBox()
        self.calculate_btn = QPushButton('Calculate')
        self.plot_chk = QCheckBox('Show Graph')
        self.all_slices_chk = QCheckBox('All Slices')
        self.d_edit = QLineEdit(f'{self.ctx.app_data.diameter}')
        self.next_tab_btn = QPushButton('Next')
        self.prev_tab_btn = QPushButton('Previous')

        self.all_slices_chk.setVisible(False)
        self.baseon_cb.addItems(self.baseon_items)
        self.source_cb.addItems(self.src_method_items.keys())
        self.method_cb.addItems(self.src_method_items[list(
            self.src_method_items.keys())[0]])
        self.d_edit.setMaximumWidth(50)
        self.d_edit.setValidator(QDoubleValidator())
        self.d_edit.setReadOnly(True)

        self.calculate_btn.setAutoDefault(True)
        self.calculate_btn.setDefault(True)
        self.next_tab_btn.setAutoDefault(False)
        self.next_tab_btn.setDefault(False)
        self.prev_tab_btn.setAutoDefault(False)
        self.prev_tab_btn.setDefault(False)

        out_layout = QHBoxLayout()
        out_layout.addWidget(self.calculate_btn)
        out_layout.addWidget(QLabel('Diameter'))
        out_layout.addWidget(self.d_edit)
        out_layout.addWidget(QLabel('cm'))
        out_layout.addStretch()

        chk_layout = QHBoxLayout()
        chk_layout.addWidget(self.plot_chk)
        chk_layout.addWidget(self.all_slices_chk)
        chk_layout.addStretch()

        menu_layout = QVBoxLayout()
        menu_layout.addWidget(QLabel('Based on:'))
        menu_layout.addWidget(self.baseon_cb)
        menu_layout.addWidget(QLabel('Source:'))
        menu_layout.addWidget(self.source_cb)
        menu_layout.addWidget(QLabel('Method:'))
        menu_layout.addWidget(self.method_cb)
        menu_layout.addWidget(QLabel(''))
        menu_layout.addLayout(out_layout)
        menu_layout.addLayout(chk_layout)
        menu_layout.addStretch()

        self.menu_grpbox = QGroupBox('', self)
        self.menu_grpbox.setLayout(menu_layout)

    def _deff_correction_ui(self):
        self.bone_chk = QCheckBox("Bone")
        self.lung_chk = QCheckBox("Lung")
        self.bone_sb = QSpinBox()
        self.stissue_sb = QSpinBox()

        self.bone_sb.setRange(np.iinfo('int16').min, np.iinfo('int16').max)
        self.bone_sb.setValue(self.bone_limit)
        self.bone_sb.setMaximumWidth(60)
        self.stissue_sb.setRange(np.iinfo('int16').min, np.iinfo('int16').max)
        self.stissue_sb.setValue(self.stissue_limit)
        self.stissue_sb.setMaximumWidth(60)

        chk_layout = QHBoxLayout()
        chk_layout.addWidget(self.lung_chk)
        chk_layout.addWidget(self.bone_chk)

        corr_form = QFormLayout()
        corr_form.addRow(QLabel('Bone (HU)'), self.bone_sb)
        corr_form.addRow(QLabel('Soft Tissue (HU)'), self.stissue_sb)

        self.lower_bnd_grpbox = QGroupBox('Lower Bound')
        self.lower_bnd_grpbox.setLayout(corr_form)
        self.lower_bnd_grpbox.setEnabled(False)

        corr_layout = QVBoxLayout()
        corr_layout.addLayout(chk_layout)
        corr_layout.addWidget(self.lower_bnd_grpbox)

        self.deff_auto_corr_grpbox = QGroupBox('Correction', self)
        self.deff_auto_corr_grpbox.setLayout(corr_layout)

    def _3d_opts_ui(self):
        self.to_lbl = QLabel('to')
        self.slice1_sb = QSpinBox()
        self.slice2_sb = QSpinBox()
        self.slice_step_rbtn = QRadioButton('Slice Step')
        self.slice_nmbr_rbtn = QRadioButton('Slice Number')
        self.slice_regn_rbtn = QRadioButton('Regional')
        self.d_3d_rbtns = [
            self.slice_step_rbtn, self.slice_nmbr_rbtn, self.slice_regn_rbtn
        ]

        self.d_3d_btngrp = QButtonGroup()
        [self.d_3d_btngrp.addButton(btn) for btn in self.d_3d_rbtns]

        self.slice_step_rbtn.setChecked(True)
        self.slice1_sb.setMaximum(self.ctx.total_img)
        self.slice1_sb.setMinimum(1)
        self.slice1_sb.setMinimumWidth(50)
        self.slice2_sb.setMaximum(self.ctx.total_img)
        self.slice2_sb.setMinimum(1)
        self.slice2_sb.setMinimumWidth(50)
        self.to_lbl.setHidden(True)
        self.slice2_sb.setHidden(True)

        slice_layout = QHBoxLayout()
        slice_layout.addWidget(self.slice1_sb)
        slice_layout.addWidget(self.to_lbl)
        slice_layout.addWidget(self.slice2_sb)
        slice_layout.addStretch()

        self.d_3d_grpbox = QGroupBox('Z-axis Options', self)
        d_3d_layout = QVBoxLayout()
        [d_3d_layout.addWidget(btn) for btn in self.d_3d_rbtns]
        d_3d_layout.addLayout(slice_layout)
        d_3d_layout.addStretch()
        self.d_3d_grpbox.setLayout(d_3d_layout)

    def _deff_auto_ui(self):
        self.deff_minimum_area_sb = QSpinBox()
        self.deff_threshold_sb = QSpinBox()
        self.ap_edit = QLineEdit('0 cm')
        self.lat_edit = QLineEdit('0 cm')
        self.area_rbtn = QRadioButton('Area')
        self.center_rbtn = QRadioButton('Center')
        self.max_rbtn = QRadioButton('Max')
        self.deff_auto_rbtns = [
            self.area_rbtn, self.center_rbtn, self.max_rbtn
        ]

        self.deff_auto_btngrp = QButtonGroup()
        [self.deff_auto_btngrp.addButton(btn) for btn in self.deff_auto_rbtns]

        self.deff_threshold_sb.setRange(
            np.iinfo('int16').min,
            np.iinfo('int16').max)
        self.deff_threshold_sb.setValue(self.threshold)
        self.deff_threshold_sb.setMaximumWidth(60)
        self.deff_minimum_area_sb.setMaximum(512 * 512)
        self.deff_minimum_area_sb.setValue(self.minimum_area)
        self.deff_minimum_area_sb.setMaximumWidth(60)
        self.area_rbtn.setChecked(True)
        self.ap_edit.setMaximumWidth(60)
        self.lat_edit.setMaximumWidth(60)
        self.ap_edit.setReadOnly(True)
        self.lat_edit.setReadOnly(True)

        info_form = QFormLayout()
        info_form.addRow(QLabel('AP'), self.ap_edit)
        info_form.addRow(QLabel('LAT'), self.lat_edit)

        self.deff_auto_info_widget = QWidget()
        self.deff_auto_info_widget.setLayout(info_form)
        self.deff_auto_info_widget.setContentsMargins(0, 0, 0, 0)

        method_layout = QVBoxLayout()
        [method_layout.addWidget(btn) for btn in self.deff_auto_rbtns]
        method_layout.addStretch()

        method_info_layout = QHBoxLayout()
        method_info_layout.addLayout(method_layout)
        method_info_layout.addWidget(self.deff_auto_info_widget)

        deff_auto_method_grpbox = QGroupBox('Method', self)
        deff_auto_method_grpbox.setLayout(method_info_layout)

        self.deff_auto_grpbox = QGroupBox('Options', self)
        deff_auto_layout = QFormLayout()
        deff_auto_layout.addRow(QLabel('Threshold (HU)'),
                                self.deff_threshold_sb)
        deff_auto_layout.addRow(QLabel('Min. pixel area'),
                                self.deff_minimum_area_sb)
        deff_auto_layout.addRow(deff_auto_method_grpbox)
        self.deff_auto_grpbox.setLayout(deff_auto_layout)

    def _deff_img_manual_ui(self):
        self.deff_ap_edit = QLineEdit(
            f'{self.lineAP:#.2f} cm') if self.lineAP else QLineEdit('0 cm')
        self.deff_lat_edit = QLineEdit(
            f'{self.lineLAT:#.2f} cm') if self.lineLAT else QLineEdit('0 cm')
        self.deff_ap_btn = QPushButton('AP')
        self.deff_lat_btn = QPushButton('LAT')
        self.deff_clear_btn = QPushButton('Clear')
        btns = [self.deff_ap_btn, self.deff_lat_btn, self.deff_clear_btn]

        self.deff_clear_btn.setMaximumWidth(100)
        self.deff_ap_edit.setMaximumWidth(60)
        self.deff_lat_edit.setMaximumWidth(60)
        self.deff_ap_edit.setReadOnly(True)
        self.deff_lat_edit.setReadOnly(True)
        [btn.setAutoDefault(False) for btn in btns]
        [btn.setDefault(False) for btn in btns]

        form = QFormLayout()
        form.addRow(self.deff_ap_btn, self.deff_ap_edit)
        form.addRow(self.deff_lat_btn, self.deff_lat_edit)
        form.addRow(self.deff_clear_btn)

        self.deff_img_manual_grpbox = QGroupBox('Options', self)
        self.deff_img_manual_grpbox.setLayout(form)

    def _deff_manual_ui(self):
        self.deff_man_opts_cb = QComboBox()
        self.deff_man_opts_cb.addItems(['Deff', 'AP', 'LAT', 'AP+LAT', 'AGE'])

        self.year_sb = QSpinBox()
        self.month_sb = QSpinBox()
        self.deff_man_edit1 = QLineEdit()
        self.deff_man_edit2 = QLineEdit()
        self.deff_man_unit1 = QLabel('cm')
        self.deff_man_unit2 = QLabel('cm')

        self.year_sb.setRange(0, self.age_data[-1, 0])
        self.month_sb.setRange(0, 11)
        self.month_sb.setWrapping(True)

        self.deff_man_edit1.setPlaceholderText('Deff')
        self.deff_man_edit1.setValidator(QDoubleValidator())
        self.deff_man_edit2.setPlaceholderText('LAT')
        self.deff_man_edit2.setValidator(QDoubleValidator())

        self.deff_man_stack1 = QStackedWidget()
        self.deff_man_stack1.setMaximumWidth(50)
        self.deff_man_stack1.setMaximumHeight(25)
        self.deff_man_stack1.addWidget(self.deff_man_edit1)
        self.deff_man_stack1.addWidget(self.year_sb)

        self.deff_man_stack2 = QStackedWidget()
        self.deff_man_stack2.setMaximumWidth(50)
        self.deff_man_stack2.setMaximumHeight(25)
        self.deff_man_stack2.addWidget(self.deff_man_edit2)
        self.deff_man_stack2.addWidget(self.month_sb)

        h1 = QHBoxLayout()
        h1.addWidget(self.deff_man_stack1)
        h1.addWidget(self.deff_man_unit1)
        h2 = QHBoxLayout()
        h2.addWidget(self.deff_man_stack2)
        h2.addWidget(self.deff_man_unit2)

        form = QVBoxLayout()
        form.addWidget(self.deff_man_opts_cb)
        form.addLayout(h1)
        form.addLayout(h2)
        form.addStretch()

        self.deff_manual_grpbox = QGroupBox('Options')
        self.deff_manual_grpbox.setLayout(form)

        # self.deff_man_edit2.setHidden(True)
        self.deff_man_stack2.setHidden(True)
        self.deff_man_unit2.setHidden(True)

    def _dw_auto_ui(self):
        self.dw_minimum_area_lbl = QLabel('Min. pixel area')
        self.dw_threshold_lbl = QLabel('Threshold (HU)')
        self.dw_minimum_area_sb = QSpinBox()
        self.dw_threshold_sb = QSpinBox()
        self.trunc_img_chk = QCheckBox('Truncated image')
        self.large_obj_chk = QCheckBox('Largest object only')
        self.no_roi_chk = QCheckBox('Without ROI')
        self.no_table_chk = QCheckBox('Remove table')
        self.dw_auto_grpbox = QGroupBox('Options', self)
        self.no_table_chk.setEnabled(False)

        self.dw_threshold_sb.setRange(
            np.iinfo('int16').min,
            np.iinfo('int16').max)
        self.dw_threshold_sb.setValue(self.threshold)
        self.dw_threshold_sb.setMaximumWidth(60)
        self.dw_minimum_area_sb.setMaximum(512 * 512)
        self.dw_minimum_area_sb.setValue(self.minimum_area)
        self.dw_minimum_area_sb.setMaximumWidth(60)

        dw_auto_layout = QFormLayout()
        dw_auto_layout.addRow(self.dw_threshold_lbl, self.dw_threshold_sb)
        dw_auto_layout.addRow(self.dw_minimum_area_lbl,
                              self.dw_minimum_area_sb)
        dw_auto_layout.addRow(self.trunc_img_chk)
        dw_auto_layout.addRow(self.large_obj_chk)
        dw_auto_layout.addRow(self.no_roi_chk)
        dw_auto_layout.addRow(self.no_table_chk)
        # dw_auto_layout.addStretch()
        self.dw_auto_grpbox.setLayout(dw_auto_layout)

    def _dw_img_manual_ui(self):
        self.dw_polygon_btn = QPushButton('Polygon')
        self.dw_ellipse_btn = QPushButton('Ellipse')
        self.dw_clear_btn = QPushButton('Clear')
        btns = [self.dw_polygon_btn, self.dw_ellipse_btn, self.dw_clear_btn]

        [btn.setMaximumWidth(100) for btn in btns]
        [btn.setAutoDefault(False) for btn in btns]
        [btn.setDefault(False) for btn in btns]

        dw_img_manual_layout = QVBoxLayout()
        [dw_img_manual_layout.addWidget(btn) for btn in btns]
        dw_img_manual_layout.addStretch()

        self.dw_img_manual_grpbox = QGroupBox('Options')
        self.dw_img_manual_grpbox.setLayout(dw_img_manual_layout)

    def _opts_ui(self):
        self._3d_opts_ui()
        self._deff_auto_ui()
        self._deff_img_manual_ui()
        self._deff_manual_ui()
        self._dw_auto_ui()
        self._dw_img_manual_ui()
        self._deff_correction_ui()

        self.opts_stack = QStackedWidget()
        self.opts_stack.addWidget(self.deff_auto_grpbox)
        self.opts_stack.addWidget(self.deff_img_manual_grpbox)
        self.opts_stack.addWidget(self.deff_manual_grpbox)
        self.opts_stack.addWidget(self.dw_auto_grpbox)
        self.opts_stack.addWidget(self.dw_img_manual_grpbox)

        opts_layout = QVBoxLayout()
        opts_layout.addWidget(self.opts_stack)
        opts_layout.addWidget(self.deff_auto_corr_grpbox)
        opts_layout.addWidget(self.d_3d_grpbox)
        opts_layout.addStretch()

        opts_widget = QWidget()
        opts_widget.setContentsMargins(0, 0, 0, 0)
        opts_widget.setLayout(opts_layout)

        self.opts_scroll = QScrollArea()
        self.opts_scroll.setWidget(opts_widget)
        self.opts_scroll.setWidgetResizable(True)
        self.opts_scroll.horizontalScrollBar().setEnabled(False)

        self.d_3d_grpbox.setVisible(False)

    def _set_layout(self):
        menu_layout = QHBoxLayout()
        menu_layout.addWidget(self.menu_grpbox)
        menu_layout.addWidget(self.opts_scroll)

        tab_nav = QHBoxLayout()
        tab_nav.addWidget(self.prev_tab_btn)
        tab_nav.addStretch()
        tab_nav.addWidget(self.next_tab_btn)

        main_layout = QVBoxLayout()
        main_layout.addLayout(menu_layout)
        main_layout.addLayout(tab_nav)
        self.setLayout(main_layout)

    def sigConnect(self):
        self.baseon_cb.activated[str].connect(self.on_set_opts_panel)
        self.method_cb.activated[str].connect(self.on_set_opts_panel)
        self.source_cb.activated[str].connect(self.on_set_opts_panel)
        self.source_cb.activated[str].connect(self.on_source_changed)
        self.deff_man_opts_cb.activated[str].connect(
            self.on_deff_manual_method_changed)
        self.year_sb.valueChanged.connect(self.check_age)
        self.trunc_img_chk.stateChanged.connect(self.on_truncated_check)
        self.large_obj_chk.stateChanged.connect(self.on_largest_check)
        self.no_roi_chk.stateChanged.connect(self.on_roi_check)
        self.no_table_chk.stateChanged.connect(self.on_table_check)
        self.calculate_btn.clicked.connect(self.on_calculate)
        self.deff_clear_btn.clicked.connect(self.clearROIs)
        self.dw_clear_btn.clicked.connect(self.clearROIs)
        self.deff_minimum_area_sb.valueChanged.connect(
            self.on_minimum_area_changed)
        self.dw_minimum_area_sb.valueChanged.connect(
            self.on_minimum_area_changed)
        self.deff_threshold_sb.valueChanged.connect(self.on_threshold_changed)
        self.dw_threshold_sb.valueChanged.connect(self.on_threshold_changed)
        self.dw_ellipse_btn.clicked.connect(self.add_ellipse)
        self.dw_polygon_btn.clicked.connect(self.add_polygon)
        self.deff_ap_btn.clicked.connect(self.add_ap_line)
        self.deff_lat_btn.clicked.connect(self.add_lat_line)
        self.bone_chk.stateChanged.connect(self.on_corr_check)
        self.lung_chk.stateChanged.connect(self.on_corr_check)
        self.bone_sb.valueChanged.connect(self.on_bone_limit_changed)
        self.stissue_sb.valueChanged.connect(self.on_stissue_limit_changed)
        self.ctx.app_data.imgLoaded.connect(self.img_loaded_handle)
        self.ctx.app_data.imgChanged.connect(self.img_changed_handle)
        self.ctx.app_data.sliceOptChanged.connect(self.sliceopt_handle)
        self.ctx.app_data.mode3dChanged.connect(self.mode3d_handle)
        self.ctx.app_data.slice1Changed.connect(self.slice1_handle)
        self.ctx.app_data.slice2Changed.connect(self.slice2_handle)
        [
            btn.toggled.connect(self.on_deff_auto_method_changed)
            for btn in self.deff_auto_rbtns
        ]
        [
            btn.toggled.connect(self.on_3d_opts_changed)
            for btn in self.d_3d_rbtns
        ]
        self.plot_chk.stateChanged.connect(self.on_show_graph_check)
        self.all_slices_chk.stateChanged.connect(self.on_all_slices)

    def on_all_slices(self, state):
        self.all_slices = state == Qt.Checked
        self.ctx.app_data.d_mode = int(self.all_slices)

    def img_loaded_handle(self, state):
        if not state:
            self.all_slices = False
            self.all_slices_chk.setChecked(False)
        self.all_slices_chk.setEnabled(state)

    def on_show_graph_check(self, state):
        self.show_graph = state == Qt.Checked

    def plot_chk_handle(self, state):
        self.plot_chk.setEnabled(state)
        self.show_graph = False
        self.plot_chk.setCheckState(Qt.Unchecked)

    def getData(self, model):
        data = [[
            model.data(model.index(i, j)) for i in range(model.rowCount())
        ] for j in range(1, 3)]
        return np.array(data).T

    def check_age(self, val):
        if val == self.age_data[-1, 0]:
            self.month_sb.setMaximum(0)
        else:
            self.month_sb.setMaximum(11)

    def on_truncated_check(self, state):
        self.is_truncated = state == Qt.Checked

    def on_largest_check(self, state):
        self.is_largest_only = state == Qt.Checked

    def on_roi_check(self, state):
        self.is_no_roi = state == Qt.Checked
        if self.is_no_roi:
            self.large_obj_chk.setCheckState(Qt.Unchecked)
            self.trunc_img_chk.setCheckState(Qt.Unchecked)
            self.is_largest_only = False
            self.is_truncated = False
        else:
            self.no_table_chk.setCheckState(Qt.Unchecked)
            self.is_no_table = False
        self.no_table_chk.setEnabled(self.is_no_roi)
        self.large_obj_chk.setEnabled(not self.is_no_roi)
        self.trunc_img_chk.setEnabled(not self.is_no_roi)
        self.dw_minimum_area_lbl.setEnabled(not self.is_no_roi)
        self.dw_minimum_area_sb.setEnabled(not self.is_no_roi)
        self.dw_threshold_lbl.setEnabled(not self.is_no_roi)
        self.dw_threshold_sb.setEnabled(not self.is_no_roi)

    def on_table_check(self, state):
        self.is_no_table = state == Qt.Checked
        self.dw_threshold_lbl.setEnabled(self.is_no_table)
        self.dw_threshold_sb.setEnabled(self.is_no_table)

    def on_corr_check(self, state):
        self.is_corr[int(
            self.sender().text().lower() == 'bone')] = state == Qt.Checked
        self.lower_bnd_grpbox.setEnabled(any(self.is_corr))

    def on_source_changed(self, src):
        self.method_cb.clear()
        self.method_cb.addItems(self.src_method_items[src])
        self.on_set_opts_panel()

    def on_deff_auto_method_changed(self):
        self.clearROIs()
        sel = self.sender()
        if sel.isChecked():
            self.deff_auto_method = sel.text().lower()
            is_area = self.deff_auto_method == 'area'
            self.deff_auto_corr_grpbox.setVisible(not is_area)
            if self.method == 0:
                self.deff_auto_info_widget.setVisible(not is_area)
            if is_area:
                self.bone_chk.setCheckState(Qt.Unchecked)
                self.lung_chk.setCheckState(Qt.Unchecked)
                self.is_corr = [False, False]
            print(self.deff_auto_method)

    def on_3d_opts_changed(self):
        sel = self.sender()
        if sel.isChecked():
            self.d_3d_method = sel.text().lower()
            if self.d_3d_method == 'regional':
                self.to_lbl.setHidden(False)
                self.slice2_sb.setHidden(False)
                self.slice1_sb.setMinimum(1)
                self.slice1_sb.setMaximum(self.ctx.total_img)
            else:
                self.to_lbl.setHidden(True)
                self.slice2_sb.setHidden(True)

    def on_set_opts_panel(self):
        self.clearROIs()
        self.opts_stack.setVisible(True)
        self.deff_auto_info_widget.setVisible(False)
        self.d_3d_grpbox.setVisible(False)
        self.deff_auto_corr_grpbox.setVisible(False)
        self.d_edit.setReadOnly(True)
        self.baseon = self.baseon_cb.currentIndex()
        self.source = self.source_cb.currentIndex()
        self.method = self.method_cb.currentIndex()
        try:
            self.d_edit.textChanged.disconnect(self._on_dw_manual)
        except:
            pass
        self.all_slices_chk.setVisible(self.source == 1)
        if self.source == 1:  # and (self.sender().tag is 'source' or self.sender().tag is 'based'):
            if self.baseon == 0 and self.method == 0:
                self.plot_chk_handle(True)
                self.opts_stack.setCurrentIndex(2)
                self.ctx.app_data.mode = DEFF_MANUAL
            else:
                self.opts_stack.setVisible(False)
                self.ctx.app_data.mode = DW
                self.d_edit.setReadOnly(False)
                self.d_edit.textChanged.connect(self._on_dw_manual)
        elif self.source == 0:  # from img
            self.d_3d_grpbox.setVisible(self.method == 1)
            self.plot_chk_handle(self.method == 1)
            if self.baseon == 0:  # deff
                if self.method == 0 or self.method == 1:
                    self.deff_auto_corr_grpbox.setVisible(
                        self.deff_auto_method != 'area')
                    self.opts_stack.setCurrentIndex(0)
                    if self.method == 0:
                        self.deff_auto_info_widget.setVisible(
                            self.deff_auto_method != 'area')
                elif self.method == 2:
                    self.opts_stack.setCurrentIndex(1)
                self.ctx.app_data.mode = DEFF_IMAGE
            else:
                if self.method == 0 or self.method == 1:
                    self.opts_stack.setCurrentIndex(3)
                elif self.method == 2:
                    self.opts_stack.setCurrentIndex(4)
                self.ctx.app_data.mode = DW
        self.d_edit.setText('0')

    def on_deff_manual_method_changed(self, sel):
        self.deff_man_edit1.clear()
        self.deff_man_edit2.clear()
        if sel.lower() != 'ap+lat' and sel.lower() != 'age':
            self.deff_man_stack1.setCurrentIndex(0)
            self.deff_man_stack2.setCurrentIndex(0)
            self.deff_man_edit1.setPlaceholderText(sel)
            self.deff_man_unit1.setText('cm')
            self.deff_man_stack2.setHidden(True)
            self.deff_man_unit2.setHidden(True)
            if sel.lower() == 'deff':
                self.ctx.app_data.mode = DEFF_MANUAL
            else:
                self.ctx.app_data.mode = DEFF_AP if sel.lower(
                ) == 'ap' else DEFF_LAT
        else:
            self.deff_man_stack2.setHidden(False)
            self.deff_man_unit2.setHidden(False)
            if sel.lower() == 'age':
                self.deff_man_stack1.setCurrentIndex(1)
                self.deff_man_stack2.setCurrentIndex(1)
                self.deff_man_unit1.setText('year(s)')
                self.deff_man_unit2.setText('month(s)')
                self.ctx.app_data.mode = DEFF_AGE
            else:
                self.deff_man_stack1.setCurrentIndex(0)
                self.deff_man_stack2.setCurrentIndex(0)
                self.deff_man_edit1.setPlaceholderText('AP')
                self.deff_man_edit2.setPlaceholderText('LAT')
                self.deff_man_unit1.setText('cm')
                self.deff_man_unit2.setText('cm')
                self.ctx.app_data.mode = DEFF_APLAT
            self.d_edit.setReadOnly(True)
        self.deff_manual_method = sel.lower()
        print(self.deff_manual_method)
        self.d_edit.setText('0')

    def _on_dw_manual(self, text):
        try:
            self.ctx.app_data.diameter = float(text)
        except:
            self.ctx.app_data.diameter = 0

    def on_minimum_area_changed(self):
        sender = self.sender()
        self.minimum_area = sender.value()
        if sender == self.deff_minimum_area_sb:
            self.dw_minimum_area_sb.setValue(self.minimum_area)
        else:
            self.deff_minimum_area_sb.setValue(self.minimum_area)

    def on_threshold_changed(self):
        sender = self.sender()
        self.threshold = sender.value()
        if sender == self.deff_threshold_sb:
            self.dw_threshold_sb.setValue(self.threshold)
        else:
            self.deff_threshold_sb.setValue(self.threshold)

    def on_bone_limit_changed(self):
        self.bone_limit = self.bone_sb.value()

    def on_stissue_limit_changed(self):
        self.stissue_limit = self.stissue_sb.value()

    def on_calculate(self):
        self.ctx.app_data.d_mode = 0
        if self.source == 0:  # from img
            if not self.ctx.isImage:
                QMessageBox.warning(None, "Warning", "Open DICOM files first.")
                return
            if self.method == 0:  # auto
                self.calculate_auto()
            elif self.method == 1:  # 3d
                self.ctx.app_data.d_mode = 1
                self.calculate_auto_3d()
            elif self.method == 2:  # manual
                self.calculate_img_manual()
        elif self.source == 1:  # input manual
            self.calculate_manual()
        self.next_tab_btn.setAutoDefault(True)
        self.next_tab_btn.setDefault(True)
        self.calculate_btn.setAutoDefault(False)
        self.calculate_btn.setDefault(False)

    def calculate_auto(self):
        self.ctx.axes.clearGraph()
        img = self.ctx.get_current_img()
        dims = self.ctx.img_dims
        rd = self.ctx.recons_dim
        img_to_show = img.copy()
        dval = 0
        mask = None
        correction = 0

        if self.baseon == 0:  # deff
            mask = self.get_img_mask(img,
                                     threshold=self.threshold,
                                     minimum_area=self.minimum_area,
                                     largest_only=True)
            if mask is None:
                return
            correction = sum(v << i for i, v in enumerate(self.is_corr[::-1]))
            if correction and self.deff_auto_method != 'area':
                center = get_center(
                    mask
                ) if self.deff_auto_method == 'center' else get_center_max(
                    mask)
                corr_mask = get_correction_mask(img,
                                                mask,
                                                lb_bone=self.bone_limit,
                                                lb_stissue=self.stissue_limit)
                dval, ap, lat = get_deff_correction(self.is_corr, corr_mask,
                                                    center, rd)
                row, col = center
                img_to_show = corr_mask
            else:
                dval, row, col, ap, lat = get_deff_value(
                    mask, dims, rd, self.deff_auto_method)
            if self.deff_auto_method != 'area':
                self.plot_ap_lat(mask, row, col)
                self.ap_edit.setText(f'{ap:#.2f} cm')
                self.lat_edit.setText(f'{lat:#.2f} cm')

        elif self.baseon == 1:
            if self.is_no_roi:
                mask = np.ones_like(img, dtype=bool)
                if self.is_no_table:
                    img_to_show = get_img_no_table(img,
                                                   threshold=self.threshold)
                    img = img_to_show.copy()
                img[img < -1000] = -1000
            else:
                mask = self.get_img_mask(img,
                                         threshold=self.threshold,
                                         minimum_area=self.minimum_area,
                                         largest_only=self.is_largest_only)
                if mask is None:
                    return
            dval = get_dw_value(img, mask, dims, rd, self.is_truncated,
                                self.is_largest_only)

        self.d_edit.setText(f'{dval:#.2f}')
        self.ctx.app_data.diameter = dval
        self.ctx.app_data.diameters[self.ctx.current_img] = dval
        self.ctx.app_data.emit_d_changed()

        if isinstance(self.par.window_width, int) and isinstance(
                self.par.window_level, int) and correction == 0:
            img_to_show = windowing(img_to_show, self.par.window_width,
                                    self.par.window_level)
        self.ctx.axes.add_alt_view(img_to_show)
        self.plot_mask(mask)

    def calculate_auto_3d(self):
        self.d_vals = []
        self.idxs = []
        nslice = self.slice1_sb.value()
        dcms = np.array(self.ctx.dicoms)
        index = list(range(len(dcms)))

        if self.d_3d_method == 'slice step':
            idxs = index[::nslice]
            imgs = dcms[::nslice]
        elif self.d_3d_method == 'slice number':
            tmps = np.array_split(np.arange(len(dcms)), nslice)
            idxs = [tmp[len(tmp) // 2] for tmp in tmps]
            imgs = dcms[idxs]
        elif self.d_3d_method == 'regional':
            nslice2 = self.slice2_sb.value()
            first = nslice if nslice <= nslice2 else nslice2
            last = nslice2 if nslice <= nslice2 else nslice
            idxs = index[first - 1:last]
            imgs = dcms[first - 1:last]
        else:
            imgs = dcms
            idxs = index

        avg_dval, idxs = self.get_avg_diameter(imgs, idxs)
        self.d_edit.setText(f'{avg_dval:#.2f}')
        self.ctx.app_data.diameter = avg_dval
        self.idxs = [i + 1 for i in idxs]
        for k, v in zip(self.idxs, self.d_vals):
            self.ctx.app_data.diameters[k] = v
        self.ctx.app_data.emit_d_changed()
        if self.show_graph:
            self.plot_3d_auto()

    def calculate_img_manual(self):
        pass

    def calculate_manual(self):
        if self.baseon == 0:  # deff
            if self.deff_manual_method == 'deff':
                label = 'Effective Diameter'
                unit = 'cm'
                try:
                    dval = float(self.deff_man_edit1.text())
                except:
                    dval = 0
                val1 = dval
                data = np.array(
                    [np.arange(0, 2 * val1, .01) for _ in range(2)]).T
            elif self.deff_manual_method == 'age':
                label = 'Age'
                unit = 'year'
                year = self.year_sb.value()
                month = self.month_sb.value()
                val1 = year + month / 12
                data = self.age_data
                dval = float(interpolate.splev(val1, self.age_interp))
            else:
                unit = 'cm'
                try:
                    val1 = float(self.deff_man_edit1.text())
                except:
                    val1 = 0
                try:
                    val2 = float(self.deff_man_edit2.text())
                except:
                    val2 = 0
                if self.deff_manual_method == 'ap+lat':
                    label = 'AP+LAT'
                    val1 += val2
                    if self.ctx.phantom == HEAD:
                        interp = self.head_latap_interp
                        data = self.head_latap_data
                    else:
                        interp = self.thorax_latap_interp
                        data = self.thorax_latap_data
                elif self.deff_manual_method == 'ap':
                    label = 'AP'
                    if self.ctx.phantom == HEAD:
                        interp = self.head_ap_interp
                        data = self.head_ap_data
                    else:
                        interp = self.thorax_ap_interp
                        data = self.thorax_ap_data
                elif self.deff_manual_method == 'lat':
                    label = 'LAT'
                    if self.ctx.phantom == HEAD:
                        interp = self.head_lat_interp
                        data = self.head_lat_data
                    else:
                        interp = self.thorax_lat_interp
                        data = self.thorax_lat_data
                if val1 < data[0, 0] or val1 > data[-1, 0]:
                    QMessageBox.information(
                        None, "Information",
                        f"The result is an extrapolated value.\nFor the best result, input value between {data[0,0]} and {data[-1,0]}."
                    )
                dval = float(interpolate.splev(val1, interp))

            if self.show_graph:
                self.figure = PlotDialog()
                self.figure.actionEnabled(True)
                self.figure.trendActionEnabled(False)
                self.figure.plot(data,
                                 pen={
                                     'color': "FFFF00",
                                     'width': 2
                                 },
                                 symbol=None)
                self.figure.plot([val1], [dval],
                                 symbol='o',
                                 symbolPen=None,
                                 symbolSize=8,
                                 symbolBrush=(255, 0, 0, 255))
                self.figure.annotate(
                    'deff',
                    pos=(val1, dval),
                    text=
                    f'{label}: {val1:#.2f} {unit}\nEffective Diameter: {dval:#.2f} cm'
                )
                self.figure.axes.showGrid(True, True)
                self.figure.setLabels(label, 'Effective Diameter', unit, 'cm')
                self.figure.setTitle(f'{label} - Deff')
                self.figure.show()
        else:
            dval = float(self.d_edit.text())
        self.d_edit.setText(f'{dval:#.2f}')
        self.ctx.app_data.diameter = dval
        if self.all_slices:
            self.idxs = list(range(1, self.ctx.total_img + 1))
            for idx in self.idxs:
                self.ctx.app_data.diameters[idx] = dval
        else:
            self.ctx.app_data.diameters[self.ctx.current_img] = dval
        self.ctx.app_data.emit_d_changed()

    def clearROIs(self):
        if len(self.ctx.axes.rois) == 0:
            return
        print(self.ctx.axes.rois)
        self.ctx.axes.clearROIs()
        self.deff_ap_edit.setText('0 cm')
        self.deff_lat_edit.setText('0 cm')
        self.ap_edit.setText('0 cm')
        self.lat_edit.setText('0 cm')
        self.d_edit.setText('0')
        self.lineLAT = self.lineAP = 0
        self.ctx.app_data.diameter = 0

    def get_avg_diameter(self, dss, idxs):
        dval = 0
        n = len(dss)
        n_seg = 0
        progress = QProgressDialog(f"Calculating diameter of {n} images...",
                                   "Stop", 0, n, self)
        progress.setWindowModality(Qt.WindowModal)
        progress.setMinimumDuration(1000)
        for idx, dcm in enumerate(dss):
            img = self.ctx.get_img_from_ds(dcm)
            if self.baseon == 0:
                mask = get_mask(img,
                                threshold=self.threshold,
                                minimum_area=self.minimum_area,
                                largest_only=True)
                if mask is not None:
                    n_seg += 1
                    correction = sum(v << i
                                     for i, v in enumerate(self.is_corr[::-1]))
                    if correction and self.deff_auto_method != 'area':
                        center = get_center(
                            mask
                        ) if self.deff_auto_method == 'center' else get_center_max(
                            mask)
                        corr_mask = get_correction_mask(
                            img,
                            mask,
                            lb_bone=self.bone_limit,
                            lb_stissue=self.stissue_limit)
                        res = get_deff_correction(self.is_corr, corr_mask,
                                                  center, self.ctx.recons_dim)
                    else:
                        res = get_deff_value(mask, self.ctx.img_dims,
                                             self.ctx.recons_dim,
                                             self.deff_auto_method)
                    d = res[0]
                else:
                    d = 0
            else:
                if self.is_no_roi:
                    mask = np.ones_like(img, dtype=bool)
                    if self.is_no_table:
                        img = get_img_no_table(img, threshold=self.threshold)
                    img[img < -1000] = -1000
                else:
                    mask = get_mask(img,
                                    threshold=self.threshold,
                                    minimum_area=self.minimum_area,
                                    largest_only=self.is_largest_only)
                if mask is not None:
                    n_seg += 1
                    d = get_dw_value(img, mask, self.ctx.img_dims,
                                     self.ctx.recons_dim, self.is_truncated,
                                     self.is_largest_only)
                else:
                    d = 0
            dval += d
            self.d_vals.append(d)
            progress.setValue(idx)
            if progress.wasCanceled():
                idxs = idxs[:idx + 1]
                break
        progress.setValue(n)
        return dval / n_seg, idxs

    def get_img_mask(self, *args, **kwargs):
        mask = get_mask(*args, **kwargs)
        if mask is None:
            QMessageBox.warning(
                None, 'Segmentation Failed',
                'No object found during segmentation process.')
        return mask

    def plot_mask(self, mask):
        pos = get_mask_pos(mask) + .5
        pos_col = pos[:, 1]
        pos_row = pos[:, 0]
        self.ctx.axes.immarker(pos_col,
                               pos_row,
                               pen=None,
                               symbol='s',
                               symbolPen=None,
                               symbolSize=3,
                               symbolBrush=(255, 0, 0, 255))

    def plot_ap_lat(self, mask, row, col):
        pos = get_mask_pos(mask) + .5
        pos_col = pos[:, 1]
        pos_row = pos[:, 0]
        col += .5
        row += .5
        id_row = [id for id, el in enumerate(pos_col) if el == col]
        id_col = [id for id, el in enumerate(pos_row) if el == row]
        line_v = np.array([pos_col[id_row], pos_row[id_row]]).T
        line_h = np.array([pos_col[id_col], pos_row[id_col]]).T
        self.ctx.axes.plot(line_v,
                           pen={
                               'color': "00FF7F",
                               'width': 2
                           },
                           symbol=None)
        self.ctx.axes.plot(line_h,
                           pen={
                               'color': "00FF7F",
                               'width': 2
                           },
                           symbol=None)
        self.ctx.axes.plot([col], [row],
                           pen=None,
                           symbol='o',
                           symbolPen=None,
                           symbolSize=10,
                           symbolBrush=(255, 127, 0, 255))

    def plot_3d_auto(self):
        xlabel = 'Dw' if self.baseon else 'Deff'
        title = 'Water Equivalent Diameter' if self.baseon else 'Effective Diameter'
        self.figure = PlotDialog()
        self.figure.actionEnabled(True)
        self.figure.trendActionEnabled(False)
        self.figure.axes.scatterPlot.clear()
        self.figure.plot(self.idxs,
                         self.d_vals,
                         pen={
                             'color': "FFFF00",
                             'width': 2
                         },
                         symbol='o',
                         symbolPen=None,
                         symbolSize=8,
                         symbolBrush=(255, 0, 0, 255))
        self.figure.axes.showGrid(True, True)
        self.figure.setLabels('slice', xlabel, '', 'cm')
        self.figure.setTitle(f'Slice - {title}')
        self.figure.show()

    def get_distance(self, p1, p2):
        try:
            col, row = self.ctx.get_current_img().shape
        except:
            return
        rd = self.ctx.recons_dim
        return np.sqrt(
            ((np.array(p2) - np.array(p1))**2).sum()) * (0.1 * (rd / row))

    def _roi_handle_to_tuple(self, handle):
        return (handle.pos().x(), handle.pos().y())

    def add_lat_line(self):
        if not self.ctx.isImage:
            QMessageBox.warning(None, "Warning", "Open DICOM files first.")
            return
        x, y = self.ctx.get_current_img().shape
        self.ctx.axes.addLAT(((x / 2) - 0.25 * x, y / 2),
                             ((x / 2) + 0.25 * x, y / 2))
        self.ctx.axes.lineLAT.sigRegionChanged.connect(self.get_lat_from_line)
        pts = self.ctx.axes.lineLAT.getHandles()
        p1 = self._roi_handle_to_tuple(pts[0])
        p2 = self._roi_handle_to_tuple(pts[1])
        self.lineLAT = self.get_distance(p1, p2)
        self.deff_lat_edit.setText(f'{self.lineLAT:#.2f} cm')
        self.get_deff_from_line()

    def add_ap_line(self):
        if not self.ctx.isImage:
            QMessageBox.warning(None, "Warning", "Open DICOM files first.")
            return
        x, y = self.ctx.get_current_img().shape
        self.ctx.axes.addAP(((x / 2), (y / 2) - 0.25 * y),
                            ((x / 2), (y / 2) + 0.25 * y))
        self.ctx.axes.lineAP.sigRegionChanged.connect(self.get_ap_from_line)
        pts = self.ctx.axes.lineAP.getHandles()
        p1 = self._roi_handle_to_tuple(pts[0])
        p2 = self._roi_handle_to_tuple(pts[1])
        self.lineAP = self.get_distance(p1, p2)
        self.deff_ap_edit.setText(f'{self.lineAP:#.2f} cm')
        self.get_deff_from_line()

    def add_ellipse(self):
        if not self.ctx.isImage:
            QMessageBox.warning(None, "Warning", "Open DICOM files first.")
            return
        self.ctx.axes.addEllipse()
        self.ctx.axes.ellipse.sigRegionChangeFinished.connect(
            self.get_dw_from_ellipse)
        self.get_dw_from_ellipse(self.ctx.axes.ellipse)

    def add_polygon(self):
        if not self.ctx.isImage:
            QMessageBox.warning(None, "Warning", "Open DICOM files first.")
            return
        self.ctx.axes.addPolyFinished.connect(self.get_dw_from_ellipse)
        self.ctx.axes.addPoly()
        self.ctx.axes.poly.sigRegionChangeFinished.connect(
            self.get_dw_from_ellipse)

    def get_lat_from_line(self, roi):
        pts = roi.getHandles()
        p1 = self._roi_handle_to_tuple(pts[0])
        p2 = self._roi_handle_to_tuple(pts[1])
        self.lineLAT = self.get_distance(p1, p2)
        self.deff_lat_edit.setText(f'{self.lineLAT:#.2f} cm')
        self.get_deff_from_line()

    def get_ap_from_line(self, roi):
        pts = roi.getHandles()
        p1 = self._roi_handle_to_tuple(pts[0])
        p2 = self._roi_handle_to_tuple(pts[1])
        self.lineAP = self.get_distance(p1, p2)
        self.deff_ap_edit.setText(f'{self.lineAP:#.2f} cm')
        self.get_deff_from_line()

    def get_deff_from_line(self):
        dval = np.sqrt(self.lineAP * self.lineLAT)
        self.d_edit.setText(f'{dval:#.2f}')
        self.ctx.app_data.diameter = dval
        self.ctx.app_data.diameters[self.ctx.current_img] = dval
        self.ctx.app_data.emit_d_changed()

    def get_dw_from_ellipse(self, roi):
        dims = self.ctx.img_dims
        rd = self.ctx.recons_dim
        img = roi.getArrayRegion(self.ctx.get_current_img(),
                                 self.ctx.axes.image,
                                 returnMappedCoords=False)
        if img.size == 0:
            return
        mask = roi.renderShapeMask(img.shape[0], img.shape[1])
        if not mask.any():
            return
        dval = get_dw_value(img, mask, dims, rd)
        self.d_edit.setText(f'{dval:#.2f}')
        self.ctx.app_data.diameter = dval
        self.ctx.app_data.diameters[self.ctx.current_img] = dval
        self.ctx.app_data.emit_d_changed()

    def img_changed_handle(self, value):
        if value:
            self.reset_fields()

    def sliceopt_handle(self, value):
        self.source_cb.setCurrentIndex(0)
        src = self.source_cb.currentText()
        self.on_source_changed(src)
        self.method_cb.setCurrentIndex(value)
        self.on_set_opts_panel()

    def mode3d_handle(self, value):
        rb = [r for r in self.d_3d_rbtns if r.text().lower() == value]
        rb[0].setChecked(True)

    def slice1_handle(self, value):
        self.slice1_sb.setValue(value)

    def slice2_handle(self, value):
        self.slice2_sb.setValue(value)

    def reset_fields(self):
        self.initVar()
        self.ctx.app_data.diameter = 0
        self.d_edit.setText('0')
        self.ap_edit.setText('0 cm')
        self.lat_edit.setText('0 cm')
        self.deff_ap_edit.setText('0 cm')
        self.deff_lat_edit.setText('0 cm')
        self.deff_man_edit1.clear()
        self.deff_man_edit2.clear()
        self.calculate_btn.setAutoDefault(True)
        self.calculate_btn.setDefault(True)
        self.next_tab_btn.setAutoDefault(False)
        self.next_tab_btn.setDefault(False)
        self.plot_chk.setCheckState(Qt.Unchecked)
Exemplo n.º 3
0
class _ToolsDock(ui_tools.StyledBar):
    def __init__(self, parent=None):
        super().__init__(parent)
        # Register signals connections
        # connections = (
        #    {
        #        "target": "main_container",
        #        "signal_name": "runFile",
        #        "slot": self.execute_file
        #    },
        # )
        # Buttons Widget
        self._buttons_widget = ui_tools.StyledBar()
        self._buttons_widget.setProperty("border", True)
        self._buttons_widget.setFixedHeight(26)
        self._buttons_widget.setLayout(QHBoxLayout())
        self._buttons_widget.layout().setContentsMargins(2, 2, 0, 2)
        self._buttons_widget.layout().setSpacing(10)

        IDE.register_service('tools_dock', self)

    def install(self):
        self.setup_ui()
        ide = IDE.get_service('ide')
        ide.place_me_on('tools_dock', self, 'central')
        ui_tools.install_shortcuts(self, actions.ACTIONS, ide)
        ide.goingDown.connect(self._save_settings)
        settings = IDE.ninja_settings()
        index = int(settings.value("tools_dock/tool_visible", -1))
        if index == -1:
            self.hide()
        else:
            self.set_current_index(index)

    def setup_ui(self):
        self._stack = QStackedWidget()
        self.__current_widget = None
        self.__last_index = -1
        self.__buttons = []

        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(0)

        # toolbar = StyledBar()
        tool_layout = QVBoxLayout()
        tool_layout.setContentsMargins(0, 0, 0, 0)
        tool_layout.setSpacing(0)

        self._run_widget = run_widget.RunWidget()

        main_layout.addLayout(tool_layout)
        self._tool_stack = QStackedWidget()
        self._tool_stack.setMaximumHeight(22)
        # self._tool_stack.setMaximumWidth(22)

        tool_layout.addWidget(self._tool_stack)
        # FIXME: poner en stack
        # clear_btn = QToolButton()
        # clear_btn.setIcon(QIcon(self.style().standardIcon(QStyle.SP_LineEditClearButton)))
        # clear_btn.clicked.connect(self._run_widget.output.clear)
        # tool_layout.addWidget(clear_btn)
        # tool_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding))
        # tool_layout.addWidget(close_button)
        # main_layout.addWidget(toolbar)
        main_layout.addWidget(self._stack)

        # Widgets
        # errors_tree = IDE.get_service('errors_tree')
        from ninja_ide.gui.tools_dock import find_in_files
        self.widgets = [
            self._run_widget,
            console_widget.ConsoleWidget(),
            find_in_files.FindInFilesWidget(),
            # errors_tree
        ]
        # Intall widgets
        number = 1
        for wi in self.widgets:
            if wi is None:
                continue
            btn = ToolButton(number, wi.display_name())
            btn.setCheckable(True)
            # Action
            # action = QAction(wi.display_name(), self)
            # action.triggered.connect(self._triggered)
            number += 1
            self.__buttons.append(btn)
            self._buttons_widget.layout().addWidget(btn)
            self._stack.addWidget(wi)
            btn.clicked.connect(self._button_triggered)
            # Toolbar buttons
            container = QWidget(self._tool_stack)
            tool_buttons_layout = QHBoxLayout()
            tool_buttons_layout.setContentsMargins(0, 0, 0, 0)
            tool_buttons_layout.setSpacing(0)
            for b in wi.button_widgets():
                tool_buttons_layout.addWidget(b)
            tool_buttons_layout.addStretch(5)
            container.setLayout(tool_buttons_layout)
            self._tool_stack.addWidget(container)

        self._buttons_widget.layout().addItem(
            QSpacerItem(0, 0, QSizePolicy.Expanding))
        self.__current_widget = self._stack.currentWidget()

        self.set_current_index(0)

    def execute_file(self):
        """Execute the current file"""

        main_container = IDE.get_service("main_container")
        editor_widget = main_container.get_current_editor()
        if editor_widget is not None and editor_widget.is_modified or \
                editor_widget.file_path:
            main_container.save_file(editor_widget)
            # FIXME: Emit a signal for plugin!
            # self.fileExecuted.emit(editor_widget.file_path)
            file_path = editor_widget.file_path
            extension = file_manager.get_file_extension(file_path)
            # TODO: Remove the IF statment and use Handlers
            if extension == "py":
                self._run_application(file_path)

    def _run_application(self, filename):
        """Execute the process to run the application"""

        self._show(0)  # Show widget in index = 0
        self._run_widget.start_process(filename)
        self._run_widget.input.setFocus()

    @pyqtSlot()
    def _button_triggered(self):
        # Get ToolButton index
        button = self.sender()
        index = self.__buttons.index(button)

        if index == self.current_index() and self._is_current_visible():
            self._hide()
        else:
            self._show(index)

    def _show(self, index):
        self.show()
        self.widgets[index].setVisible(True)
        self.__current_widget = self.widgets[index]
        self.set_current_index(index)

    def _hide(self):
        self.__current_widget.setVisible(False)
        index = self.current_index()
        self.__buttons[index].setChecked(False)
        self.widgets[index].setVisible(False)
        self.hide()

    def showEvent(self, event):
        super().showEvent(event)
        self._stack.currentWidget().setFocus()

    def set_current_index(self, index):

        if self.__last_index != -1:
            self.__buttons[self.__last_index].setChecked(False)
            self.__buttons[index].setChecked(True)

        if index != -1:
            self._stack.setCurrentIndex(index)
            self._tool_stack.setCurrentIndex(index)

            tool = self.widgets[index]
            tool.setVisible(True)
        self.__last_index = index

    def current_index(self):
        return self._stack.currentIndex()

    def _is_current_visible(self):
        return self.__current_widget and self.__current_widget.isVisible()

    def _save_settings(self):
        settings = IDE.ninja_settings()
        visible_index = self.current_index()
        if not self.isVisible():
            visible_index = -1
        settings.setValue("tools_dock/tool_visible", visible_index)
Exemplo n.º 4
0
class OknoSwiat(QWidget):
    def __init__(self, swiat):
        super().__init__()
        self.__swiat = swiat
        self.setWindowTitle("Michał Baranowski 165463")
        self.__screen = QDesktopWidget().screenGeometry()
        self.__wys = self.__screen.height()
        self.__szer = self.__screen.width()
        self.setGeometry(0, 0, self.__szer, self.__wys)

        self.__plansza = Plansza(swiat)
        self.__plansza.setGeometry(0, 0, self.__szer, self.__wys / 2)

        self.__buforowane = QStackedWidget()
        self.__buforowane.setGeometry(0, 0, self.__szer, self.__wys / 2)
        self.__buforowane.setMaximumHeight(self.__wys / 2)
        self.__buforowane.addWidget(self.__plansza)

        self.__komunikaty = QLabel()
        self.__komunikaty.setMaximumWidth(self.__szer / 2 - 100)
        self.__komunikaty.setMaximumHeight(self.__wys / 4)
        self.__komunikaty.setAlignment(Qt.AlignTop)
        self.__komunikaty.setText("roboczy tekst")
        self.__komunikaty.setWordWrap(True)

        self.__sterowanie = QLabel()
        self.__sterowanie.setMaximumWidth(self.__szer / 2 - 100)
        self.__sterowanie.setMaximumHeight(self.__wys / 4)
        self.__sterowanie.setAlignment(Qt.AlignTop)
        self.__sterowanie.setText("roboczy 2")
        self.__sterowanie.setWordWrap(True)

        nowa_tura = QPushButton("Nowa Tura", self)
        nowa_tura.setMaximumHeight(self.__wys / 10)
        nowa_tura.setMaximumWidth(self.__szer / 10)
        nowa_tura.clicked.connect(self.on_click_nowa_tura)
        nowa_tura.setFocusPolicy(Qt.NoFocus)

        zapisz_b = QPushButton("Zapisz Stan", self)
        zapisz_b.setMaximumHeight(self.__wys / 10)
        zapisz_b.setMaximumWidth(self.__szer / 10)
        zapisz_b.clicked.connect(self.on_click_zapisz)
        zapisz_b.setFocusPolicy(Qt.NoFocus)

        wczytaj_b = QPushButton("Wczytaj Stan", self)
        wczytaj_b.setMaximumHeight(self.__wys / 10)
        wczytaj_b.setMaximumWidth(self.__szer / 10)
        wczytaj_b.clicked.connect(self.on_click_wczytaj)
        wczytaj_b.setFocusPolicy(Qt.NoFocus)

        panel_komunikacji = QGroupBox()
        info_layout = QHBoxLayout()
        info_layout.addWidget(self.__komunikaty)
        info_layout.addWidget(self.__sterowanie)
        panel_komunikacji.setLayout(info_layout)
        panel_komunikacji.setMaximumHeight(self.__wys / 4)

        panel_przyciskow = QGroupBox()
        button_layout = QHBoxLayout()
        button_layout.addWidget(nowa_tura)
        button_layout.addWidget(zapisz_b)
        button_layout.addWidget(wczytaj_b)
        panel_przyciskow.setLayout(button_layout)
        panel_przyciskow.setMaximumHeight(self.__wys / 4)

        main_layout = QVBoxLayout()
        main_layout.addWidget(self.__buforowane)
        main_layout.addWidget(panel_komunikacji)
        main_layout.addWidget(panel_przyciskow)
        self.setLayout(main_layout)

    def rysuj_organizmy(self):
        self.__plansza.rysuj_organizmy()

    def reset_planszy(self):
        self.__buforowane.removeWidget(self.__plansza)
        self.__plansza = Plansza(self.__swiat)
        self.__buforowane.addWidget(self.__plansza)

    def ustaw_komunikaty(self):
        caly_tekst = ""
        for info in self.__swiat.get_komunikaty():
            caly_tekst += info
            caly_tekst += "\n"
        self.__komunikaty.setText(caly_tekst)

    def ustaw_panel_sterowania(self, opcja=None):
        caly_tekst = ""
        caly_tekst += "Lista dostępnych akcji: \n"
        czlowiek_zyje = False
        licznik = -1
        # sprawdź czy Człowiek żyje i spisz licznik:
        for org in self.__swiat.get_organizmy():
            if isinstance(org, Czlowiek):
                czlowiek_zyje = True
                licznik = org.get_licznik_tarczy()
                break
        if czlowiek_zyje:
            caly_tekst += ">> klawisze strzałek (prawo, lewo, góra, dół) - ruch Człowieka \n"
            if licznik > 5:
                caly_tekst += "TARCZA ALZURA JEST AKTYWNA \n"
            elif licznik > 0:
                caly_tekst += ("Tarcza Alzura będzie aktywna za " +
                               str(licznik))
                if licznik == 5:
                    caly_tekst += " tur \n"
                elif licznik == 1:
                    caly_tekst += " turę \n"
                else:
                    caly_tekst += " tury \n"
            elif licznik == 0:
                caly_tekst += ">> SPACJA - aktywacja Tarczy Alzura \n"
        else:
            caly_tekst += ">> klawisze strzalek /spacja - kolejna tura \n"

        caly_tekst += ">> dedykowane przyciski - kolejna tura, zapis, odczyt i zakończenie \n"
        caly_tekst += ">> kliknięcie myszką w puste pole - dodanie nowego organizmu z listy \n"
        if opcja is not None:
            caly_tekst += opcja
        self.__sterowanie.setText(caly_tekst)

    def on_click_nowa_tura(self):
        self.__swiat.wykonaj_ture()

    def on_click_zapisz(self):
        self.__swiat.zapisz_swiat()
        self.ustaw_panel_sterowania("Stan gry zapisany do pliku. ")

    def on_click_wczytaj(self):
        self.__swiat.wczytaj_swiat()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self.close()
        elif event.key() == Qt.Key_Up:
            self.__swiat.set_kierunek(Akcje.gora)
            self.__swiat.wykonaj_ture()
        elif event.key() == Qt.Key_Down:
            self.__swiat.set_kierunek(Akcje.dol)
            self.__swiat.wykonaj_ture()
        elif event.key() == Qt.Key_Right:
            self.__swiat.set_kierunek(Akcje.prawo)
            self.__swiat.wykonaj_ture()
        elif event.key() == Qt.Key_Left:
            self.__swiat.set_kierunek(Akcje.lewo)
            self.__swiat.wykonaj_ture()
        elif event.key() == Qt.Key_Space:
            self.__swiat.set_kierunek(Akcje.spacja)
            self.__swiat.wykonaj_ture()
        else:
            pass