diff --git a/bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py b/bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py index 973a2f20..aa9ad588 100644 --- a/bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py +++ b/bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py @@ -1,12 +1,13 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -from qtpy.QtCore import Slot from qtpy.QtDesigner import QExtensionFactory, QPyDesignerTaskMenuExtension from qtpy.QtGui import QAction from qtpy.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout from tictactoe import TicTacToe +from bec_widgets.qt_utils.error_popups import SafeSlot as Slot + class TicTacToeDialog(QDialog): # pragma: no cover def __init__(self, parent): diff --git a/bec_widgets/qt_utils/error_popups.py b/bec_widgets/qt_utils/error_popups.py index baf24e93..3cac06dc 100644 --- a/bec_widgets/qt_utils/error_popups.py +++ b/bec_widgets/qt_utils/error_popups.py @@ -34,7 +34,7 @@ class WarningPopupUtility(QObject): Utility class to show warning popups in the application. """ - @Slot(str, str, str, QWidget) + @SafeSlot(str, str, str, QWidget) def show_warning_message(self, title, message, detailed_text, widget): msg = QMessageBox(widget) msg.setIcon(QMessageBox.Warning) @@ -75,7 +75,7 @@ class _ErrorPopupUtility(QObject): self._initialized = True sys.excepthook = self.custom_exception_hook - @Slot(str, str, QWidget) + @SafeSlot(str, str, QWidget) def show_error_message(self, title, message, widget): detailed_text = self.format_traceback(message) error_message = self.parse_error_message(detailed_text) diff --git a/bec_widgets/qt_utils/settings_dialog.py b/bec_widgets/qt_utils/settings_dialog.py index d47cb570..97d8c1fa 100644 --- a/bec_widgets/qt_utils/settings_dialog.py +++ b/bec_widgets/qt_utils/settings_dialog.py @@ -1,6 +1,7 @@ -from qtpy.QtCore import Slot from qtpy.QtWidgets import QDialog, QDialogButtonBox, QHBoxLayout, QPushButton, QVBoxLayout, QWidget +from bec_widgets.qt_utils.error_popups import SafeSlot as Slot + class SettingWidget(QWidget): """ diff --git a/bec_widgets/utils/bec_connector.py b/bec_widgets/utils/bec_connector.py index 050fc407..fd4f9272 100644 --- a/bec_widgets/utils/bec_connector.py +++ b/bec_widgets/utils/bec_connector.py @@ -10,11 +10,11 @@ import yaml from bec_lib.utils.import_utils import lazy_import_from from pydantic import BaseModel, Field, field_validator from qtpy.QtCore import QObject, QRunnable, QThreadPool, Signal -from qtpy.QtCore import Slot as pyqtSlot from qtpy.QtWidgets import QApplication from bec_widgets.cli.rpc_register import RPCRegister from bec_widgets.qt_utils.error_popups import ErrorPopupUtility +from bec_widgets.qt_utils.error_popups import SafeSlot as pyqtSlot from bec_widgets.utils.yaml_dialog import load_yaml, load_yaml_gui, save_yaml, save_yaml_gui BECDispatcher = lazy_import_from("bec_widgets.utils.bec_dispatcher", ("BECDispatcher",)) diff --git a/bec_widgets/widgets/console/console.py b/bec_widgets/widgets/console/console.py index 97c9a047..c2b2247b 100644 --- a/bec_widgets/widgets/console/console.py +++ b/bec_widgets/widgets/console/console.py @@ -18,10 +18,11 @@ import pyte from qtpy import QtCore, QtGui, QtWidgets from qtpy.QtCore import QSize, QSocketNotifier, Qt from qtpy.QtCore import Signal as pyqtSignal -from qtpy.QtCore import Slot as pyqtSlot from qtpy.QtGui import QClipboard, QTextCursor from qtpy.QtWidgets import QApplication, QHBoxLayout, QScrollBar, QSizePolicy +from bec_widgets.qt_utils.error_popups import SafeSlot as Slot + ansi_colors = { "black": "#000000", "red": "#CD0000", @@ -289,7 +290,7 @@ class _TerminalWidget(QtWidgets.QPlainTextEdit): old["value"] = value self.dataReady(self.backend.screen, reset_scroll=False) - @pyqtSlot(object) + @Slot(object) def keyPressEvent(self, event): """ Redirect all keystrokes to the terminal process. diff --git a/bec_widgets/widgets/figure/plots/axis_settings.py b/bec_widgets/widgets/figure/plots/axis_settings.py index 10572883..75d55d0a 100644 --- a/bec_widgets/widgets/figure/plots/axis_settings.py +++ b/bec_widgets/widgets/figure/plots/axis_settings.py @@ -1,8 +1,8 @@ import os -from qtpy.QtCore import Slot from qtpy.QtWidgets import QVBoxLayout +from bec_widgets.qt_utils.error_popups import SafeSlot as Slot from bec_widgets.qt_utils.settings_dialog import SettingWidget from bec_widgets.utils import UILoader from bec_widgets.utils.widget_io import WidgetIO diff --git a/bec_widgets/widgets/figure/plots/image/image.py b/bec_widgets/widgets/figure/plots/image/image.py index f4d58539..78580d89 100644 --- a/bec_widgets/widgets/figure/plots/image/image.py +++ b/bec_widgets/widgets/figure/plots/image/image.py @@ -7,9 +7,9 @@ import numpy as np from bec_lib.endpoints import MessageEndpoints from pydantic import BaseModel, Field, ValidationError from qtpy.QtCore import QThread -from qtpy.QtCore import Slot as pyqtSlot from qtpy.QtWidgets import QWidget +from bec_widgets.qt_utils.error_popups import SafeSlot as Slot from bec_widgets.utils import EntryValidator from bec_widgets.widgets.figure.plots.image.image_item import BECImageItem, ImageItemConfig from bec_widgets.widgets.figure.plots.image.image_processor import ( @@ -500,7 +500,7 @@ class BECImageShow(BECPlotBase): self.update_image(device, data) self.update_vrange(device, self.processor.config.stats) - @pyqtSlot(dict) + @Slot(dict) def on_image_update(self, msg: dict): """ Update the image of the device monitor from bec. @@ -514,7 +514,7 @@ class BECImageShow(BECPlotBase): image.raw_data = data self.process_image(device, image, data) - @pyqtSlot(str, np.ndarray) + @Slot(str, np.ndarray) def update_image(self, device: str, data: np.ndarray): """ Update the image of the device monitor. @@ -526,7 +526,7 @@ class BECImageShow(BECPlotBase): image_to_update = self._images["device_monitor_2d"][device] image_to_update.updateImage(data, autoLevels=image_to_update.config.autorange) - @pyqtSlot(str, ImageStats) + @Slot(str, ImageStats) def update_vrange(self, device: str, stats: ImageStats): """ Update the scaling of the image. diff --git a/bec_widgets/widgets/figure/plots/motor_map/motor_map.py b/bec_widgets/widgets/figure/plots/motor_map/motor_map.py index b896cb0b..56e0f7a1 100644 --- a/bec_widgets/widgets/figure/plots/motor_map/motor_map.py +++ b/bec_widgets/widgets/figure/plots/motor_map/motor_map.py @@ -10,9 +10,9 @@ from pydantic import Field, ValidationError, field_validator from pydantic_core import PydanticCustomError from qtpy import QtCore, QtGui from qtpy.QtCore import Signal as pyqtSignal -from qtpy.QtCore import Slot from qtpy.QtWidgets import QWidget +from bec_widgets.qt_utils.error_popups import SafeSlot as Slot from bec_widgets.utils import Colors, EntryValidator from bec_widgets.widgets.figure.plots.plot_base import BECPlotBase, SubplotConfig from bec_widgets.widgets.figure.plots.waveform.waveform import Signal, SignalData @@ -444,7 +444,7 @@ class BECMotorMap(BECPlotBase): return None @Slot() - def _update_plot(self): + def _update_plot(self, _=None): """Update the motor map plot.""" # If the number of points exceeds max_points, delete the oldest points if len(self.database_buffer["x"]) > self.config.max_points: diff --git a/bec_widgets/widgets/figure/plots/waveform/waveform.py b/bec_widgets/widgets/figure/plots/waveform/waveform.py index 127c941d..47a7492d 100644 --- a/bec_widgets/widgets/figure/plots/waveform/waveform.py +++ b/bec_widgets/widgets/figure/plots/waveform/waveform.py @@ -11,9 +11,9 @@ from bec_lib.endpoints import MessageEndpoints from pydantic import Field, ValidationError, field_validator from pyqtgraph.exporters import MatplotlibExporter from qtpy.QtCore import Signal as pyqtSignal -from qtpy.QtCore import Slot as pyqtSlot from qtpy.QtWidgets import QWidget +from bec_widgets.qt_utils.error_popups import SafeSlot as Slot from bec_widgets.utils import Colors, EntryValidator from bec_widgets.widgets.figure.plots.plot_base import BECPlotBase, SubplotConfig from bec_widgets.widgets.figure.plots.waveform.waveform_curve import ( @@ -391,7 +391,7 @@ class BECWaveform(BECPlotBase): self.async_signal_update.emit() self.scan_signal_update.emit() - @pyqtSlot() + @Slot() def auto_range(self): self.plot_item.autoRange() @@ -408,7 +408,7 @@ class BECWaveform(BECPlotBase): """ self.plot_item.enableAutoRange(axis, enabled) - @pyqtSlot() + @Slot() def auto_range(self): self.plot_item.autoRange() @@ -642,7 +642,7 @@ class BECWaveform(BECPlotBase): self.refresh_dap() return curve - @pyqtSlot() + @Slot() def get_dap_params(self) -> dict: """ Get the DAP parameters of all DAP curves. @@ -655,7 +655,7 @@ class BECWaveform(BECPlotBase): params[curve_id] = curve.dap_params return params - @pyqtSlot() + @Slot() def get_dap_summary(self) -> dict: """ Get the DAP summary of all DAP curves. @@ -921,7 +921,7 @@ class BECWaveform(BECPlotBase): else: raise IndexError(f"Curve order {N} out of range.") - @pyqtSlot(dict) + @Slot(dict) def on_scan_status(self, msg): """ Handle the scan status message. @@ -945,7 +945,7 @@ class BECWaveform(BECPlotBase): for curve_id, curve in self._curves_data["async"].items(): self.setup_async(curve.config.signals.y.name) - @pyqtSlot(dict, dict) + @Slot(dict, dict) def on_scan_segment(self, msg: dict, metadata: dict): """ Handle new scan segments and saves data to a dictionary. Linked through bec_dispatcher. @@ -1004,7 +1004,7 @@ class BECWaveform(BECPlotBase): self.update_dap, MessageEndpoints.dap_response(f"{new_scan_id}-{self.gui_id}") ) - @pyqtSlot(str) + @Slot(str) def setup_async(self, device: str): self.bec_dispatcher.disconnect_slot( self.on_async_readback, MessageEndpoints.device_async_readback(self.old_scan_id, device) @@ -1020,8 +1020,8 @@ class BECWaveform(BECPlotBase): from_start=True, ) - @pyqtSlot() - def refresh_dap(self): + @Slot() + def refresh_dap(self, _=None): """ Refresh the DAP curves with the latest data from the DAP model MessageEndpoints.dap_response(). """ @@ -1069,7 +1069,7 @@ class BECWaveform(BECPlotBase): ) self.client.connector.set_and_publish(MessageEndpoints.dap_request(), msg) - @pyqtSlot(dict, dict) + @Slot(dict, dict) def update_dap(self, msg, metadata): self.msg = msg scan_id, x_name, x_entry, y_name, y_entry = msg["dap_request"].content["config"]["args"] @@ -1089,7 +1089,7 @@ class BECWaveform(BECPlotBase): self.dap_summary_update.emit(curve.dap_summary) break - @pyqtSlot(dict, dict) + @Slot(dict, dict) def on_async_readback(self, msg, metadata): """ Get async data readback. @@ -1127,7 +1127,7 @@ class BECWaveform(BECPlotBase): else: curve.setData(data_plot) - @pyqtSlot() + @Slot() def replot_async_curve(self): try: data = self.scan_item.async_data @@ -1152,8 +1152,8 @@ class BECWaveform(BECPlotBase): else: curve.setData(data_x, data_y) - @pyqtSlot() - def _update_scan_curves(self): + @Slot() + def _update_scan_curves(self, _=None): """ Update the scan curves with the data from the scan segment. """ diff --git a/bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.py b/bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.py index f7267ba0..d027a877 100644 --- a/bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.py +++ b/bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.py @@ -1,8 +1,8 @@ import os -from qtpy.QtCore import Slot from qtpy.QtWidgets import QVBoxLayout +from bec_widgets.qt_utils.error_popups import SafeSlot as Slot from bec_widgets.qt_utils.settings_dialog import SettingWidget from bec_widgets.utils import UILoader from bec_widgets.utils.widget_io import WidgetIO diff --git a/bec_widgets/widgets/stop_button/stop_button.py b/bec_widgets/widgets/stop_button/stop_button.py index 8038d56d..79db8c24 100644 --- a/bec_widgets/widgets/stop_button/stop_button.py +++ b/bec_widgets/widgets/stop_button/stop_button.py @@ -1,6 +1,6 @@ -from qtpy.QtCore import Slot from qtpy.QtWidgets import QPushButton +from bec_widgets.qt_utils.error_popups import SafeSlot as Slot from bec_widgets.utils.bec_widget import BECWidget diff --git a/bec_widgets/widgets/waveform/waveform_popups/dap_summary_dialog/dap_summary_dialog.py b/bec_widgets/widgets/waveform/waveform_popups/dap_summary_dialog/dap_summary_dialog.py index 6b4aeb1f..00512e05 100644 --- a/bec_widgets/widgets/waveform/waveform_popups/dap_summary_dialog/dap_summary_dialog.py +++ b/bec_widgets/widgets/waveform/waveform_popups/dap_summary_dialog/dap_summary_dialog.py @@ -1,8 +1,8 @@ import os -from qtpy.QtCore import Slot from qtpy.QtWidgets import QDialog, QTreeWidgetItem, QVBoxLayout +from bec_widgets.qt_utils.error_popups import SafeSlot as Slot from bec_widgets.utils import UILoader diff --git a/tests/unit_tests/test_bec_connector.py b/tests/unit_tests/test_bec_connector.py index a8446886..040b4461 100644 --- a/tests/unit_tests/test_bec_connector.py +++ b/tests/unit_tests/test_bec_connector.py @@ -2,9 +2,9 @@ import time import pytest -from qtpy.QtCore import Slot from qtpy.QtWidgets import QApplication +from bec_widgets.qt_utils.error_popups import SafeSlot as Slot from bec_widgets.utils import BECConnector, ConnectionConfig from .client_mocks import mocked_client