def __init__(self, tpm): super(ViaSettingsDialog, self).__init__() self.tpm = tpm self.radius_li = UnitLineEdit(UNIT_GROUP_MM) self.radius_li.setValue(self.tpm.radius) self.layout.addRow("Radius:", self.radius_li)
def __init__(self, parent, model): super(KeypointAlignmentWidget, self).__init__() self.model = model self._parent = parent layout = QtGui.QFormLayout() self.setLayout(layout) keypoint_gb = QtGui.QGroupBox("Keypoint") layout.addWidget(keypoint_gb) edit_layout = QtGui.QFormLayout() keypoint_gb.setLayout(edit_layout) self.kpts_sel = QtGui.QComboBox() self.kpts_sel.setModel(self.model.combo_adapter) self.kpts_sel.currentIndexChanged.connect(self.kptChanged) edit_layout.addRow("Keypoint:", self.kpts_sel) self.wx = UnitLineEdit(UNIT_GROUP_MM) self.wy = UnitLineEdit(UNIT_GROUP_MM) edit_layout.addRow("World X", self.wx) edit_layout.addRow("World Y", self.wy) self.wx.edited.connect(self.update_world) self.wy.edited.connect(self.update_world) self.px = UnitLineEdit(UNIT_GROUP_PX) self.py = UnitLineEdit(UNIT_GROUP_PX) edit_layout.addRow("Image X", self.px) edit_layout.addRow("Image Y", self.py) self.px.edited.connect(self.update_layer) self.py.edited.connect(self.update_layer) self.use_for_alignment = QtGui.QCheckBox() edit_layout.addRow("Use", self.use_for_alignment) self.use_for_alignment.clicked.connect(self.update_used) self.add_btn = QtGui.QPushButton("Add New") self.add_btn.clicked.connect(self.addKeypoint) self.del_btn = QtGui.QPushButton("Remove Current") self.del_btn.clicked.connect(self.delKeypoint) bhl = QtGui.QHBoxLayout() bhl.addWidget(self.add_btn) bhl.addWidget(self.del_btn) edit_layout.addRow(bhl) self.constraint_status_lbl = QtGui.QLabel("") self.constraint_status_lbl.setWordWrap(True) layout.addRow(self.constraint_status_lbl) self.model.changed.connect(self.modelChanged) self.modelChanged()
def __init__(self, model, attr, unitgroup, defaultunit=None): self.widget = UnitLineEdit(unitgroup) self.widget.suppress_enter = False self.model = model self.attr = attr path = self.attr.split('.') self.path = path[:-1] self.subattr = path[-1] self.load()
class ViaSettingsDialog(SettingsDialog): def __init__(self, tpm): super(ViaSettingsDialog, self).__init__() self.tpm = tpm self.radius_li = UnitLineEdit(UNIT_GROUP_MM) self.radius_li.setValue(self.tpm.radius) self.layout.addRow("Radius:", self.radius_li) @QtCore.Slot() def accept(self): self.tpm.radius = self.radius_li.getValue() QtGui.QDialog.accept(self)
def __init__(self, parent: 'LayerAlignmentDialog', model: KeypointAlignmentModel) -> None: super(KeypointAlignmentWidget, self).__init__() self.model = model self._parent = parent layout = QtWidgets.QFormLayout() self.setLayout(layout) keypoint_gb = QtWidgets.QGroupBox("Keypoint") layout.addWidget(keypoint_gb) edit_layout = QtWidgets.QFormLayout() keypoint_gb.setLayout(edit_layout) self.kpts_sel = QtWidgets.QComboBox() self.kpts_sel.setModel(self.model.combo_adapter) self.kpts_sel.currentIndexChanged.connect(self.kptChanged) edit_layout.addRow("Keypoint:", self.kpts_sel) self.wx = UnitLineEdit(UNIT_GROUP_MM) self.wy = UnitLineEdit(UNIT_GROUP_MM) edit_layout.addRow("World X", self.wx) edit_layout.addRow("World Y", self.wy) self.wx.edited.connect(self.update_world) self.wy.edited.connect(self.update_world) self.px = UnitLineEdit(UNIT_GROUP_PX) self.py = UnitLineEdit(UNIT_GROUP_PX) edit_layout.addRow("Image X", self.px) edit_layout.addRow("Image Y", self.py) self.px.edited.connect(self.update_layer) self.py.edited.connect(self.update_layer) self.use_for_alignment = QtWidgets.QCheckBox() edit_layout.addRow("Use", self.use_for_alignment) self.use_for_alignment.clicked.connect(self.update_used) self.add_btn = QtWidgets.QPushButton("Add New") self.add_btn.clicked.connect(self.addKeypoint) self.del_btn = QtWidgets.QPushButton("Remove Current") self.del_btn.clicked.connect(self.delKeypoint) bhl = QtWidgets.QHBoxLayout() bhl.addWidget(self.add_btn) bhl.addWidget(self.del_btn) edit_layout.addRow(bhl) self.constraint_status_lbl = QtWidgets.QLabel("") self.constraint_status_lbl.setWordWrap(True) layout.addRow(self.constraint_status_lbl) self.model.changed.connect(self.modelChanged) self.modelChanged()
def __init__(self, model, attr, unitgroup, defaultunit=None): self.widget = UnitLineEdit(unitgroup) self.widget.suppress_enter = False self.model = model self.attr = attr path = self.attr.split(".") self.path = path[:-1] self.subattr = path[-1] self.load()
class UnitEditable(object): def __init__(self, model, attr, unitgroup, defaultunit=None): self.widget = UnitLineEdit(unitgroup) self.widget.suppress_enter = False self.model = model self.attr = attr path = self.attr.split('.') self.path = path[:-1] self.subattr = path[-1] self.load() def _get_par_obj(self): obj = self.model for p_cmp in self.path: obj = getattr(obj, p_cmp) return obj def load(self): par = self._get_par_obj() elem = getattr(par, self.subattr) self.widget.setValue(elem) def save(self): v = self.value par = self._get_par_obj() setattr(par, self.subattr, v) @property def value(self): return self.widget.getValue() @value.setter def value(self, v): self.widget.setValue(v)
class UnitEditable(object): def __init__(self, model, attr, unitgroup, defaultunit=None): self.widget = UnitLineEdit(unitgroup) self.widget.suppress_enter = False self.model = model self.attr = attr path = self.attr.split(".") self.path = path[:-1] self.subattr = path[-1] self.load() def _get_par_obj(self): obj = self.model for p_cmp in self.path: obj = getattr(obj, p_cmp) return obj def load(self): par = self._get_par_obj() elem = getattr(par, self.subattr) self.widget.setValue(elem) def save(self): v = self.value par = self._get_par_obj() setattr(par, self.subattr, v) @property def value(self): return self.widget.getValue() @value.setter def value(self, v): self.widget.setValue(v)
def __init__(self, parent: 'LayerAlignmentDialog', model: RectAlignmentModel) -> None: super(RectAlignSettingsWidget, self).__init__() self._parent = parent self.model = model layout = QtWidgets.QFormLayout() self.setLayout(layout) dims_gb = QtWidgets.QGroupBox("Scale") dims_gb_layout = QtWidgets.QFormLayout() dims_gb.setLayout(dims_gb_layout) layout.addWidget(dims_gb) self.dims_locked_cb = QtWidgets.QCheckBox() self.dims_locked_cb.clicked.connect(self.set_dims_locked) self.dims_1 = UnitLineEdit(UNIT_GROUP_MM) self.dims_2 = UnitLineEdit(UNIT_GROUP_MM) self.dims_1.edited.connect(self.changed_dim) self.dims_2.edited.connect(self.changed_dim) dims_gb_layout.addRow("Dims on perimeter", self.dims_locked_cb) dims_gb_layout.addRow("Dimension 1", self.dims_1) dims_gb_layout.addRow("Dimension 2", self.dims_2) origin_gb = QtWidgets.QGroupBox("Origin") origin_gb_layout = QtWidgets.QFormLayout() origin_gb.setLayout(origin_gb_layout) layout.addWidget(origin_gb) self.origin_ref = QtWidgets.QComboBox() self.origin_ref.addItem("Lower-left") self.origin_ref.addItem("Lower-right") self.origin_ref.addItem("Upper-left") self.origin_ref.addItem("Upper-right") origin_gb_layout.addRow(self.origin_ref) self.origin_ref.currentIndexChanged.connect(self.ref_changed) self.origin_x = PLineEdit() self.origin_y = PLineEdit() self.origin_x.editingFinished.connect(self.changed_dim) self.origin_y.editingFinished.connect(self.changed_dim) origin_gb_layout.addRow("Offset X:", self.origin_x) origin_gb_layout.addRow("Offset Y:", self.origin_y) layout.addWidget(origin_gb) fr_gb = QtWidgets.QGroupBox("Flip/Rotate") fr_gb_layout = QtWidgets.QHBoxLayout() fr_gb.setLayout(fr_gb_layout) self.flip_x_btn = QtWidgets.QPushButton("Flip X") self.flip_x_btn.setCheckable(True) fr_gb_layout.addWidget(self.flip_x_btn) self.flip_y_btn = QtWidgets.QPushButton("Flip Y") self.flip_y_btn.setCheckable(True) fr_gb_layout.addWidget(self.flip_y_btn) fr_gb_layout.addStretch() fr_gb_layout.addWidget(QtWidgets.QLabel("Rotate:")) self.theta_le = ThetaLineEdit() fr_gb_layout.addWidget(self.theta_le) fr_gb_layout.addWidget(QtWidgets.QLabel("\u00b0")) self.flip_x_btn.clicked.connect(self.rotate_flip_changed) self.flip_y_btn.clicked.connect(self.rotate_flip_changed) self.theta_le.editingFinished.connect(self.rotate_flip_changed) layout.addWidget(fr_gb) self.model.update_matricies() self.update_from_model()
class RectAlignSettingsWidget(QtWidgets.QWidget): def __init__(self, parent: 'LayerAlignmentDialog', model: RectAlignmentModel) -> None: super(RectAlignSettingsWidget, self).__init__() self._parent = parent self.model = model layout = QtWidgets.QFormLayout() self.setLayout(layout) dims_gb = QtWidgets.QGroupBox("Scale") dims_gb_layout = QtWidgets.QFormLayout() dims_gb.setLayout(dims_gb_layout) layout.addWidget(dims_gb) self.dims_locked_cb = QtWidgets.QCheckBox() self.dims_locked_cb.clicked.connect(self.set_dims_locked) self.dims_1 = UnitLineEdit(UNIT_GROUP_MM) self.dims_2 = UnitLineEdit(UNIT_GROUP_MM) self.dims_1.edited.connect(self.changed_dim) self.dims_2.edited.connect(self.changed_dim) dims_gb_layout.addRow("Dims on perimeter", self.dims_locked_cb) dims_gb_layout.addRow("Dimension 1", self.dims_1) dims_gb_layout.addRow("Dimension 2", self.dims_2) origin_gb = QtWidgets.QGroupBox("Origin") origin_gb_layout = QtWidgets.QFormLayout() origin_gb.setLayout(origin_gb_layout) layout.addWidget(origin_gb) self.origin_ref = QtWidgets.QComboBox() self.origin_ref.addItem("Lower-left") self.origin_ref.addItem("Lower-right") self.origin_ref.addItem("Upper-left") self.origin_ref.addItem("Upper-right") origin_gb_layout.addRow(self.origin_ref) self.origin_ref.currentIndexChanged.connect(self.ref_changed) self.origin_x = PLineEdit() self.origin_y = PLineEdit() self.origin_x.editingFinished.connect(self.changed_dim) self.origin_y.editingFinished.connect(self.changed_dim) origin_gb_layout.addRow("Offset X:", self.origin_x) origin_gb_layout.addRow("Offset Y:", self.origin_y) layout.addWidget(origin_gb) fr_gb = QtWidgets.QGroupBox("Flip/Rotate") fr_gb_layout = QtWidgets.QHBoxLayout() fr_gb.setLayout(fr_gb_layout) self.flip_x_btn = QtWidgets.QPushButton("Flip X") self.flip_x_btn.setCheckable(True) fr_gb_layout.addWidget(self.flip_x_btn) self.flip_y_btn = QtWidgets.QPushButton("Flip Y") self.flip_y_btn.setCheckable(True) fr_gb_layout.addWidget(self.flip_y_btn) fr_gb_layout.addStretch() fr_gb_layout.addWidget(QtWidgets.QLabel("Rotate:")) self.theta_le = ThetaLineEdit() fr_gb_layout.addWidget(self.theta_le) fr_gb_layout.addWidget(QtWidgets.QLabel("\u00b0")) self.flip_x_btn.clicked.connect(self.rotate_flip_changed) self.flip_y_btn.clicked.connect(self.rotate_flip_changed) self.theta_le.editingFinished.connect(self.rotate_flip_changed) layout.addWidget(fr_gb) self.model.update_matricies() self.update_from_model() def update_from_model(self) -> None: self.dims_1.setPlaceholderValue(self.model.placeholder_dim_values[0]) self.dims_2.setPlaceholderValue(self.model.placeholder_dim_values[1]) self.dims_1.setValue(self.model.dim_values[0]) self.dims_2.setValue(self.model.dim_values[1]) self.dims_locked_cb.setChecked(self.model.dims_locked) self.origin_x.setText("%f" % self.model.translate_x) self.origin_y.setText("%f" % self.model.translate_y) # Updated the box index without forcing a retrigger self.origin_ref.blockSignals(True) self.origin_ref.setCurrentIndex(self.model.origin_idx) self.origin_ref.blockSignals(False) self.flip_x_btn.setChecked(self.model.flip_x) self.flip_y_btn.setChecked(self.model.flip_y) self.theta_le.setText("%4.1f" % math.degrees(self.model.rotate_theta)) def rotate_flip_changed(self) -> None: theta = math.radians(float(self.theta_le.text())) cmd = cmd_set_rotate(self.model, theta, self.flip_x_btn.isChecked(), self.flip_y_btn.isChecked()) self._parent.undoStack.push(cmd) def set_dims_locked(self) -> None: cmd = cmd_set_dimensions_locked(self.model, self.dims_locked_cb.isChecked()) self._parent.undoStack.push(cmd) def changed_dim(self) -> None: dim_a = self.dims_1.getValue() dim_b = self.dims_2.getValue() translate_x = float(self.origin_x.text()) translate_y = float(self.origin_y.text()) if dim_a != self.model.dim_values[0] or dim_b != self.model.dim_values[1] or \ translate_x != self.model.translate_x or translate_y != self.model.translate_y: cmd = cmd_set_dimensions(self.model, dim_a, dim_b, translate_x, translate_y) self._parent.undoStack.push(cmd) def ref_changed(self, idx: int) -> None: # Ordering in the combo box isn't pure counterclockwise. Map ordering to CCW if idx == 2: idx = 3 elif idx == 3: idx = 2 cmd = cmd_set_origin_reference(self.model, idx) self._parent.undoStack.push(cmd)
def __init__(self, parent, model): super(RectAlignSettingsWidget, self).__init__() self._parent = parent self.model = model layout = QtGui.QFormLayout() self.setLayout(layout) dims_gb = QtGui.QGroupBox("Scale") dims_gb_layout = QtGui.QFormLayout() dims_gb.setLayout(dims_gb_layout) layout.addWidget(dims_gb) self.dims_locked_cb = QtGui.QCheckBox() self.dims_locked_cb.clicked.connect(self.set_dims_locked) self.dims_1 = UnitLineEdit(UNIT_GROUP_MM) self.dims_2 = UnitLineEdit(UNIT_GROUP_MM) self.dims_1.edited.connect(self.changed_dim) self.dims_2.edited.connect(self.changed_dim) dims_gb_layout.addRow("Dims on perimeter", self.dims_locked_cb) dims_gb_layout.addRow("Dimension 1", self.dims_1) dims_gb_layout.addRow("Dimension 2", self.dims_2) origin_gb = QtGui.QGroupBox("Origin") origin_gb_layout = QtGui.QFormLayout() origin_gb.setLayout(origin_gb_layout) layout.addWidget(origin_gb) self.origin_ref = QtGui.QComboBox() self.origin_ref.addItem("Lower-left") self.origin_ref.addItem("Lower-right") self.origin_ref.addItem("Upper-left") self.origin_ref.addItem("Upper-right") origin_gb_layout.addRow(self.origin_ref) self.origin_ref.currentIndexChanged.connect(self.ref_changed) self.origin_x = PLineEdit() self.origin_y = PLineEdit() self.origin_x.editingFinished.connect(self.changed_dim) self.origin_y.editingFinished.connect(self.changed_dim) origin_gb_layout.addRow("Offset X:", self.origin_x) origin_gb_layout.addRow("Offset Y:", self.origin_y) layout.addWidget(origin_gb) fr_gb = QtGui.QGroupBox("Flip/Rotate") fr_gb_layout = QtGui.QHBoxLayout() fr_gb.setLayout(fr_gb_layout) self.flip_x_btn = QtGui.QPushButton("Flip X") self.flip_x_btn.setCheckable(True) fr_gb_layout.addWidget(self.flip_x_btn) self.flip_y_btn = QtGui.QPushButton("Flip Y") self.flip_y_btn.setCheckable(True) fr_gb_layout.addWidget(self.flip_y_btn) fr_gb_layout.addStretch() fr_gb_layout.addWidget(QtGui.QLabel("Rotate:")) self.theta_le = ThetaLineEdit() fr_gb_layout.addWidget(self.theta_le) fr_gb_layout.addWidget(QtGui.QLabel("\u00b0")) self.flip_x_btn.clicked.connect(self.rotate_changed) self.flip_y_btn.clicked.connect(self.rotate_changed) self.theta_le.editingFinished.connect(self.rotate_changed) layout.addWidget(fr_gb) self.model.changed.connect(self.update_controls_ra) self.model.update_matricies() self.update_controls_ra()
class RectAlignSettingsWidget(QtGui.QWidget): def __init__(self, parent, model): super(RectAlignSettingsWidget, self).__init__() self._parent = parent self.model = model layout = QtGui.QFormLayout() self.setLayout(layout) dims_gb = QtGui.QGroupBox("Scale") dims_gb_layout = QtGui.QFormLayout() dims_gb.setLayout(dims_gb_layout) layout.addWidget(dims_gb) self.dims_locked_cb = QtGui.QCheckBox() self.dims_locked_cb.clicked.connect(self.set_dims_locked) self.dims_1 = UnitLineEdit(UNIT_GROUP_MM) self.dims_2 = UnitLineEdit(UNIT_GROUP_MM) self.dims_1.edited.connect(self.changed_dim) self.dims_2.edited.connect(self.changed_dim) dims_gb_layout.addRow("Dims on perimeter", self.dims_locked_cb) dims_gb_layout.addRow("Dimension 1", self.dims_1) dims_gb_layout.addRow("Dimension 2", self.dims_2) origin_gb = QtGui.QGroupBox("Origin") origin_gb_layout = QtGui.QFormLayout() origin_gb.setLayout(origin_gb_layout) layout.addWidget(origin_gb) self.origin_ref = QtGui.QComboBox() self.origin_ref.addItem("Lower-left") self.origin_ref.addItem("Lower-right") self.origin_ref.addItem("Upper-left") self.origin_ref.addItem("Upper-right") origin_gb_layout.addRow(self.origin_ref) self.origin_ref.currentIndexChanged.connect(self.ref_changed) self.origin_x = PLineEdit() self.origin_y = PLineEdit() self.origin_x.editingFinished.connect(self.changed_dim) self.origin_y.editingFinished.connect(self.changed_dim) origin_gb_layout.addRow("Offset X:", self.origin_x) origin_gb_layout.addRow("Offset Y:", self.origin_y) layout.addWidget(origin_gb) fr_gb = QtGui.QGroupBox("Flip/Rotate") fr_gb_layout = QtGui.QHBoxLayout() fr_gb.setLayout(fr_gb_layout) self.flip_x_btn = QtGui.QPushButton("Flip X") self.flip_x_btn.setCheckable(True) fr_gb_layout.addWidget(self.flip_x_btn) self.flip_y_btn = QtGui.QPushButton("Flip Y") self.flip_y_btn.setCheckable(True) fr_gb_layout.addWidget(self.flip_y_btn) fr_gb_layout.addStretch() fr_gb_layout.addWidget(QtGui.QLabel("Rotate:")) self.theta_le = ThetaLineEdit() fr_gb_layout.addWidget(self.theta_le) fr_gb_layout.addWidget(QtGui.QLabel("\u00b0")) self.flip_x_btn.clicked.connect(self.rotate_changed) self.flip_y_btn.clicked.connect(self.rotate_changed) self.theta_le.editingFinished.connect(self.rotate_changed) layout.addWidget(fr_gb) self.model.changed.connect(self.update_controls_ra) self.model.update_matricies() self.update_controls_ra() def update_controls_ra(self): self.dims_1.setPlaceholderText("%f" % self.model.placeholder_dim_values[0]) self.dims_2.setPlaceholderText("%f" % self.model.placeholder_dim_values[1]) self.dims_1.setValue(self.model.dim_values[0]) self.dims_2.setValue(self.model.dim_values[1]) self.dims_locked_cb.setChecked(self.model.dims_locked) self.origin_x.setText("%f" % self.model.translate_x) self.origin_y.setText("%f" % self.model.translate_y) # Updated the box index without forcing a retrigger self.origin_ref.blockSignals(True) self.origin_ref.setCurrentIndex(self.model.origin_idx) self.origin_ref.blockSignals(False) self.flip_x_btn.setChecked(self.model.flip_x) self.flip_y_btn.setChecked(self.model.flip_y) self.theta_le.setText("%4.1f" % math.degrees(self.model.rotate_theta)) def rotate_changed(self): theta = math.radians(float(self.theta_le.text())) cmd = cmd_set_rotate(self.model, theta, self.flip_x_btn.isChecked(), self.flip_y_btn.isChecked()) self._parent.undoStack.push(cmd) def set_dims_locked(self): cmd = cmd_set_dimensions_locked(self.model, self.dims_locked_cb.isChecked()) self._parent.undoStack.push(cmd) def changed_dim(self): dim_a = self.dims_1.getValue() dim_b = self.dims_2.getValue() translate_x = float(self.origin_x.text()) translate_y = float(self.origin_y.text()) if dim_a != self.model.dim_values[0] or dim_b != self.model.dim_values[1] or \ translate_x != self.model.translate_x or translate_y != self.model.translate_y: cmd = cmd_set_dimensions(self.model, dim_a, dim_b, translate_x, translate_y) self._parent.undoStack.push(cmd) def ref_changed(self, idx): # Ordering in the combo box isn't pure counterclockwise. Map ordering to CCW if idx == 2: idx = 3 elif idx == 3: idx = 2 cmd = cmd_set_origin_reference(self.model, idx) self._parent.undoStack.push(cmd)
class KeypointAlignmentWidget(QtWidgets.QWidget): def __init__(self, parent: 'LayerAlignmentDialog', model: KeypointAlignmentModel) -> None: super(KeypointAlignmentWidget, self).__init__() self.model = model self._parent = parent layout = QtWidgets.QFormLayout() self.setLayout(layout) keypoint_gb = QtWidgets.QGroupBox("Keypoint") layout.addWidget(keypoint_gb) edit_layout = QtWidgets.QFormLayout() keypoint_gb.setLayout(edit_layout) self.kpts_sel = QtWidgets.QComboBox() self.kpts_sel.setModel(self.model.combo_adapter) self.kpts_sel.currentIndexChanged.connect(self.kptChanged) edit_layout.addRow("Keypoint:", self.kpts_sel) self.wx = UnitLineEdit(UNIT_GROUP_MM) self.wy = UnitLineEdit(UNIT_GROUP_MM) edit_layout.addRow("World X", self.wx) edit_layout.addRow("World Y", self.wy) self.wx.edited.connect(self.update_world) self.wy.edited.connect(self.update_world) self.px = UnitLineEdit(UNIT_GROUP_PX) self.py = UnitLineEdit(UNIT_GROUP_PX) edit_layout.addRow("Image X", self.px) edit_layout.addRow("Image Y", self.py) self.px.edited.connect(self.update_layer) self.py.edited.connect(self.update_layer) self.use_for_alignment = QtWidgets.QCheckBox() edit_layout.addRow("Use", self.use_for_alignment) self.use_for_alignment.clicked.connect(self.update_used) self.add_btn = QtWidgets.QPushButton("Add New") self.add_btn.clicked.connect(self.addKeypoint) self.del_btn = QtWidgets.QPushButton("Remove Current") self.del_btn.clicked.connect(self.delKeypoint) bhl = QtWidgets.QHBoxLayout() bhl.addWidget(self.add_btn) bhl.addWidget(self.del_btn) edit_layout.addRow(bhl) self.constraint_status_lbl = QtWidgets.QLabel("") self.constraint_status_lbl.setWordWrap(True) layout.addRow(self.constraint_status_lbl) self.model.changed.connect(self.modelChanged) self.modelChanged() def addKeypoint(self) -> None: cmd = cmd_add_keypoint(self.model) self._parent.undoStack.push(cmd) self.kpts_sel.setCurrentIndex(cmd.index) def delKeypoint(self) -> None: cmd = cmd_del_keypoint(self.model, self.model.selected_idx) self._parent.undoStack.push(cmd) def modelChanged(self) -> None: cmb_index = -1 if self.model.selected_idx is None else self.model.selected_idx self.kpts_sel.blockSignals(True) self.kpts_sel.setCurrentIndex(cmb_index) self.kpts_sel.blockSignals(False) self.updateTextViews() def kptChanged(self) -> None: """ Called when keypoint combo-box drop down changed :return: """ idx: Optional[int] = self.kpts_sel.currentIndex() if idx == -1: idx = None self.model.selected_idx = idx def update_world(self) -> None: idx = self.kpts_sel.currentIndex() vx = self.wx.getValue() vy = self.wy.getValue() if vx is None or vy is None: # TODO - flash bad box? return p = Vec2(vx, vy) cmd = cmd_set_keypoint_world(self.model, idx, p) self._parent.undoStack.push(cmd) def update_layer(self) -> None: idx = self.kpts_sel.currentIndex() vx = self.px.getValue() vy = self.py.getValue() if vx is None or vy is None: # TODO - flash bad box? return p = Vec2(vx, vy) cmd = cmd_set_keypoint_px(self.model, idx, p) self._parent.undoStack.push(cmd) def update_used(self) -> None: idx = self.kpts_sel.currentIndex() cmd = cmd_set_keypoint_used(self.model, idx, self.use_for_alignment.isChecked()) self._parent.undoStack.push(cmd) def updateTextViews(self) -> None: idx = self.model.selected_idx # Disable keypoint delete when we selected a prior-existing keypoint # Also disable delete button when no kp is selected self.del_btn.setEnabled(idx is not None and self.model.keypoints[idx].is_new) self.updateConstraintLabel() # If nothing is selected, clear-out all the edit fields if idx is None: self.wx.setValue(None) self.wy.setValue(None) self.px.setValue(None) self.py.setValue(None) self.wx.setEnabled(False) self.wy.setEnabled(False) self.px.setEnabled(False) self.py.setEnabled(False) self.use_for_alignment.setEnabled(False) self.use_for_alignment.setChecked(False) return kpt = self.model.keypoints[idx] # Disable editing of old keypoints self.wx.setEnabled(kpt.is_new) self.wy.setEnabled(kpt.is_new) self.wx.setValue(kpt.world.x) self.wy.setValue(kpt.world.y) self.use_for_alignment.setEnabled(True) self.use_for_alignment.setChecked(kpt.use) self.px.setEnabled(kpt.use) self.py.setEnabled(kpt.use) self.px.setValue(kpt.layer.x) self.py.setValue(kpt.layer.y) def updateConstraintLabel(self) -> None: cs = self.model.constraint_info if cs == Constraint.Unconstrained: self.constraint_status_lbl.setText( "Image is unconstrained. Will not be aligned in world space. " + "This is probably not what you want") elif cs == Constraint.Translation: self.constraint_status_lbl.setText( "Image is constrained only by one keypoint. This will only position " + "the image in space, but not provide scale or alignment information. " + "This is probably not what you want") elif cs == Constraint.Rotate_Scale: self.constraint_status_lbl.setText( "Image is constrained by two keypoints. This will only position, " + "proportionally scale and rotate the image. That may be OK for " + "scanned images") elif cs == Constraint.Orthogonal: self.constraint_status_lbl.setText( "Image is constrained by three keypoints. This allows alignment of " + "scale, rotation, translation and shear. This is probably not what " + "you want, but may be useful for synthetically transformed images" ) elif cs == Constraint.Perspective: self.constraint_status_lbl.setText( "Image is constrained by four keypoints. This allows for full recovery" + " of the perspective transform. This is probably what you want " + "for camera imagery.") elif cs == Constraint.Singular: self.constraint_status_lbl.setText( "Can't solve for these constraints. Are keypoints overlapping or " + "colinear in either world or image space?") elif cs == Constraint.Overconstrained: self.constraint_status_lbl.setText( "Too many constraints to solve for. " + "Max 4 enabled keypoints for alignment.")
class KeypointAlignmentWidget(QtGui.QWidget): def __init__(self, parent, model): super(KeypointAlignmentWidget, self).__init__() self.model = model self._parent = parent layout = QtGui.QFormLayout() self.setLayout(layout) keypoint_gb = QtGui.QGroupBox("Keypoint") layout.addWidget(keypoint_gb) edit_layout = QtGui.QFormLayout() keypoint_gb.setLayout(edit_layout) self.kpts_sel = QtGui.QComboBox() self.kpts_sel.setModel(self.model.combo_adapter) self.kpts_sel.currentIndexChanged.connect(self.kptChanged) edit_layout.addRow("Keypoint:", self.kpts_sel) self.wx = UnitLineEdit(UNIT_GROUP_MM) self.wy = UnitLineEdit(UNIT_GROUP_MM) edit_layout.addRow("World X", self.wx) edit_layout.addRow("World Y", self.wy) self.wx.edited.connect(self.update_world) self.wy.edited.connect(self.update_world) self.px = UnitLineEdit(UNIT_GROUP_PX) self.py = UnitLineEdit(UNIT_GROUP_PX) edit_layout.addRow("Image X", self.px) edit_layout.addRow("Image Y", self.py) self.px.edited.connect(self.update_layer) self.py.edited.connect(self.update_layer) self.use_for_alignment = QtGui.QCheckBox() edit_layout.addRow("Use", self.use_for_alignment) self.use_for_alignment.clicked.connect(self.update_used) self.add_btn = QtGui.QPushButton("Add New") self.add_btn.clicked.connect(self.addKeypoint) self.del_btn = QtGui.QPushButton("Remove Current") self.del_btn.clicked.connect(self.delKeypoint) bhl = QtGui.QHBoxLayout() bhl.addWidget(self.add_btn) bhl.addWidget(self.del_btn) edit_layout.addRow(bhl) self.constraint_status_lbl = QtGui.QLabel("") self.constraint_status_lbl.setWordWrap(True) layout.addRow(self.constraint_status_lbl) self.model.changed.connect(self.modelChanged) self.modelChanged() def addKeypoint(self): cmd = cmd_add_keypoint(self.model) self._parent.undoStack.push(cmd) self.kpts_sel.setCurrentIndex(cmd.index) def delKeypoint(self): cmd = cmd_del_keypoint(self.model, self.model.selected_idx) self._parent.undoStack.push(cmd) def modelChanged(self): cmb_index = -1 if self.model.selected_idx is None else self.model.selected_idx self.kpts_sel.blockSignals(True) self.kpts_sel.setCurrentIndex(cmb_index) self.kpts_sel.blockSignals(False) self.updateTextViews() def kptChanged(self): """ Called when keypoint combo-box drop down changed :return: """ idx = self.kpts_sel.currentIndex() if idx == -1: idx = None self.model.selected_idx = idx def update_world(self): idx = self.kpts_sel.currentIndex() p = Point2(self.wx.getValue(), self.wy.getValue()) cmd = cmd_set_keypoint_world(self.model, idx, p) self._parent.undoStack.push(cmd) def update_layer(self): idx = self.kpts_sel.currentIndex() p = Point2(self.px.getValue(), self.py.getValue()) cmd = cmd_set_keypoint_px(self.model, idx, p) self._parent.undoStack.push(cmd) def update_used(self): idx = self.kpts_sel.currentIndex() cmd = cmd_set_keypoint_used(self.model, idx, self.use_for_alignment.isChecked()) self._parent.undoStack.push(cmd) def updateTextViews(self): idx = self.model.selected_idx # Disable keypoint delete when we selected a prior-existing keypoint # Also disable delete button when no kp is selected self.del_btn.setEnabled(idx is not None and self.model.keypoints[idx].is_new) self.updateConstraintLabel() # If nothing is selected, clear-out all the edit fields if idx is None: self.wx.setValue(None) self.wy.setValue(None) self.px.setValue(None) self.py.setValue(None) self.wx.setEnabled(False) self.wy.setEnabled(False) self.px.setEnabled(False) self.py.setEnabled(False) self.use_for_alignment.setEnabled(False) self.use_for_alignment.setChecked(False) return kpt = self.model.keypoints[idx] # Disable editing of old keypoints self.wx.setEnabled(kpt.is_new) self.wy.setEnabled(kpt.is_new) self.wx.setValue(kpt.world.x) self.wy.setValue(kpt.world.y) self.use_for_alignment.setEnabled(True) self.use_for_alignment.setChecked(kpt.use) self.px.setEnabled(kpt.use) self.py.setEnabled(kpt.use) self.px.setValue(kpt.layer.x) self.py.setValue(kpt.layer.y) def updateConstraintLabel(self): cs = self.model.constraint_info if cs == CONS_UNCONSTRAINED: self.constraint_status_lbl.setText("Image is unconstrained. Will not be aligned in world space. " + "This is probably not what you want") elif cs == CONS_TRANSLATION: self.constraint_status_lbl.setText("Image is constrained only by one keypoint. This will only position " + "the image in space, but not provide scale or alignment information. " + "This is probably not what you want") elif cs == CONS_ROTATE_SCALE: self.constraint_status_lbl.setText("Image is constrained by two keypoints. This will only position, " + "proportionally scale and rotate the image. That may be OK for " + "scanned images") elif cs == CONS_ORTHOGONAL: self.constraint_status_lbl.setText("Image is constrained by three keypoints. This allows alignment of " + "scale, rotation, translation and shear. This is probably not what " + "you want, but may be useful for synthetically transformed images") elif cs == CONS_PERSPECTIVE: self.constraint_status_lbl.setText("Image is constrained by four keypoints. This allows for full recovery" + " of the perspective transform. This is probably what you want " + "for camera imagery.") elif cs == CONS_SINGULAR: self.constraint_status_lbl.setText("Can't solve for these constraints. Are keypoints overlapping or "+ "colinear in either world or image space?") elif cs == CONS_OVERCONSTRAINED: self.constraint_status_lbl.setText("Too many constraints to solve for. " + "Max 4 enabled keypoints for alignment.")