diff --git a/CHANGELOG.md b/CHANGELOG.md index a051cf7..a2da93b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ # Version 1.0.0 +- Change order of widget states (#129) - Adds the class `AdvancedDialogForm` & tests/example; deprecates `getWidgetStates` to be `getSavedWidgetStates` (#124) - Edits 'contributing.md' and 'README.md (#131, #133) diff --git a/eqt/ui/FormDialog.py b/eqt/ui/FormDialog.py index 52b69e9..ca83bfb 100644 --- a/eqt/ui/FormDialog.py +++ b/eqt/ui/FormDialog.py @@ -5,26 +5,20 @@ class FormDialog(QtWidgets.QDialog): def __init__(self, parent=None, title=None): + super().__init__(parent) - QtWidgets.QDialog.__init__(self, parent) - - # button box - bb = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok - | QtWidgets.QDialogButtonBox.Cancel) - self.buttonBox = bb - - formWidget = UIFormFactory.getQWidget(parent=self) - self.formWidget = formWidget - + self.buttonBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok + | QtWidgets.QDialogButtonBox.Cancel) + self.formWidget = UIFormFactory.getQWidget(parent=self) # set the layout of the dialog - self.setLayout(formWidget.uiElements['verticalLayout']) + self.setLayout(self.formWidget.uiElements['verticalLayout']) if title is not None: self.setWindowTitle(title) # add button box to the UI - self.formWidget.uiElements['verticalLayout'].addWidget(bb) - bb.button(QtWidgets.QDialogButtonBox.Ok).clicked.connect(self._onOk) - bb.button(QtWidgets.QDialogButtonBox.Cancel).clicked.connect(self._onCancel) + self.formWidget.uiElements['verticalLayout'].addWidget(self.buttonBox) + self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).clicked.connect(self._onOk) + self.buttonBox.button(QtWidgets.QDialogButtonBox.Cancel).clicked.connect(self._onCancel) @property def Ok(self): @@ -75,7 +69,7 @@ def addWidget(self, qwidget, qlabel=None, name=None, layout='form'): Parameters ---------- - qwidget : widget + qwidget : QWidget qlabel : qlabel widget or str only supported when layout is 'form' name : str @@ -100,9 +94,15 @@ def addWidget(self, qwidget, qlabel=None, name=None, layout='form'): def addSpanningWidget(self, qwidget, name=None, layout='form'): ''' Adds a spanning widget occupying the full row in the layout. - layout = 'form' - adds the widget to the form layout - layout = 'vertical' - adds the widget to the vertical layout below the form. - To add to the form layout, name must be passed. + + Parameters + ---------- + qwidget : QWidget + name : str + only supported when layout is 'form' + layout : 'form' or 'vertical' + 'form' - adds to the `groupBoxFormLayout`, + 'vertical' - adds to the `verticalLayout` below the form. ''' if layout == 'vertical': if name is not None: @@ -131,7 +131,7 @@ def insertWidget(self, row, name, qwidget, qlabel=None): The position in the form where the widget is added. name : str The string associated to the qwidget and qlabel. - qwidget : widget + qwidget : QWidget The widget to be added on the right hand side of the form or as a spanning widget. qlabel : qlabel widget or str The qlabel widget, or a str from which a qlabel widget is created, to be added @@ -141,14 +141,11 @@ def insertWidget(self, row, name, qwidget, qlabel=None): self.formWidget.insertWidget(row, name, qwidget, qlabel) def insertWidgetToVerticalLayout(self, row, qwidget): - ''' - Inserts a widget to the vertical layout at position specified by row. - ''' + '''Inserts a widget to the vertical layout at position specified by row.''' self.formWidget.uiElements['verticalLayout'].insertWidget(row, qwidget) def getWidgetFromVerticalLayout(self, index): - ''' - Returns the widget in the vertical layout located at position index.''' + '''Returns the widget in the vertical layout located at position index.''' return self.formWidget.uiElements['verticalLayout'].itemAt(index).widget() def getIndexFromVerticalLayout(self, widget): @@ -167,10 +164,10 @@ def getIndexFromVerticalLayout(self, widget): ''' return self.formWidget.uiElements['verticalLayout'].indexOf(widget) - def removeWidget(self, widget): + def removeWidget(self, name): ''' Removes the widget with the specified name from the form layout. - This method delete the qwidget, and qlabel if present, from the widgets dictionary + This method deletes the qwidget, and qlabel if present, from the widgets dictionary and sets their parent to `None`. Parameters @@ -184,20 +181,22 @@ def removeWidget(self, widget): If the widget has a corresponding label, a tuple containing the widget and label is returned. Otherwise, only the widget is returned. ''' - return self.formWidget.removeWidget(widget) + return self.formWidget.removeWidget(name) def removeWidgetFromVerticalLayout(self, widget): - ''' - Removes a widget from the vertical layout. + '''Removes a widget from the vertical layout. + + Parameters + ---------- + widget : QWidget + The widget to be removed. ''' self.formWidget.uiElements['verticalLayout'].removeWidget(widget) widget.setParent(None) return widget def getNumWidgets(self): - ''' - Returns the number of widgets in the form. - ''' + '''Returns the number of widgets in the form.''' return self.formWidget.getNumWidgets() def getWidget(self, name, role='field'): diff --git a/eqt/ui/UIFormWidget.py b/eqt/ui/UIFormWidget.py index 2f163d5..3e067db 100644 --- a/eqt/ui/UIFormWidget.py +++ b/eqt/ui/UIFormWidget.py @@ -23,9 +23,6 @@ class UIFormWidget: | | +----------------------------------------------------------+ ''' - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - def createForm(self): # Add vertical layout to dock contents verticalLayout = QtWidgets.QVBoxLayout(self) @@ -74,7 +71,7 @@ def insertWidget(self, row, name, qwidget, qlabel=None): The position in the form where the widget is added. name : str The string associated to the qwidget and qlabel. - qwidget : widget + qwidget : QWidget The widget to be added on the right hand side of the form or as a spanning widget. qlabel : qlabel widget or str The qlabel widget, or a str from which a qlabel widget is created, to be added @@ -99,7 +96,6 @@ def insertWidget(self, row, name, qwidget, qlabel=None): formLayout.insertRow(row, qlabel, qwidget) self.widgets[f'{name}_label'] = qlabel self.default_widget_states[f'{name}_label'] = self.getWidgetState(name, 'label') - else: formLayout.insertRow(row, qwidget) @@ -148,7 +144,7 @@ def addWidget(self, qwidget, qlabel, name): Parameters ---------- - qwidget : widget + qwidget : QWidget The widget to be added on the right hand side of the form. qlabel : qlabel widget or str The qlabel widget, or a str from which a qlabel widget is created, to be added @@ -280,10 +276,7 @@ def getAllWidgetStates(self): e.g. {'widget1': {'value': 1, 'enabled': True, 'visible': True, 'widget_row': 0}, 'widget2': {'value': 2, 'enabled': False, 'visible': False, 'widget_row': 1}}. ''' - all_widget_states = {} - for key, widget in self.widgets.items(): - all_widget_states[key] = self.getWidgetState(widget) - return all_widget_states + return {key: self.getWidgetState(widget) for key, widget in self.widgets.items()} def getWidgetState(self, widget, role=None): ''' @@ -326,9 +319,6 @@ def getWidgetState(self, widget, role=None): else: name, role = self._getNameAndRoleFromWidget(widget) widget_state = {} - widget_state['enabled'] = widget.isEnabled() - widget_state['visible'] = widget.isVisible() - if isinstance(widget, QtWidgets.QLabel): widget_state['value'] = widget.text() elif isinstance(widget, (QtWidgets.QCheckBox, QtWidgets.QPushButton)): @@ -345,7 +335,8 @@ def getWidgetState(self, widget, role=None): widget_state['value'] = widget.isChecked() elif isinstance(widget, (QtWidgets.QTextEdit, QtWidgets.QPlainTextEdit)): widget_state['value'] = widget.toPlainText() - + widget_state['enabled'] = widget.isEnabled() + widget_state['visible'] = widget.isVisible() widget_state['widget_row'] = self.getWidgetRow(name, role) return widget_state @@ -360,15 +351,10 @@ def _getNameAndRoleFromKey(self, key): Format: name or name_field or name_label ''' if key.endswith('_field'): - name = key.removesuffix('_field') - role = 'field' + return key.removesuffix('_field'), 'field' elif key.endswith('_label'): - name = key.removesuffix('_label') - role = 'label' - else: - name = key - role = 'field' - return name, role + return key.removesuffix('_label'), 'label' + return key, 'field' def _getNameAndRoleFromWidget(self, widget): ''' @@ -400,7 +386,7 @@ def applyWidgetState(self, name, state, role=None): e.g. {'value': 1, 'enabled': True, 'visible': True, 'widget_row' : 0}. ''' if role is not None: - if role in ['label', 'field']: + if role in ('label', 'field'): name_role = name + '_' + role else: raise ValueError(f'Role must be either "label", "field" or None. Got {role}.') @@ -408,10 +394,7 @@ def applyWidgetState(self, name, state, role=None): name_role = f'{name}_field' # retrieve widget - try: - widget = self.widgets[name_role] - except KeyError: - raise KeyError(f'No widget associated with the dictionary key `{name_role}`.') + widget = self.widgets[name_role] # apply state for key, value in state.items(): if key == 'enabled': @@ -454,7 +437,7 @@ def applyWidgetStates(self, states): 'widget2': {'value': 2, 'enabled': False, 'visible': False, 'widget_row': 1}}. ''' if set(self.widgets) != set(states): - raise KeyError("states={set(states)} do not match form widgets ({set(self.widgets)})") + raise KeyError(f"states={set(states)} do not match form widgets ({set(self.widgets)})") for key, widget_state in states.items(): name, role = self._getNameAndRoleFromKey(key) self.applyWidgetState(name, widget_state, role) @@ -502,10 +485,10 @@ def __init__(self, parent=None): class FormDockWidget(QtWidgets.QDockWidget): - def __init__(self, parent=None, title=None): + def __init__(self, parent=None, title=''): if title is None: title = '' - QtWidgets.QDockWidget.__init__(self, title, parent) + super().__init__(title, parent) widget = FormWidget(parent) self.setWidget(widget) if title is not None: @@ -556,7 +539,7 @@ def insertWidget(self, row, name, qwidget, qlabel=None): The position in the form where the widget is added. name : str The string associated to the qwidget and qlabel. - qwidget : widget + qwidget : QWidget The widget to be added on the right hand side of the form or as a spanning widget. qlabel : qlabel widget or str The qlabel widget, or a str from which a qlabel widget is created, to be added