diff --git a/src/pymmcore_widgets/_group_preset_widget/_add_first_preset_widget.py b/src/pymmcore_widgets/_group_preset_widget/_add_first_preset_widget.py index 34818c7a4..cb1a540b0 100644 --- a/src/pymmcore_widgets/_group_preset_widget/_add_first_preset_widget.py +++ b/src/pymmcore_widgets/_group_preset_widget/_add_first_preset_widget.py @@ -1,7 +1,6 @@ from __future__ import annotations from pymmcore_plus import CMMCorePlus -from qtpy.QtCore import Qt from qtpy.QtWidgets import ( QDialog, QGroupBox, @@ -11,15 +10,14 @@ QPushButton, QSizePolicy, QSpacerItem, - QTableWidget, - QTableWidgetItem, QVBoxLayout, QWidget, ) -from pymmcore_widgets._property_widget import PropertyWidget from pymmcore_widgets._util import block_core +from ._cfg_table import _CfgTable + class AddFirstPresetWidget(QDialog): """A widget to create the first specified group's preset.""" @@ -39,7 +37,7 @@ def __init__( self._create_gui() - self._populate_table() + self.table.populate_table(self._dev_prop_val_list) def _create_gui(self) -> None: self.setWindowTitle(f"Add the first Preset to the new '{self._group}' Group") @@ -58,7 +56,7 @@ def _create_gui(self) -> None: top_wdg = self._create_top_wdg() wdg_layout.addWidget(top_wdg) - self.table = _Table() + self.table = _CfgTable() wdg_layout.addWidget(self.table) bottom_wdg = self._create_bottom_wdg() @@ -121,26 +119,8 @@ def _create_bottom_wdg(self) -> QWidget: return wdg - def _populate_table(self) -> None: - self.table.clearContents() - - self.table.setRowCount(len(self._dev_prop_val_list)) - for idx, (dev, prop, _) in enumerate(self._dev_prop_val_list): - item = QTableWidgetItem(f"{dev}-{prop}") - wdg = PropertyWidget(dev, prop, mmcore=self._mmc) - wdg._value_widget.valueChanged.disconnect() # type: ignore - self.table.setItem(idx, 0, item) - self.table.setCellWidget(idx, 1, wdg) - def _create_first_preset(self) -> None: - dev_prop_val = [] - for row in range(self.table.rowCount()): - device_property = self.table.item(row, 0).text() - dev = device_property.split("-")[0] - prop = device_property.split("-")[1] - value = str(self.table.cellWidget(row, 1).value()) - dev_prop_val.append((dev, prop, value)) - + dev_prop_val = self.table.get_state() preset = self.preset_name_lineedit.text() if not preset: preset = self.preset_name_lineedit.placeholderText() @@ -153,20 +133,3 @@ def _create_first_preset(self) -> None: self.close() self.parent().close() - - -class _Table(QTableWidget): - """Set table properties for EditPresetWidget.""" - - def __init__(self) -> None: - super().__init__() - hdr = self.horizontalHeader() - hdr.setSectionResizeMode(hdr.ResizeMode.Stretch) - hdr.setDefaultAlignment(Qt.AlignmentFlag.AlignHCenter) - vh = self.verticalHeader() - vh.setVisible(False) - vh.setSectionResizeMode(vh.ResizeMode.Fixed) - vh.setDefaultSectionSize(24) - self.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers) - self.setColumnCount(2) - self.setHorizontalHeaderLabels(["Device-Property", "Value"]) diff --git a/src/pymmcore_widgets/_group_preset_widget/_add_preset_widget.py b/src/pymmcore_widgets/_group_preset_widget/_add_preset_widget.py index 155629acc..6b65a3ed5 100644 --- a/src/pymmcore_widgets/_group_preset_widget/_add_preset_widget.py +++ b/src/pymmcore_widgets/_group_preset_widget/_add_preset_widget.py @@ -3,7 +3,6 @@ import warnings from pymmcore_plus import CMMCorePlus -from qtpy.QtCore import Qt from qtpy.QtWidgets import ( QDialog, QGroupBox, @@ -13,15 +12,14 @@ QPushButton, QSizePolicy, QSpacerItem, - QTableWidget, - QTableWidgetItem, QVBoxLayout, QWidget, ) -from pymmcore_widgets._property_widget import PropertyWidget from pymmcore_widgets._util import block_core +from ._cfg_table import _CfgTable + class AddPresetWidget(QDialog): """A widget to add presets to a specified group.""" @@ -53,7 +51,7 @@ def _create_gui(self) -> None: top_wdg = self._create_top_wdg() wdg_layout.addWidget(top_wdg) - self.table = _Table() + self.table = _CfgTable() wdg_layout.addWidget(self.table) bottom_wdg = self._create_bottom_wdg() @@ -114,8 +112,6 @@ def _create_bottom_wdg(self) -> QWidget: return wdg def _populate_table(self) -> None: - self.table.clearContents() - dev_prop = [] for preset in self._mmc.getAvailableConfigs(self._group): dev_prop.extend( @@ -125,14 +121,7 @@ def _populate_table(self) -> None: if (k[0], k[1]) not in dev_prop ] ) - - self.table.setRowCount(len(dev_prop)) - for idx, (dev, prop) in enumerate(dev_prop): - item = QTableWidgetItem(f"{dev}-{prop}") - wdg = PropertyWidget(dev, prop, mmcore=self._mmc) - wdg._value_widget.valueChanged.disconnect() # type: ignore - self.table.setItem(idx, 0, item) - self.table.setCellWidget(idx, 1, wdg) + self.table.populate_table(dev_prop) def _add_preset(self) -> None: preset_name = self.preset_name_lineedit.text() @@ -148,14 +137,7 @@ def _add_preset(self) -> None: if not preset_name: preset_name = self.preset_name_lineedit.placeholderText() - dev_prop_val = [] - for row in range(self.table.rowCount()): - device_property = self.table.item(row, 0).text() - dev = device_property.split("-")[0] - prop = device_property.split("-")[1] - value = str(self.table.cellWidget(row, 1).value()) - dev_prop_val.append((dev, prop, value)) - + dev_prop_val = self.table.get_state() for p in self._mmc.getAvailableConfigs(self._group): dpv_preset = [ (k[0], k[1], k[2]) for k in self._mmc.getConfigData(self._group, p) @@ -171,28 +153,11 @@ def _add_preset(self) -> None: return with block_core(self._mmc.events): - for d, p, v in dev_prop_val: - self._mmc.defineConfig(self._group, preset_name, d, p, v) + for dev, prop, val in dev_prop_val: + self._mmc.defineConfig(self._group, preset_name, dev, prop, val) - self._mmc.events.configDefined.emit(self._group, preset_name, d, p, v) + self._mmc.events.configDefined.emit(self._group, preset_name, dev, prop, val) self.info_lbl.setStyleSheet("") self.info_lbl.setText(f"'{preset_name}' has been added!") self.preset_name_lineedit.setPlaceholderText(self._get_placeholder_name()) - - -class _Table(QTableWidget): - """Set table properties for EditPresetWidget.""" - - def __init__(self) -> None: - super().__init__() - hdr = self.horizontalHeader() - hdr.setSectionResizeMode(hdr.ResizeMode.Stretch) - hdr.setDefaultAlignment(Qt.AlignmentFlag.AlignHCenter) - vh = self.verticalHeader() - vh.setVisible(False) - vh.setSectionResizeMode(vh.ResizeMode.Fixed) - vh.setDefaultSectionSize(24) - self.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers) - self.setColumnCount(2) - self.setHorizontalHeaderLabels(["Device-Property", "Value"]) diff --git a/src/pymmcore_widgets/_group_preset_widget/_cfg_table.py b/src/pymmcore_widgets/_group_preset_widget/_cfg_table.py new file mode 100644 index 000000000..ae72d97e8 --- /dev/null +++ b/src/pymmcore_widgets/_group_preset_widget/_cfg_table.py @@ -0,0 +1,47 @@ +from __future__ import annotations + +from typing import Any, Sequence, cast + +from qtpy.QtCore import Qt +from qtpy.QtWidgets import QTableWidget, QTableWidgetItem + +from pymmcore_widgets._property_widget import PropertyWidget + +DEV_PROP_ROLE = Qt.ItemDataRole.UserRole + 1 + + +class _CfgTable(QTableWidget): + """Set table properties for EditPresetWidget.""" + + def __init__(self) -> None: + super().__init__() + hdr = self.horizontalHeader() + hdr.setSectionResizeMode(hdr.ResizeMode.Stretch) + hdr.setDefaultAlignment(Qt.AlignmentFlag.AlignHCenter) + vh = self.verticalHeader() + vh.setVisible(False) + vh.setSectionResizeMode(vh.ResizeMode.Fixed) + vh.setDefaultSectionSize(24) + self.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers) + self.setColumnCount(2) + self.setHorizontalHeaderLabels(["Device-Property", "Value"]) + + def populate_table(self, dev_prop_val: Sequence[Sequence[Any]]) -> None: + self.clearContents() + self.setRowCount(len(dev_prop_val)) + for idx, (dev, prop, *_) in enumerate(dev_prop_val): + item = QTableWidgetItem(f"{dev}-{prop}") + item.setData(DEV_PROP_ROLE, (dev, prop)) + wdg = PropertyWidget(dev, prop, connect_core=False) + self.setItem(idx, 0, item) + self.setCellWidget(idx, 1, wdg) + + def get_state(self) -> list[tuple[str, str, str]]: + dev_prop_val = [] + for row in range(self.rowCount()): + if (dev_prop_item := self.item(row, 0)) and ( + wdg := cast("PropertyWidget", self.cellWidget(row, 1)) + ): + dev, prop = dev_prop_item.data(DEV_PROP_ROLE) + dev_prop_val.append((dev, prop, str(wdg.value()))) + return dev_prop_val diff --git a/src/pymmcore_widgets/_group_preset_widget/_edit_preset_widget.py b/src/pymmcore_widgets/_group_preset_widget/_edit_preset_widget.py index 4b868c679..ffb04d347 100644 --- a/src/pymmcore_widgets/_group_preset_widget/_edit_preset_widget.py +++ b/src/pymmcore_widgets/_group_preset_widget/_edit_preset_widget.py @@ -3,7 +3,6 @@ import warnings from pymmcore_plus import CMMCorePlus -from qtpy.QtCore import Qt from qtpy.QtWidgets import ( QComboBox, QDialog, @@ -14,16 +13,15 @@ QPushButton, QSizePolicy, QSpacerItem, - QTableWidget, - QTableWidgetItem, QVBoxLayout, QWidget, ) from superqt.utils import signals_blocked -from pymmcore_widgets._property_widget import PropertyWidget from pymmcore_widgets._util import block_core +from ._cfg_table import _CfgTable + class EditPresetWidget(QDialog): """A widget to edit a specified group's presets.""" @@ -60,7 +58,7 @@ def _create_gui(self) -> None: # sourcery skip: class-extract-method top_wdg = self._create_top_wdg() wdg_layout.addWidget(top_wdg) - self.table = _Table() + self.table = _CfgTable() wdg_layout.addWidget(self.table) bottom_wdg = self._create_bottom_wdg() @@ -151,20 +149,12 @@ def _resize_combo_height(self, max_items: int) -> None: def _populate_table_and_combo(self) -> None: self._update_combo() - self.table.clearContents() - dev_prop_val = [ (k[0], k[1], k[2]) for k in self._mmc.getConfigData(self._group, self._preset) ] - self.table.setRowCount(len(dev_prop_val)) - for idx, (dev, prop, val) in enumerate(dev_prop_val): - item = QTableWidgetItem(f"{dev}-{prop}") - wdg = PropertyWidget(dev, prop, mmcore=self._mmc) - wdg._value_widget.valueChanged.disconnect() # type: ignore - wdg.setValue(val) - self.table.setItem(idx, 0, item) - self.table.setCellWidget(idx, 1, wdg) + + self.table.populate_table(dev_prop_val) def _on_combo_changed(self, preset: str) -> None: self._preset = preset @@ -173,13 +163,7 @@ def _on_combo_changed(self, preset: str) -> None: self._populate_table_and_combo() def _apply_changes(self) -> None: - dev_prop_val = [] - for row in range(self.table.rowCount()): - device_property = self.table.item(row, 0).text() - dev = device_property.split("-")[0] - prop = device_property.split("-")[1] - value = str(self.table.cellWidget(row, 1).value()) - dev_prop_val.append((dev, prop, value)) + dev_prop_val = self.table.get_state() for p in self._mmc.getAvailableConfigs(self._group): dpv_preset = [ @@ -205,29 +189,12 @@ def _apply_changes(self) -> None: self._preset = self.preset_name_lineedit.text() with block_core(self._mmc.events): - for d, p, v in dev_prop_val: - self._mmc.defineConfig(self._group, self._preset, d, p, v) + for dev, prop, val in dev_prop_val: + self._mmc.defineConfig(self._group, self._preset, dev, prop, val) - self._mmc.events.configDefined.emit(self._group, self._preset, d, p, v) + self._mmc.events.configDefined.emit(self._group, self._preset, dev, prop, val) self._update_combo() self.info_lbl.setStyleSheet("") self.info_lbl.setText(f"'{self._preset}' has been modified!") - - -class _Table(QTableWidget): - """Set table properties for EditPresetWidget.""" - - def __init__(self) -> None: - super().__init__() - hdr = self.horizontalHeader() - hdr.setSectionResizeMode(hdr.ResizeMode.Stretch) - hdr.setDefaultAlignment(Qt.AlignmentFlag.AlignHCenter) - vh = self.verticalHeader() - vh.setVisible(False) - vh.setSectionResizeMode(vh.ResizeMode.Fixed) - vh.setDefaultSectionSize(24) - self.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers) - self.setColumnCount(2) - self.setHorizontalHeaderLabels(["Device-Property", "Value"])