diff --git a/conda.recipe/meta.yaml b/conda.recipe/meta.yaml index 1d67f3b420aeeaaf11629b30a1c26333b7f2aed4..3a0f5b3c26e70e91a6049837d4a4498ecf169379 100644 --- a/conda.recipe/meta.yaml +++ b/conda.recipe/meta.yaml @@ -20,7 +20,7 @@ requirements: - python >=3.9 - numpy >=1.23.0,<2.0 - obspy >=1.3.0 - - PySide6>=6.5.2 + - PySide6>=6.7 - matplotlib>=3.6.2 test: diff --git a/sohstationviewer/view/db_config/channel_dialog.py b/sohstationviewer/view/db_config/channel_dialog.py index 28dc07013c1e26da05892e607e544b9c7ae9ba3d..e58eb1d9bb08d48bf151da0779b6612d68be897e 100755 --- a/sohstationviewer/view/db_config/channel_dialog.py +++ b/sohstationviewer/view/db_config/channel_dialog.py @@ -5,34 +5,48 @@ GUI to add/edit/remove channels from typing import List, Union from PIL.ImageOps import contain -from PySide6.QtCore import Qt +from PySide6.QtCore import Qt, Signal, Slot from PySide6.QtWidgets import ( QMessageBox, QCheckBox, QWidget, QBoxLayout, QHBoxLayout, ) -from sohstationviewer.view.db_config.db_config_dialog import UiDBInfoDialog +from sohstationviewer.view.db_config.db_config_dialog import ( + UiDBInfoDialog, + set_widget_color, +) from sohstationviewer.database.process_db import execute_db -class CenteredCheckbox(QWidget): +class CenteredCheckBox(QWidget): + checkStateChanged = Signal(Qt.CheckState) """ A checkbox that is centered horizontally and vertically. - Implementation-wise, this puts a QCheckBox into a layout and centers it in - there. Method calls are then passed on to the internal QCheckBox for - processing. + Implementation-wise, this widget contains a layout, which contains a + centered QCheckBox. This is simply the standard method to center a widget + without having to use stylesheets. The main bulk of the custom code is to + pass to the internal QCheckBox for processing. + + This wrapper is intended to provide a more convenient way to work with a + centered checkbox. Without it, the internal QCheckBox has to be retrieved + every time we want to use it. This can become annoying to do, especially + since there is no convenient method provided to retrieve the checkbox. """ def __init__(self, parent=None): - super(CenteredCheckbox, self).__init__(parent) + super(CenteredCheckBox, self).__init__(parent) layout = QHBoxLayout() self.setLayout(layout) self.checkbox = QCheckBox() layout.addWidget(self.checkbox) + self.setAutoFillBackground(True) + layout.setContentsMargins(0, 0, 0, 0) layout.setAlignment(Qt.AlignmentFlag.AlignCenter) + self.checkbox.checkStateChanged.connect(self.checkStateChanged) + def isChecked(self) -> bool: return self.checkbox.isChecked() @@ -77,11 +91,43 @@ class ChannelDialog(UiDBInfoDialog): """ checked = (self.database_rows[row_idx][col_idx - 1] if row_idx < len(self.database_rows) else False) - checkbox = CenteredCheckbox(self.data_table_widget) + checkbox = CenteredCheckBox(self.data_table_widget) checkbox.setChecked(checked) + set_widget_color(checkbox) + checkbox.checkStateChanged.connect( + lambda check_state: + self.on_checkbox_toggle(bool(check_state.value), checkbox) + ) self.data_table_widget.setCellWidget(row_idx, col_idx, checkbox) return checkbox + @Slot() + def on_checkbox_toggle(self, checked: bool, checkbox: CenteredCheckBox): + """ + Called when a checkbox is toggled. Store whether the toggle reverts the + checkbox to its original state and style the checkbox accordingly. + + :param checked: whether the checkbox is checked after the toggle + :param checkbox: the widget whose content was changed. + """ + # Because this method is used in a lambda, passing the column and row + # indices directly would cause their value to be bound at the lambda's + # definition time. This causes problems when the checkbox is moved to a + # different row. + checkbox_x, checkbox_y = checkbox.pos().toTuple() + col_idx = self.data_table_widget.columnAt(checkbox_x) + row_idx = self.data_table_widget.rowAt(checkbox_y) + if row_idx == -1: + return + changed = False + if row_idx < len(self.database_rows): + if checked != self.database_rows[row_idx][col_idx - 1]: + changed = True + set_widget_color(checkbox, changed=changed) + else: + changed = True + self.changes_array[row_idx][col_idx - 1] = changed + def update_data_table_widget_items(self): """ Create list of parameters to used in widget for selecting parameters