Skip to content

Commit af61844

Browse files
feat(editor): add RadioTabWidget
1 parent 6c7d283 commit af61844

File tree

3 files changed

+64
-6
lines changed

3 files changed

+64
-6
lines changed

qt_parameters/editor.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from . import utils
99
from .box import CollapsibleBox
10+
from .rediotab import RadioTabWidget
1011
from .scrollarea import VerticalScrollArea
1112
from .widgets import ParameterWidget, BoolParameter
1213

@@ -206,6 +207,9 @@ def values(self) -> dict[str, Any]:
206207
values[name] = widget.values()
207208
elif isinstance(widget, CollapsibleBox):
208209
values[name] = widget.checked()
210+
elif isinstance(widget, RadioTabWidget):
211+
if form := self.form(name.replace('_enabled', '')):
212+
values[name] = widget.currentWidget() == form
209213
return values
210214

211215
def set_values(self, values: dict) -> None:
@@ -220,6 +224,10 @@ def set_values(self, values: dict) -> None:
220224
widget.set_values(value)
221225
elif isinstance(widget, CollapsibleBox):
222226
widget.set_checked(value)
227+
elif isinstance(widget, RadioTabWidget):
228+
if value:
229+
if form := self.form(name.replace('_enabled', '')):
230+
widget.setCurrentWidget(form)
223231

224232
def set_defaults(self, values: dict) -> None:
225233
"""Set the default values of ParameterWidgets in the form."""
@@ -318,14 +326,23 @@ def add_form(self, form: ParameterForm, checkable: bool = False) -> CollapsibleB
318326

319327
return box
320328

321-
def add_forms(self, forms: Sequence[ParameterForm]) -> QtWidgets.QTabWidget:
322-
"""Add multiple forms and return the TabWidget."""
329+
def add_forms(
330+
self, forms: Sequence[ParameterForm], radio: bool = False
331+
) -> QtWidgets.QTabWidget:
332+
"""
333+
Add multiple forms and return the TabWidget. If radio is True, use a
334+
RadioTabWidget which only allows one form to be active.
335+
"""
323336

324337
# Validate the names before creating any widgets.
325338
for form in forms:
326339
self._validate_name(form.name())
327340

328-
tab_widget = QtWidgets.QTabWidget()
341+
if radio:
342+
tab_widget = RadioTabWidget()
343+
else:
344+
tab_widget = QtWidgets.QTabWidget()
345+
329346
for form in forms:
330347
name = form.name()
331348
self._widgets[name] = form
@@ -335,6 +352,9 @@ def add_forms(self, forms: Sequence[ParameterForm]) -> QtWidgets.QTabWidget:
335352
label = utils.title(name)
336353
tab_widget.addTab(form, label)
337354

355+
if radio:
356+
self._widgets[f'{name}_enabled'] = tab_widget
357+
338358
self.add_widget(tab_widget)
339359

340360
return tab_widget
@@ -524,6 +544,8 @@ def widgets(self) -> dict:
524544
widgets[name] = widget
525545
elif isinstance(widget, CollapsibleBox):
526546
widgets[name] = widget
547+
elif isinstance(widget, RadioTabWidget):
548+
widgets[name] = widget
527549
return widgets
528550

529551
@staticmethod

qt_parameters/rediotab.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from __future__ import annotations
2+
3+
from qt_material_icons import MaterialIcon
4+
from qtpy import QtWidgets
5+
6+
7+
class RadioTabWidget(QtWidgets.QTabWidget):
8+
def __init__(self, parent: QtWidgets.QWidget | None = None) -> None:
9+
super().__init__(parent)
10+
11+
self._unchecked_icon = MaterialIcon('radio_button_unchecked')
12+
self._checked_icon = MaterialIcon('radio_button_checked')
13+
14+
self.currentChanged.connect(self._current_changed)
15+
16+
def tabInserted(self, index: int) -> None:
17+
if not self.tabIcon(index):
18+
self.setTabIcon(index, self._unchecked_icon)
19+
20+
def _current_changed(self, index: int) -> None:
21+
for i in range(self.count()):
22+
if i == index:
23+
self.setTabIcon(i, self._checked_icon)
24+
else:
25+
self.setTabIcon(i, self._unchecked_icon)

tests/editor.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ def init_ui(self) -> None:
5757
try:
5858
parm = StringParameter('string')
5959
form.add_parameter(parm)
60-
except ValueError as e:
61-
logging.exception(e)
60+
except ValueError:
61+
logging.info(f'Unique names validated successfully.')
6262
self.remove_form(form)
6363
self.remove_widget(box)
6464

@@ -105,6 +105,17 @@ def init_ui(self) -> None:
105105
# TabWidget
106106
self.add_forms((multi_form, qt_form))
107107

108+
# RadioTabWidget
109+
form_tab_1 = ParameterForm('tab_1')
110+
parm = StringParameter('string')
111+
form_tab_1.add_parameter(parm)
112+
113+
form_tab_2 = ParameterForm('tab_2')
114+
parm = StringParameter('string')
115+
form_tab_2.add_parameter(parm)
116+
117+
self.add_forms((form_tab_1, form_tab_2), radio=True)
118+
108119
# Options
109120
self.add_separator()
110121

@@ -144,7 +155,7 @@ def __init__(self, parent: QtWidgets.QWidget | None = None) -> None:
144155

145156
def _init_ui(self) -> None:
146157
self.setWindowTitle('Parameter Editors')
147-
self.resize(640, 720)
158+
self.resize(640, 840)
148159

149160
layout = QtWidgets.QHBoxLayout()
150161
self.setLayout(layout)

0 commit comments

Comments
 (0)