Пример #1
0
    def _command(self, node, channel):
        attrs = ['name', 'path', 'description', 'hidden', 'groups', 'enum', 'typeStr', 'disp']

        if node.isinstance(pyrogue.RemoteCommand):
            attrs += ['offset', 'bitSize', 'bitOffset', 'varBytes']

        msgBox = QDialog()
        msgBox.setWindowTitle("Command Information For {}".format(node.name))
        msgBox.setMinimumWidth(400)

        vb = QVBoxLayout()
        msgBox.setLayout(vb)

        fl = QFormLayout()
        fl.setRowWrapPolicy(QFormLayout.DontWrapRows)
        fl.setFormAlignment(Qt.AlignHCenter | Qt.AlignTop)
        fl.setLabelAlignment(Qt.AlignRight)
        vb.addLayout(fl)

        pb = QPushButton('Close')
        pb.pressed.connect(msgBox.close)
        vb.addWidget(pb)

        for a in attrs:
            le = QLineEdit()
            le.setReadOnly(True)
            le.setText(str(getattr(node,a)))
            fl.addRow(a,le)

        le = QLineEdit()
        le.setReadOnly(True)
        le.setText(channel.address)
        fl.addRow('PyDM Path',le)

        msgBox.exec()
Пример #2
0
    def _device(self, node, channel):
        attrs = ['name', 'path', 'description', 'hidden', 'groups']

        msgBox = QDialog()
        msgBox.setWindowTitle("Device Information For {}".format(node.name))
        msgBox.setMinimumWidth(400)

        vb = QVBoxLayout()
        msgBox.setLayout(vb)

        fl = QFormLayout()
        fl.setRowWrapPolicy(QFormLayout.DontWrapRows)
        fl.setFormAlignment(Qt.AlignHCenter | Qt.AlignTop)
        fl.setLabelAlignment(Qt.AlignRight)
        vb.addLayout(fl)

        pb = QPushButton('Close')
        pb.pressed.connect(msgBox.close)
        vb.addWidget(pb)

        for a in attrs:
            le = QLineEdit()
            le.setReadOnly(True)
            le.setText(str(getattr(node,a)))
            fl.addRow(a,le)

        le = QLineEdit()
        le.setReadOnly(True)
        le.setText(channel.address)
        fl.addRow('PyDM Path',le)

        msgBox.exec()
Пример #3
0
    def connection_changed(self, connected):
        build = (self._node is None) and (self._connected != connected
                                          and connected is True)
        super(RunControl, self).connection_changed(connected)

        if not build:
            return

        self._node = nodeFromAddress(self.channel)
        self._path = self.channel

        vb = QVBoxLayout()
        self.setLayout(vb)

        gb = QGroupBox('Run Control ({})'.format(self._node.name))
        vb.addWidget(gb)

        vb = QVBoxLayout()
        gb.setLayout(vb)

        fl = QFormLayout()
        fl.setRowWrapPolicy(QFormLayout.DontWrapRows)
        fl.setFormAlignment(Qt.AlignHCenter | Qt.AlignTop)
        fl.setLabelAlignment(Qt.AlignRight)
        vb.addLayout(fl)

        w = PyDMEnumComboBox(parent=None, init_channel=self._path + '.runRate')
        w.alarmSensitiveContent = False
        w.alarmSensitiveBorder = False
        fl.addRow('Run Rate:', w)

        hb = QHBoxLayout()
        vb.addLayout(hb)

        fl = QFormLayout()
        fl.setRowWrapPolicy(QFormLayout.DontWrapRows)
        fl.setFormAlignment(Qt.AlignHCenter | Qt.AlignTop)
        fl.setLabelAlignment(Qt.AlignRight)
        hb.addLayout(fl)

        w = PyDMEnumComboBox(parent=None,
                             init_channel=self._path + '.runState')
        w.alarmSensitiveContent = False
        w.alarmSensitiveBorder = False
        fl.addRow('Run State:', w)

        fl = QFormLayout()
        fl.setRowWrapPolicy(QFormLayout.DontWrapRows)
        fl.setFormAlignment(Qt.AlignHCenter | Qt.AlignTop)
        fl.setLabelAlignment(Qt.AlignRight)
        hb.addLayout(fl)

        w = PyDMLabel(parent=None, init_channel=self._path + '.runCount')
        w.showUnits = False
        w.precisionFromPV = True
        w.alarmSensitiveContent = False
        w.alarmSensitiveBorder = False

        fl.addRow('Run Count:', w)
Пример #4
0
    def connection_changed(self, connected):
        build = (self._node is None) and (self._connected != connected
                                          and connected is True)
        super(Process, self).connection_changed(connected)

        if not build:
            return

        self._node = nodeFromAddress(self.channel)
        self._path = self.channel

        vb = QVBoxLayout()
        self.setLayout(vb)

        gb = QGroupBox('Process ({})'.format(self._node.name))
        vb.addWidget(gb)

        vb = QVBoxLayout()
        gb.setLayout(vb)

        hb = QHBoxLayout()
        vb.addLayout(hb)

        w = PyDMPushButton(label='Start',
                           pressValue=1,
                           init_channel=self._path + '.Start')
        hb.addWidget(w)

        w = PyDMPushButton(label='Stop',
                           pressValue=1,
                           init_channel=self._path + '.Stop')
        hb.addWidget(w)

        fl = QFormLayout()
        fl.setRowWrapPolicy(QFormLayout.DontWrapRows)
        fl.setFormAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        fl.setLabelAlignment(Qt.AlignRight)
        hb.addLayout(fl)

        w = PyRogueLineEdit(parent=None,
                            init_channel=self._path + '.Running/disp')
        w.showUnits = False
        w.precisionFromPV = False
        w.alarmSensitiveContent = False
        w.alarmSensitiveBorder = False

        fl.addRow('Running:', w)

        fl = QFormLayout()
        fl.setRowWrapPolicy(QFormLayout.DontWrapRows)
        fl.setFormAlignment(Qt.AlignHCenter | Qt.AlignTop)
        fl.setLabelAlignment(Qt.AlignRight)
        vb.addLayout(fl)

        w = PyDMScaleIndicator(parent=None,
                               init_channel=self._path + '.Progress')
        w.showUnits = False
        w.precisionFromPV = True
        w.alarmSensitiveContent = False
        w.alarmSensitiveBorder = False
        w.showValue = False
        w.showLimits = False
        w.showTicks = False
        w.barIndicator = True

        fl.addRow('Progress:', w)

        w = PyRogueLineEdit(parent=None,
                            init_channel=self._path + '.Message/disp')
        w.showUnits = False
        w.precisionFromPV = False
        w.alarmSensitiveContent = False
        w.alarmSensitiveBorder = False

        fl.addRow('Message:', w)

        # Auto add additional fields
        noAdd = ['enable', 'Start', 'Stop', 'Running', 'Progress', 'Message']

        prc = nodeFromAddress(self.channel)

        for k, v in prc.nodes.items():
            if v.name not in noAdd and not v.hidden:
                if v.disp == 'enum' and v.enum is not None and v.mode != 'RO' and v.typeStr != 'list':
                    w = PyDMEnumComboBox(parent=None,
                                         init_channel=self._path +
                                         '.{}'.format(v.name))
                    w.alarmSensitiveContent = False
                    w.alarmSensitiveBorder = True

                elif v.minimum is not None and v.maximum is not None and v.disp == '{}' and (
                        v.mode != 'RO' or v.isCommand):
                    w = PyDMSpinbox(parent=None,
                                    init_channel=self._path +
                                    '.{}'.format(v.name))
                    w.precision = 0
                    w.showUnits = False
                    w.precisionFromPV = False
                    w.alarmSensitiveContent = False
                    w.alarmSensitiveBorder = True
                    w.showStepExponent = False
                    w.writeOnPress = True

                elif v.mode == 'RO' and not v.isCommand:
                    w = PyDMLabel(parent=None,
                                  init_channel=self._path +
                                  '.{}/disp'.format(v.name))
                    w.showUnits = False
                    w.precisionFromPV = True
                    w.alarmSensitiveContent = False
                    w.alarmSensitiveBorder = True
                else:
                    w = PyRogueLineEdit(parent=None,
                                        init_channel=self._path +
                                        '.{}/disp'.format(v.name))
                    w.showUnits = False
                    w.precisionFromPV = True
                    w.alarmSensitiveContent = False
                    w.alarmSensitiveBorder = True

                fl.addRow(v.name + ':', w)
Пример #5
0
    def connection_changed(self, connected):
        build = (self._node is None) and (self._connected != connected
                                          and connected is True)
        super(DataWriter, self).connection_changed(connected)

        if not build:
            return

        self._node = nodeFromAddress(self.channel)
        self._path = self.channel

        vb = QVBoxLayout()
        self.setLayout(vb)

        gb = QGroupBox('Data File Control ({}) '.format(self._node.name))
        vb.addWidget(gb)

        vb = QVBoxLayout()
        gb.setLayout(vb)

        fl = QFormLayout()
        fl.setRowWrapPolicy(QFormLayout.DontWrapRows)
        fl.setFormAlignment(Qt.AlignHCenter | Qt.AlignTop)
        fl.setLabelAlignment(Qt.AlignRight)
        vb.addLayout(fl)

        self._dataFile = PyRogueLineEdit(parent=None,
                                         init_channel=self._path + '.DataFile')
        self._dataFile.alarmSensitiveContent = False
        self._dataFile.alarmSensitiveBorder = True
        fl.addRow('Data File:', self._dataFile)

        hb = QHBoxLayout()
        vb.addLayout(hb)

        self._browsebutton = QPushButton('Browse')
        self._browsebutton.clicked.connect(self._browse)
        hb.addWidget(self._browsebutton)

        self._autonamebutton = PyDMPushButton(label='Auto Name',
                                              pressValue=1,
                                              init_channel=self._path +
                                              '.AutoName')
        hb.addWidget(self._autonamebutton)

        self._openbutton = PyDMPushButton(label='Open',
                                          pressValue=1,
                                          init_channel=self._path + '.Open')
        self._openbutton.clicked.connect(self._openDataFile)
        hb.addWidget(self._openbutton)

        self._closebutton = PyDMPushButton(label='Close',
                                           pressValue=1,
                                           init_channel=self._path + '.Close')
        self._closebutton.check_enable_state = lambda: None
        self._closebutton.clicked.connect(self._closeDataFile)
        self._closebutton.setEnabled(False)
        hb.addWidget(self._closebutton)

        hb = QHBoxLayout()
        vb.addLayout(hb)

        vbl = QVBoxLayout()
        hb.addLayout(vbl)

        fl = QFormLayout()
        fl.setRowWrapPolicy(QFormLayout.DontWrapRows)
        fl.setFormAlignment(Qt.AlignHCenter | Qt.AlignTop)
        fl.setLabelAlignment(Qt.AlignRight)
        vbl.addLayout(fl)

        w = PyRogueLineEdit(parent=None,
                            init_channel=self._path + '.BufferSize')
        w.alarmSensitiveContent = False
        w.alarmSensitiveBorder = True
        fl.addRow('Buffer Size:', w)

        w = PyDMLabel(parent=None, init_channel=self._path + '.IsOpen/disp')
        w.alarmSensitiveContent = False
        w.alarmSensitiveBorder = True
        fl.addRow('File Open:', w)

        w = PyDMLabel(parent=None, init_channel=self._path + '.CurrentSize')
        w.alarmSensitiveContent = False
        w.alarmSensitiveBorder = True
        fl.addRow('Current File Size:', w)

        vbr = QVBoxLayout()
        hb.addLayout(vbr)

        fl = QFormLayout()
        fl.setRowWrapPolicy(QFormLayout.DontWrapRows)
        fl.setFormAlignment(Qt.AlignHCenter | Qt.AlignTop)
        fl.setLabelAlignment(Qt.AlignRight)
        vbr.addLayout(fl)

        w = PyRogueLineEdit(parent=None,
                            init_channel=self._path + '.MaxFileSize')
        w.alarmSensitiveContent = False
        w.alarmSensitiveBorder = True
        fl.addRow('Max Size:', w)

        w = PyDMLabel(parent=None, init_channel=self._path + '.FrameCount')
        w.alarmSensitiveContent = False
        w.alarmSensitiveBorder = True
        fl.addRow('Frame Count:', w)

        w = PyDMLabel(parent=None, init_channel=self._path + '.TotalSize')
        w.alarmSensitiveContent = False
        w.alarmSensitiveBorder = True
        fl.addRow('Total File Size:', w)
Пример #6
0
    def __init__(self, settings: QSettings, parent: Optional[QObject] = None):
        # noinspection PyArgumentList
        super(NappingDialog, self).__init__(parent)

        checked_selection_mode = NappingDialog.SelectionMode(
            int(
                settings.value(
                    self.SELECTION_MODE_SETTING,
                    defaultValue=self.DEFAULT_SELECTION_MODE.value)))
        self._file_selection_mode_button = QRadioButton(
            'Single file pair', self)
        self._file_selection_mode_button.setChecked(
            checked_selection_mode == NappingDialog.SelectionMode.FILE)
        self._dir_selection_mode_button = QRadioButton(
            'Directories (multiple file pairs)', self)
        self._dir_selection_mode_button.setChecked(
            checked_selection_mode == NappingDialog.SelectionMode.DIR)
        self._selection_mode_buttons_group = QButtonGroup(self)
        self._selection_mode_buttons_group.addButton(
            self._file_selection_mode_button, NappingDialog.SelectionMode.FILE)
        self._selection_mode_buttons_group.addButton(
            self._dir_selection_mode_button, NappingDialog.SelectionMode.DIR)
        # noinspection PyUnresolvedReferences
        self._selection_mode_buttons_group.buttonClicked.connect(
            lambda _: self.refresh())

        matching_strategy_combo_box_current_text = str(
            settings.value(self.MATCHING_STRATEGY_SETTING,
                           defaultValue=self.DEFAULT_MATCHING_STRATEGY.value))
        self._matching_strategy_combo_box = QComboBox(self)
        self._matching_strategy_combo_box.addItems(
            [x.value for x in NappingDialog.MatchingStrategy])
        self._matching_strategy_combo_box.setCurrentText(
            matching_strategy_combo_box_current_text)
        # noinspection PyUnresolvedReferences
        self._matching_strategy_combo_box.currentIndexChanged.connect(
            lambda _: self.refresh())

        source_images_file_line_edit_text = str(
            settings.value(self.SOURCE_IMAGES_SETTING,
                           defaultValue=self.DEFAULT_SOURCE_IMAGES))
        self._source_images_file_line_edit = FileLineEdit(check_exists=True,
                                                          parent=self)
        self._source_images_file_line_edit.file_dialog.setWindowTitle(
            'Select source image(s)')
        self._source_images_file_line_edit.setText(
            source_images_file_line_edit_text)
        # noinspection PyUnresolvedReferences
        self._source_images_file_line_edit.textChanged.connect(
            lambda text: self.refresh(text))

        source_regex_line_edit_text = str(
            settings.value(self.SOURCE_REGEX_SETTING,
                           defaultValue=self.DEFAULT_SOURCE_REGEX))
        self._source_regex_label = QLabel('        RegEx:')
        self._source_regex_line_edit = QLineEdit(self)
        self._source_regex_line_edit.setText(source_regex_line_edit_text)
        # noinspection PyUnresolvedReferences
        self._source_regex_line_edit.textChanged.connect(
            lambda _: self.refresh())

        target_images_file_line_edit_text = str(
            settings.value(self.TARGET_IMAGES_SETTING,
                           defaultValue=self.DEFAULT_TARGET_IMAGES))
        self._target_images_file_line_edit = FileLineEdit(check_exists=True,
                                                          parent=self)
        self._target_images_file_line_edit.file_dialog.setWindowTitle(
            'Select target image(s)')
        self._target_images_file_line_edit.setText(
            target_images_file_line_edit_text)
        # noinspection PyUnresolvedReferences
        self._target_images_file_line_edit.textChanged.connect(
            lambda text: self.refresh(text))

        target_regex_line_edit_text = str(
            settings.value(self.TARGET_REGEX_SETTING,
                           defaultValue=self.DEFAULT_TARGET_REGEX))
        self._target_regex_label = QLabel('        RegEx:')
        self._target_regex_line_edit = QLineEdit(self)
        self._target_regex_line_edit.setText(target_regex_line_edit_text)
        # noinspection PyUnresolvedReferences
        self._target_regex_line_edit.textChanged.connect(
            lambda _: self.refresh())

        control_points_dest_file_line_edit_text = str(
            settings.value(self.CONTROL_POINTS_DEST_SETTING,
                           defaultValue=self.DEFAULT_CONTROL_POINTS_DEST))
        self._control_points_dest_file_line_edit = FileLineEdit(parent=self)
        self._control_points_dest_file_line_edit.file_dialog.setWindowTitle(
            'Select control points destination')
        self._control_points_dest_file_line_edit.setText(
            control_points_dest_file_line_edit_text)
        # noinspection PyUnresolvedReferences
        self._control_points_dest_file_line_edit.textChanged.connect(
            lambda text: self.refresh(text))

        joint_transform_dest_file_line_edit_text = str(
            settings.value(self.JOINT_TRANSFORM_DEST_SETTING,
                           defaultValue=self.DEFAULT_JOINT_TRANSFORM_DEST))
        self._joint_transform_dest_file_line_edit = FileLineEdit(parent=self)
        self._joint_transform_dest_file_line_edit.file_dialog.setWindowTitle(
            'Select joint transform destination')
        self._joint_transform_dest_file_line_edit.setText(
            joint_transform_dest_file_line_edit_text)
        # noinspection PyUnresolvedReferences
        self._joint_transform_dest_file_line_edit.textChanged.connect(
            lambda text: self.refresh(text))

        transform_type_combo_box_current_text = str(
            settings.value(self.TRANSFORM_TYPE_SETTING,
                           defaultValue=self.DEFAULT_TRANSFORM_TYPE))
        self._transform_type_combo_box = QComboBox(self)
        self._transform_type_combo_box.addItems(
            [x.value for x in NappingDialog.TransformType])
        self._transform_type_combo_box.setCurrentText(
            transform_type_combo_box_current_text)
        # noinspection PyUnresolvedReferences
        self._transform_type_combo_box.currentIndexChanged.connect(
            lambda _: self.refresh())

        source_coords_file_line_edit_text = str(
            settings.value(self.SOURCE_COORDS_SETTING,
                           defaultValue=self.DEFAULT_SOURCE_COORDS))
        self._source_coords_file_line_edit = FileLineEdit(check_exists=True,
                                                          parent=self)
        self._source_coords_file_line_edit.file_dialog.setWindowTitle(
            'Select source coordinates')
        self._source_coords_file_line_edit.setText(
            source_coords_file_line_edit_text)
        # noinspection PyUnresolvedReferences
        self._source_coords_file_line_edit.textChanged.connect(
            lambda text: self.refresh(text))

        source_coords_regex_line_edit_text = str(
            settings.value(self.SOURCE_COORDS_REGEX_SETTING,
                           defaultValue=self.DEFAULT_SOURCE_COORDS_REGEX))
        self._source_coords_regex_label = QLabel('        RegEx:')
        self._source_coords_regex_line_edit = QLineEdit(self)
        self._source_coords_regex_line_edit.setText(
            source_coords_regex_line_edit_text)
        # noinspection PyUnresolvedReferences
        self._source_coords_regex_line_edit.textChanged.connect(
            lambda _: self.refresh())

        transformed_coords_dest_file_line_edit_text = str(
            settings.value(self.TRANSFORMED_COORDS_DEST_SETTING,
                           defaultValue=self.DEFAULT_TRANSFORMED_COORDS_DEST))
        self._transformed_coords_dest_file_line_edit = FileLineEdit(
            parent=self)
        self._transformed_coords_dest_file_line_edit.file_dialog.setWindowTitle(
            'Select transformed coordinates destination')
        self._transformed_coords_dest_file_line_edit.setText(
            transformed_coords_dest_file_line_edit_text)
        # noinspection PyUnresolvedReferences
        self._transformed_coords_dest_file_line_edit.textChanged.connect(
            lambda text: self.refresh(text))

        pre_transform_file_line_edit_text = str(
            settings.value(self.PRE_TRANSFORM_SETTING,
                           defaultValue=self.DEFAULT_PRE_TRANSFORM))
        self._pre_transform_file_line_edit = FileLineEdit(parent=self)
        self._pre_transform_file_line_edit.file_dialog.setWindowTitle(
            'Select pre-transform')
        self._pre_transform_file_line_edit.setText(
            pre_transform_file_line_edit_text)
        self._pre_transform_file_line_edit.file_dialog.setFileMode(
            QFileDialog.ExistingFile)
        self._pre_transform_file_line_edit.file_dialog.setNameFilter(
            'Numpy files (*.npy)')
        # noinspection PyUnresolvedReferences
        self._pre_transform_file_line_edit.textChanged.connect(
            lambda text: self.refresh(text))

        post_transform_file_line_edit_text = str(
            settings.value(self.POST_TRANSFORM_SETTING,
                           defaultValue=self.DEFAULT_POST_TRANSFORM))
        self._post_transform_file_line_edit = FileLineEdit(parent=self)
        self._post_transform_file_line_edit.file_dialog.setWindowTitle(
            'Select post-transform')
        self._post_transform_file_line_edit.file_dialog.setFileMode(
            QFileDialog.ExistingFile)
        self._post_transform_file_line_edit.file_dialog.setNameFilter(
            'Numpy files (*.npy)')
        self._post_transform_file_line_edit.setText(
            post_transform_file_line_edit_text)
        # noinspection PyUnresolvedReferences
        self._post_transform_file_line_edit.textChanged.connect(
            lambda text: self.refresh(text))

        self._button_box = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self)
        # noinspection PyUnresolvedReferences
        self._button_box.rejected.connect(self.reject)

        # noinspection PyUnresolvedReferences
        @self._button_box.accepted.connect
        def on_button_box_accepted():
            settings.setValue(self.SELECTION_MODE_SETTING,
                              self.selection_mode.value)
            settings.setValue(self.SOURCE_IMAGES_SETTING,
                              str(self.source_images_path))
            settings.setValue(self.SOURCE_REGEX_SETTING, self.source_regex)
            settings.setValue(self.TARGET_IMAGES_SETTING,
                              str(self.target_images_path))
            settings.setValue(self.TARGET_REGEX_SETTING, self.target_regex)
            settings.setValue(self.CONTROL_POINTS_DEST_SETTING,
                              str(self.control_points_dest_path))
            settings.setValue(self.JOINT_TRANSFORM_DEST_SETTING,
                              str(self.joint_transform_dest_path))
            settings.setValue(self.TRANSFORM_TYPE_SETTING,
                              self.transform_type.value)
            settings.setValue(self.MATCHING_STRATEGY_SETTING,
                              self.matching_strategy.value)
            settings.setValue(self.SOURCE_COORDS_SETTING,
                              str(self.source_coords_path or ''))
            settings.setValue(self.SOURCE_COORDS_REGEX_SETTING,
                              self.source_coords_regex)
            settings.setValue(self.TRANSFORMED_COORDS_DEST_SETTING,
                              str(self.transformed_coords_dest_path or ''))
            settings.setValue(self.PRE_TRANSFORM_SETTING,
                              str(self.pre_transform_path or ''))
            settings.setValue(self.POST_TRANSFORM_SETTING,
                              str(self.post_transform_path or ''))
            settings.sync()
            self.accept()

        required_group_box = QGroupBox(self)
        required_group_box_layout = QFormLayout()
        required_group_box_layout.setLabelAlignment(Qt.AlignLeft)
        required_group_box_layout.setRowWrapPolicy(QFormLayout.DontWrapRows)
        required_group_box_layout.setFieldGrowthPolicy(
            QFormLayout.AllNonFixedFieldsGrow)
        required_group_box_layout.addRow('Source image(s):',
                                         self._source_images_file_line_edit)
        required_group_box_layout.addRow(self._source_regex_label,
                                         self._source_regex_line_edit)
        required_group_box_layout.addRow('Target image(s):',
                                         self._target_images_file_line_edit)
        required_group_box_layout.addRow(self._target_regex_label,
                                         self._target_regex_line_edit)
        required_group_box_layout.addRow(
            'Control points dest.:', self._control_points_dest_file_line_edit)
        required_group_box_layout.addRow(
            'Joint transform dest.:',
            self._joint_transform_dest_file_line_edit)
        required_group_box_layout.addRow('Transform type:',
                                         self._transform_type_combo_box)
        required_group_box.setLayout(required_group_box_layout)

        optional_group_box = QGroupBox(self)
        optional_group_box_layout = QFormLayout()
        optional_group_box_layout.setLabelAlignment(Qt.AlignLeft)
        optional_group_box_layout.setRowWrapPolicy(QFormLayout.DontWrapRows)
        optional_group_box_layout.setFieldGrowthPolicy(
            QFormLayout.AllNonFixedFieldsGrow)
        optional_group_box_layout.addRow('Source coordinates:',
                                         self._source_coords_file_line_edit)
        optional_group_box_layout.addRow(self._source_coords_regex_label,
                                         self._source_coords_regex_line_edit)
        optional_group_box_layout.addRow(
            'Transformed coord. dest.:',
            self._transformed_coords_dest_file_line_edit)
        optional_group_box_layout.addRow('Pre-transform:',
                                         self._pre_transform_file_line_edit)
        optional_group_box_layout.addRow('Post-transform:',
                                         self._post_transform_file_line_edit)
        optional_group_box.setLayout(optional_group_box_layout)

        layout = QVBoxLayout()
        mode_layout = QHBoxLayout()
        # noinspection PyArgumentList
        mode_layout.addWidget(self._file_selection_mode_button)
        # noinspection PyArgumentList
        mode_layout.addWidget(self._dir_selection_mode_button)
        # noinspection PyArgumentList
        mode_layout.addWidget(self._matching_strategy_combo_box)
        mode_layout.addStretch()
        layout.addLayout(mode_layout)
        # noinspection PyArgumentList
        layout.addWidget(required_group_box)
        # noinspection PyArgumentList
        layout.addWidget(optional_group_box)
        # noinspection PyArgumentList
        layout.addWidget(self._button_box)
        self.setLayout(layout)

        self.setWindowTitle('Control point matching')
        self.setMinimumWidth(600)
        self.refresh()