Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
DanicaSTFC committed Feb 22, 2024
2 parents 3e28914 + c90c4ec commit 5536161
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 16 deletions.
14 changes: 9 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Version x.x.x
- Adds the class `AdvancedDialogForm` & tests/example (#124).
- Adds methods to insert widgets in the forms & tests/example. Removes `_addWidget`.
Adds `getWidgetRow`and updates states dictionary and related methods. Adds
`getNameAndRole*`. Changes `num_widgets` to be a property (#109)
# Version 1.0.0
- Adds the class `AdvancedDialogForm` & tests/example (#124)
- Edits 'contributing.md' and 'README.md (#131, #133)
- Adds unit test for `addWidget` and `addSpanningWidget`; adds `getIndexFromVerticalLayout`
to `FormDialog` (#123)
- Initialises `widget_states` in init (#132)
- Adds methods to insert widgets in the forms & tests/example; removes `_addWidget`;
adds `getWidgetRow`and updates states dictionary and related methods; adds
`getNameAndRole*`; changes `num_widgets` to be a property (#109)
- Reinstates changelog (#99)
- Adds `title` to `FormDockWidget` & update tests/examples (#102)
- Stops `pre-commit` committing corrections to user PRs (#112)
Expand Down
40 changes: 33 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
# Developer Contribution Guide
Contribute to the repository by opening a pull request.

## Local
Develop code locally by cloning the source code and installing it.

```sh
# Clone (download) source code
git clone git@github.com:TomographicImaging/eqt
cd eqt
# Install git hooks for automatic sanity checking when trying to commit
pip install pre-commit
pre-commit install
# Install test dependencies
pip install .[dev]
# Run tests
```

### Run tests
Before merging a pull request, all tests must pass. These can be run locally from the repository folder
```sh
pytest
```
### Pre-commit guide
Adhere to our styling guide by installing [pre-commit](https://pre-commit.com) in your local eqt environment.
```sh
pip install pre-commit
pre-commit install
```
From your local repository folder, run pre-commit on all the files before committing
```sh
pre-commit run -a
```
or run pre-commit on a single file by specifying its file path
```sh
pre-commit run --files [path]
```
The [.pre-commit-config.yaml](./.pre-commit-config.yaml) config file indicates the repositories and the hooks which will automatically applied.

## CI
## Continuous integration

GitHub Actions runs automatically on every commit via [test.yml](.github/workflows/test.yml).
GitHub Actions runs automatically a subset of the unit tests on every commit via [test.yml](.github/workflows/test.yml).

### Testing

Expand Down Expand Up @@ -50,5 +68,13 @@ Version 1.33.7
The `<body>` should be taken from the changelog (below).

#### Changelog
Located in [CHANGELOG.md](./CHANGELOG.md).

##### Changelog style
The changelog file needs to be updated manually every time a pull request (PR) is submitted.
- Itemise the message with "-".
- Be concise by explaining the overall changes in only a few words.
- Mention the relevant PR in brackets.

See [CHANGELOG.md](./CHANGELOG.md).
###### Example:
- Adds `title` to `FormDockWidget` & update tests/examples (#102)
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,6 @@ status = QtCore.Signal(tuple)
```

Read more on [Qt signals and slots](https://doc.qt.io/qt-5/signalsandslots.html) and on how to use them in [PySide2](https://wiki.qt.io/Qt_for_Python_Signals_and_Slots).

## Developer Contribution Guide
See [CONTRIBUTING.md](./CONTRIBUTING.md).
4 changes: 3 additions & 1 deletion eqt/ui/FormDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,12 @@ def getWidgetFromVerticalLayout(self, index):
def getIndexFromVerticalLayout(self, widget):
'''
Returns the index of the widget in the vertical layout.
Parameters
-------------
widget : qwidget
widget : QWidget
The widget in the layout.
Return
------------
int
Expand Down
10 changes: 8 additions & 2 deletions eqt/ui/UIFormWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def createForm(self):
'verticalLayout': verticalLayout, 'groupBox': groupBox,
'groupBoxFormLayout': groupBoxFormLayout}
self.widgets = {}
self.widget_states = {}
self.default_widget_states = {}

@property
Expand Down Expand Up @@ -80,14 +81,19 @@ def insertWidget(self, row, name, qwidget, qlabel=None):
'''
if f'{name}_field' in self.widgets:
raise KeyError(f"Widget name ({name}) already defined. Choose another name.")

formLayout = self.uiElements['groupBoxFormLayout']
if formLayout.indexOf(qwidget) != -1:
raise KeyError(f"The widget {qwidget} is already in use. Create another QWidget.")

if qlabel is not None:
if isinstance(qlabel, str):
txt = qlabel
qlabel = QtWidgets.QLabel(self)
qlabel.setText(txt)
else:
if formLayout.indexOf(qlabel) != -1:
raise KeyError(
f"The widget {qlabel} is already in use. Create another QLabel.")
formLayout.insertRow(row, qlabel, qwidget)
self.widgets[f'{name}_label'] = qlabel
self.default_widget_states[f'{name}_label'] = self.getWidgetState(name, 'label')
Expand Down Expand Up @@ -472,7 +478,7 @@ def restoreAllSavedWidgetStates(self):
`saveAllWidgetStates` was previously invoked. If there are no previously saved states,
`default_widget_states` are used instead, after being made visible.
'''
if not hasattr(self, 'widget_states'):
if not self.widget_states:
self.setDefaultWidgetStatesVisibleTrue()
self.applyWidgetStates(self.default_widget_states)
else:
Expand Down
69 changes: 68 additions & 1 deletion test/test__formUI_status_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,37 @@ def set_spanning_state(self, i: int):
self.form.getWidget('button_spanning').setCheckable(True)
self.form.getWidget('button_spanning').setChecked(state[i]['button_value'])

def _test_add_one_widget(self, name, qwidget, qlabel):
"""
Invokes `addWidget`, therefore inserts the qwidget and the qlabel
at the end of the layout. Checks the position of the widget in the form is the last one.
"""
self.form.addWidget(qwidget, qlabel, name)
position = self.layout.getWidgetPosition(self.form.getWidget(name, 'field'))[0]
self.assertEqual(position, self.form.getNumWidgets() - 1)

def _test_add_one_spanning_widget(self, name, qwidget):
"""
Invokes `addSpanningWidget`, therefore inserts the qwidget
at the end of the layout. Checks the position of the widget in the form is the last one.
"""
name = f'{name}_spanning'
self.form.addSpanningWidget(qwidget, name)
position = self.layout.getWidgetPosition(self.form.getWidget(name, 'field'))[0]
self.assertEqual(position, self.form.getNumWidgets() - 1)

def test_add_every_widget(self):
"""
Adds each widget, and then each spanning widget, in the end of the form layout.
Tests the position of the widgets in the layout is the last one.
"""
for key in self.list_all_widgets:
qwidget = self.list_all_widgets[key]
name = f'{key}_added'
self._test_add_one_widget(name, qwidget, name)
qwidget = self.list_all_widgets[key]
self._test_add_one_spanning_widget(name + '_spanning', qwidget)

def _test_insert_one_widget(self, row, name, qwidget, qlabel=None):
"""
Invokes `insertWidget`, therefore inserts the qwidget (and the qlabel)
Expand All @@ -178,7 +209,7 @@ def test_insert_every_widget(self):

def _test_remove_one_widget(self, name):
"""
Remove one widget.
Removes one widget.
Checks the number of widgets in the form before and after deletion are consistent.
Checks the number of rows in the layout and number of widgets in the form are
consistent.
Expand Down Expand Up @@ -522,6 +553,34 @@ def _test_insert_one_widget_to_vertical_layout(self, row, qwidget):
position = self.vertical_layout.indexOf(qwidget)
self.assertEqual(position, row)

def _test_add_one_widget_to_vertical_layout(self, qwidget):
"""
Invokes `addWidget` with vertical layout. Therefore adds the qwidget
at the end of the layout. Checks that the widget inserted is the inputted one and
its position in the layout corresponds to the number of widgets in the layout
before insertion.
"""
num_widgets = self.vertical_layout.count()
self.form.addWidget(qwidget, layout='vertical')
index = self.form.getIndexFromVerticalLayout(qwidget)
self.assertEqual(index, num_widgets)
widget = self.vertical_layout.itemAt(num_widgets).widget()
self.assertEqual(qwidget, widget)

def _test_add_one_spanning_widget_to_vertical_layout(self, qwidget):
"""
Invokes `addSpanningWidget` with vertical layout. Therefore adds the qwidget
at the end of the layout. Checks that the widget inserted is the inputted one and
its position in the layout corresponds to the number of widgets in the layout
before insertion.
"""
num_widgets = self.vertical_layout.count()
self.form.addSpanningWidget(qwidget, layout='vertical')
index = self.form.getIndexFromVerticalLayout(qwidget)
self.assertEqual(index, num_widgets)
widget = self.vertical_layout.itemAt(num_widgets).widget()
self.assertEqual(qwidget, widget)

def test_insert_every_widget_to_vertical_layout(self):
"""
Inserts each widget in position 0 of the vertical layout and tests its position in
Expand All @@ -530,6 +589,14 @@ def test_insert_every_widget_to_vertical_layout(self):
for key in self.list_all_widgets:
self._test_insert_one_widget_to_vertical_layout(0, self.list_all_widgets[key])

def test_add_every_widget_to_vertical_layout(self):
"""
Adds each widget and each spanning widget at the end of the vertical layout and tests them.
"""
for key in self.list_all_widgets:
self._test_add_one_widget_to_vertical_layout(self.list_all_widgets[key])
self._test_add_one_spanning_widget_to_vertical_layout(self.list_all_widgets[key])

def _test_remove_one_widget_from_vertical_layout(self, widget):
"""
Removes one widget from the vertical layout.
Expand Down

0 comments on commit 5536161

Please sign in to comment.