Skip to content

Commit 558ccab

Browse files
DanicaSTFClauramurgatroydpre-commit-ci[bot]casperdclpaskino
authored
PR Insert widget (#109)
* Add functionality of default saving in a new example * Save states and restore states as a default in FormDialog * Add all widgets to example 3 and set state method * Add unit test for state changes in form dialog --- not finished * Unit tests working * Modify and tidy example * Add minor changes * Add changes from pre-commit * Fix first cancel call bug * Save default values one by one in `_addWidget` * Close dialog when Ok is clicked and add example file for methods * Add example state to tests, add docstring to set_state * ii changed to i in test set_state * Improve applyDefaultWidgetValuesToState with docstring and new name * Change docstring to restoreAllSavedWidgetStates * Pre-commit run * add insert widget working with add row and extra example * Fix issues with unit tests * Fix issues with session label * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix formatting * Remove unused imports * remove prints * Working example and improved insert methods * Add unit test * Improve unit test * Improve docstring etc * run pre-commit * delete temporary example for testing * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Changed pre-commit suggestions * Add default widget state as a larger dictionary * Polish test_dialog_buttons_default_behaviour * pre-commit run * improve docstring and other minor things * Attempt to make remove widget and save default states compatible, not working yet * Polish code and run pre-commit * Change method name and remove qlabel from default state dictionary * Add unit test for insertWidgetToVerticalLayout * Change dictionaries * Add dictionary for widget number * Widget number dictionary works well * Modify various methods so remove widgets works * modify unit test to meet new widget number * Some polishing of the code * Improve docstrings and namings * Improve formatting * Minor change * Add widget number to label state * Num_widgets as a property * Add reviewers changes * Fix save state example * Copy docstring 3 times * Modify example insert widgets and fix problems with default states * Add remove widget and get widget from vertical layout in form dialog * Add unit tests for some methods * temporary commit * correct qlabel widget in applywidgetstates * Add test for apply widgets remove and insert * Add test for apply widgets remove and insert * Delete extra example * Change applywidgetstates and add adaptFormToStates * Change example insert widget with adaptFormToStates * Add advanced dialog to form dialog and its example file * Add button argument to advanced dialog * Improve docstrings and other minor things * Change pop widget number dictionary dictionary arguments * Fixed insert widget example * Delete _addwidget and other changes from 2nd review * Run pre-commit * Change docstring in insert widget * Change docstring remove widget * Change error message * Change insert widget docstring * Change test list * Update changelog * Delete removed widget dict and widget number dict and change getWidgetNumber * Change docstring * Change docstring * Update changelog * fixup docstrings * misc tidy * more whitespace fixes * Change docstring * Fix tests * Change docstring * Merge the removed methods and change example. Change widget number to widget row * run pre-commit * commit string Co-authored-by: Edoardo Pasca <[email protected]> * Update changelog * Add tests for remove widgets from vertical layout * Change names to remove widget and insert widget * Change getNameAndRoleFromWidget error * run pre-commit * run pre-commit * fix flake8 --------- Co-authored-by: lauramurgatroyd <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Casper da Costa-Luis <[email protected]> Co-authored-by: Edoardo Pasca <[email protected]>
1 parent 8ac20be commit 558ccab

9 files changed

+829
-359
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
# Version x.x.x
2+
- Adds methods to insert widgets in the forms & tests/example
3+
Removes `_addWidget`
4+
Adds `getWidgetRow`and updates states dictionary and related methods
5+
Adds `getNameAndRole*`.
6+
Changes `num_widgets` to be a property (#109)
27
- Reinstates changelog (#99)
38
- Adds `title` to `FormDockWidget` & update tests/examples (#102)
49
- Stops `pre-commit` committing corrections to user PRs (#112)

eqt/threading/QtThreading.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def run(self):
4747
"""
4848
try:
4949
result = self.fn(*self.args, **self.kwargs)
50-
except BaseException:
50+
except BaseException: # NOQA: B036
5151
traceback.print_exc()
5252
exctype, value = sys.exc_info()[:2]
5353
self.signals.error.emit((exctype, value, traceback.format_exc()))

eqt/ui/FormDialog.py

+147-64
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,30 @@ def __init__(self, parent=None, title=None):
2828

2929
@property
3030
def Ok(self):
31-
'''returns a reference to the Dialog Ok button to connect its signals'''
31+
'''Returns a reference to the Dialog Ok button to connect its signals.'''
3232
return self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok)
3333

3434
@property
3535
def Cancel(self):
36-
'''returns a reference to the Dialog Cancel button to connect its signals'''
36+
'''Returns a reference to the Dialog Cancel button to connect its signals.'''
3737
return self.buttonBox.button(QtWidgets.QDialogButtonBox.Cancel)
3838

3939
def _onOk(self):
40-
'''saves the widget states and calls `onOk`'''
40+
'''Saves the widget states and calls `onOk`.'''
4141
self.saveAllWidgetStates()
4242
self.onOk()
4343
self.close()
4444

4545
def _onCancel(self):
46-
'''calls `onCancel`, closes the FormDialog and restores the previously saved states
46+
'''Calls `onCancel`, closes the FormDialog and restores the previously saved states
4747
or the default states.'''
4848
self.onCancel()
4949
self.close()
5050
self.restoreAllSavedWidgetStates()
5151

5252
def onOk(self):
5353
'''Called when the dialog's "Ok" button is clicked.
54-
Can be redefined to add additional functionality on "Ok"'''
54+
Can be redefined to add additional functionality on "Ok".'''
5555
pass
5656

5757
def onCancel(self):
@@ -69,12 +69,21 @@ def groupBox(self):
6969

7070
def addWidget(self, qwidget, qlabel=None, name=None, layout='form'):
7171
'''
72-
Adds a widget to the layout.
73-
layout = 'form' - adds to the FormLayout
74-
layout = 'vertical' - adds to the Vertical layout below the form.
75-
To add to the form layout, qlabel and name must be passed.
76-
'''
72+
Adds a widget to the layout. In particular, adds a qwidget and a qlabel widget
73+
in the same row of the form layout if layout is 'form' and adds a spanning widget
74+
to the vertical layout if layout is 'vertical'.
7775
76+
Parameters
77+
----------
78+
qwidget : widget
79+
qlabel : qlabel widget or str
80+
only supported when layout is 'form'
81+
name : str
82+
only supported when layout is 'form'
83+
layout : 'form' or 'vertical'
84+
'form' - adds to the `groupBoxFormLayout`,
85+
'vertical' - adds to the `verticalLayout` below the form.
86+
'''
7887
if layout == 'vertical':
7988
if name is not None or qlabel is not None:
8089
raise ValueError('`qlabel` and `name` are unsupported when `layout=vertical`')
@@ -88,19 +97,11 @@ def addWidget(self, qwidget, qlabel=None, name=None, layout='form'):
8897
else:
8998
raise ValueError(f"layout '{layout}' unrecognised: expected 'form' or 'vertical'")
9099

91-
def removeWidget(self, name):
92-
'''
93-
Removes a widget (and its label if present) from the layout.
94-
Decreases the counter for the number of widgets in the layout.
95-
Deletes the field (and label) from the dictionary.
96-
'''
97-
self.formWidget.removeWidget(name)
98-
99100
def addSpanningWidget(self, qwidget, name=None, layout='form'):
100101
'''
101-
Adds a spanning widget to the layout.
102-
layout = 'form' - adds the widget to the FormLayout
103-
layout = 'vertical' - adds the widget to the Vertical layout below the form.
102+
Adds a spanning widget occupying the full row in the layout.
103+
layout = 'form' - adds the widget to the form layout
104+
layout = 'vertical' - adds the widget to the vertical layout below the form.
104105
To add to the form layout, name must be passed.
105106
'''
106107
if layout == 'vertical':
@@ -115,49 +116,123 @@ def addSpanningWidget(self, qwidget, name=None, layout='form'):
115116
raise ValueError(
116117
f"layout {layout} is not recognised, must be set to 'form' or 'vertical'")
117118

119+
def insertWidget(self, row, name, qwidget, qlabel=None):
120+
'''
121+
Inserts a labelled widget, or a spanning widget, to the form layout.
122+
The position in the form is specified by row. If row is out of bounds, the widget
123+
is added at the end of the form. An error is raised if `name` is already in use
124+
by another widget in the form. The entries associated with the widget are added
125+
to the widget dictionary and the default-widget-states
126+
dictionary.
127+
128+
Parameters
129+
----------
130+
row : int
131+
The position in the form where the widget is added.
132+
name : str
133+
The string associated to the qwidget and qlabel.
134+
qwidget : widget
135+
The widget to be added on the right hand side of the form or as a spanning widget.
136+
qlabel : qlabel widget or str
137+
The qlabel widget, or a str from which a qlabel widget is created, to be added
138+
on the left hand side of the form. If qlabel is `None` the widget spans the full
139+
width of the form.
140+
'''
141+
self.formWidget.insertWidget(row, name, qwidget, qlabel)
142+
143+
def insertWidgetToVerticalLayout(self, row, qwidget):
144+
'''
145+
Inserts a widget to the vertical layout at position specified by row.
146+
'''
147+
self.formWidget.uiElements['verticalLayout'].insertWidget(row, qwidget)
148+
149+
def getWidgetFromVerticalLayout(self, index):
150+
'''
151+
Returns the widget in the vertical layout located at position index.'''
152+
return self.formWidget.uiElements['verticalLayout'].itemAt(index).widget()
153+
154+
def removeWidget(self, widget):
155+
'''
156+
Removes the widget with the specified name from the form layout.
157+
This method delete the qwidget, and qlabel if present, from the widgets dictionary
158+
and sets their parent to `None`.
159+
160+
Parameters
161+
----------
162+
name : str
163+
The name of the widget to be removed.
164+
165+
Returns
166+
-------
167+
tuple or QWidget
168+
If the widget has a corresponding label, a tuple containing the widget
169+
and label is returned. Otherwise, only the widget is returned.
170+
'''
171+
return self.formWidget.removeWidget(widget)
172+
173+
def removeWidgetFromVerticalLayout(self, widget):
174+
'''
175+
Removes a widget from the vertical layout.
176+
'''
177+
self.formWidget.uiElements['verticalLayout'].removeWidget(widget)
178+
widget.setParent(None)
179+
return widget
180+
118181
def getNumWidgets(self):
119182
'''
120183
Returns the number of widgets in the form.
121184
'''
122185
return self.formWidget.getNumWidgets()
123186

124-
def insertWidget(self, index, qwidget):
125-
'''inserts a widget to the vertical layout at the specific index'''
126-
self.formWidget.uiElements['verticalLayout'].insertWidget(index, qwidget)
127-
128187
def getWidget(self, name, role='field'):
129-
'''returns the Widget by the name with which it has been added
188+
'''
189+
Returns the widget by the name with which it has been added.
130190
131191
By default it returns the widget that is the field in the form.
132-
The user can get the label by specifying the role to be label
133-
192+
The user can get the label by specifying the role to be label.
134193
Raises ValueError if the role is not field or label.
135194
'''
136195
return self.formWidget.getWidget(name, role)
137196

138197
def getWidgets(self):
139-
'''returns a dictionary of all the widgets in the form'''
198+
'''Returns a dictionary of the widgets currently present in the form.'''
140199
return self.formWidget.getWidgets()
141200

201+
def getWidgetRow(self, name, role='field'):
202+
'''
203+
Returns the widget row in the form layout by the widget name.
204+
This is the row of the widget in the form layout.
205+
'''
206+
return self.formWidget.getWidgetRow(name, role)
207+
142208
def setWidgetVisible(self, name, visible):
143209
'''
144210
Sets the visibility of the widget and associated label with the given name.
145-
Parameters:
146-
visible: bool
147-
True to set the widget visible, False to hide it
148-
name: str
149-
The name of the widget to set visible/invisible
150-
'''
151211
212+
Parameters
213+
----------
214+
name : str
215+
The name of the widget to set visible/invisible
216+
visible : bool
217+
True to set the widget visible, False to hide it
218+
'''
152219
self.formWidget.setWidgetVisible(name, visible)
153220

154221
def saveAllWidgetStates(self):
155222
'''
156-
Saves the state of all widgets in the form.
223+
Saves the state of all widgets currently present in the form.
157224
To later restore the states, use `restoreAllSavedWidgetStates()`.
158225
'''
159226
self.formWidget.saveAllWidgetStates()
160227

228+
def getWidgetStates(self):
229+
'''Returns the saved widget states.'''
230+
return self.formWidget.getWidgetStates()
231+
232+
def getDefaultWidgetStates(self):
233+
'''Returns the saved default widget states.'''
234+
return self.formWidget.getDefaultWidgetStates()
235+
161236
def restoreAllSavedWidgetStates(self):
162237
'''
163238
Restore all widgets in the form to the state saved by `saveAllWidgetStates()`.
@@ -169,60 +244,68 @@ def getAllWidgetStates(self):
169244
'''
170245
Returns
171246
-------
172-
states: dict
173-
Format: {'widget_name': {'value': str | bool | int, 'enabled': bool, 'visible': bool},
174-
...},
175-
e.g. {{'widget1': {'value': 1, 'enabled': True, 'visible': True},
176-
'widget2': {'value': 2, 'enabled': False, 'visible': False}}.
247+
dict
248+
Format: {'widget_name': {'value': str | bool | int, 'enabled': bool, 'visible': bool,
249+
'widget_row': int}, ...}.
250+
e.g. {'widget1': {'value': 1, 'enabled': True, 'visible': True, 'widget_row': 0},
251+
'widget2': {'value': 2, 'enabled': False, 'visible': False, 'widget_row': 1}}.
177252
'''
178253
return self.formWidget.getAllWidgetStates()
179254

180255
def getWidgetState(self, widget, role=None):
181256
'''
257+
Returns the current state of the widget in the form.
258+
182259
Parameters
183260
----------
184-
widget: QWidget or str
185-
The (name of) widget to get the state of.
186-
role: str, optional, default None, values: 'label', 'field', None.
187-
The role of the widget to get the state of (only if `widget` is a `str`).
188-
If unspecified, the widget is chosen based on `name=widget`.
261+
widget : QWidget or str
262+
The widget or its name (or its name + '_field' or '_label', when role is None) to get
263+
the state of.
264+
role : str, optional, default None, values: 'label', 'field', None.
265+
The role of the widget to apply the state to. This is used only if `widget` is the
266+
widget name string.
189267
190268
Returns
191269
-------
192-
dict
193-
Widget state, format: {'value': str | bool | int, 'enabled': bool, 'visible': bool},
194-
e.g. {'value': 1, 'enabled': True, 'visible': True}.
270+
state : dict
271+
Format: {'value': str | bool | int, 'enabled': bool, 'visible': bool,
272+
'widget_row' : int}.
273+
e.g. {'value': 1, 'enabled': True, 'visible': True, 'widget_row' : 0}.
195274
This can be used to restore the state of the widget using `setWidgetState()`.
196275
'''
197276
return self.formWidget.getWidgetState(widget, role)
198277

199278
def applyWidgetState(self, name, state, role=None):
200279
'''
201-
Applies the given state to the widget with the given name.
280+
Applies the given `state` to the widget associated with `name` and `role`.
281+
If role is None, the role is assigned to be 'field'.
202282
203283
Parameters
204284
----------
205-
name: str
285+
name : str
206286
The name of the widget to apply the state to.
207-
role: str, optional, default None, values: 'label', 'field', None.
287+
role : str, optional, default None, values: 'label', 'field', None.
208288
The role of the widget to apply the state to.
209-
If unspecified, the widget is chosen based on `name`.
210-
state: dict
211-
Format: {'value': str | bool | int, 'enabled': bool, 'visible': bool},
212-
e.g. {'value': 1, 'enabled': True, 'visible': True}.
289+
state : dict
290+
Format: {'value': str | bool | int, 'enabled': bool, 'visible': bool,
291+
'widget_row' : int}.
292+
e.g. {'value': 1, 'enabled': True, 'visible': True, 'widget_row' : 0}.
213293
'''
214294
return self.formWidget.applyWidgetState(name, state, role)
215295

216-
def applyWidgetStates(self, state):
296+
def applyWidgetStates(self, states):
217297
'''
218-
Applies the given states to the form's widgets.
298+
Applies the given states to the form's widgets. It raises an error if the keys in the
299+
dicitonary of states and the keys in the dictionary of widgets in the form are not the
300+
same.
219301
220302
Parameters
221303
----------
222-
state: dict
223-
Format: {'widget_name': {'value': str | bool | int, 'enabled': bool, 'visible': bool},
224-
...},
225-
e.g. {{'widget1': {'value': 1, 'enabled': True, 'visible': True},
226-
'widget2': {'value': 2, 'enabled': False, 'visible': False}}.
304+
states : dict
305+
Format: {'name_field': {'value': str | bool | int, 'enabled': bool, 'visible': bool,
306+
'widget_row' : int}, 'name_label': {'value': str | bool | int, 'enabled': bool,
307+
'visible': bool, 'widget_row' : int}, ...}.
308+
e.g. {'widget1': {'value': 1, 'enabled': True, 'visible': True, 'widget_row': 0},
309+
'widget2': {'value': 2, 'enabled': False, 'visible': False, 'widget_row': 1}}.
227310
'''
228-
return self.formWidget.applyWidgetStates(state)
311+
return self.formWidget.applyWidgetStates(states)

0 commit comments

Comments
 (0)