bec_widgets.utils.error_popups ============================== .. py:module:: bec_widgets.utils.error_popups Attributes ---------- .. autoapisummary:: bec_widgets.utils.error_popups.RAISE_ERROR_DEFAULT Classes ------- .. autoapisummary:: bec_widgets.utils.error_popups.ExampleWidget bec_widgets.utils.error_popups.SafePropertyExampleWidget bec_widgets.utils.error_popups.WarningPopupUtility bec_widgets.utils.error_popups._ErrorPopupUtility Functions --------- .. autoapisummary:: bec_widgets.utils.error_popups.ErrorPopupUtility bec_widgets.utils.error_popups.SafeConnect bec_widgets.utils.error_popups.SafeProperty bec_widgets.utils.error_popups.SafeSlot bec_widgets.utils.error_popups._safe_connect_slot Module Contents --------------- .. py:class:: ExampleWidget(parent=None) Bases: :py:obj:`qtpy.QtWidgets.QWidget` Example widget to demonstrate error handling with the ErrorPopupUtility. Warnings -> This example works properly only with PySide6, PyQt6 has a bug with the error handling. .. py:method:: init_ui() .. py:method:: method_with_error_handling() This method raises an error and the exception is handled by the decorator. .. py:method:: method_without_error_handling() This method raises an error and the exception is not handled here. .. py:method:: trigger_warning() Trigger a warning using the WarningPopupUtility. .. py:attribute:: warning_utility .. py:class:: SafePropertyExampleWidget Bases: :py:obj:`qtpy.QtWidgets.QWidget` Example widget showcasing SafeProperty auto_emit modes. .. py:method:: _on_property_changed(prop_name: str, value) .. py:method:: _on_spinbox_callable(value: int) .. py:method:: _on_spinbox_input(value: int) .. py:method:: _on_spinbox_stored(value: int) .. py:method:: precision_callable() -> int .. py:method:: precision_input() -> int .. py:method:: precision_stored() -> int .. py:attribute:: label_callable .. py:attribute:: label_input .. py:attribute:: label_stored .. py:attribute:: property_changed .. py:attribute:: spinbox_callable .. py:attribute:: spinbox_input .. py:attribute:: spinbox_stored .. py:attribute:: status .. py:class:: WarningPopupUtility Bases: :py:obj:`qtpy.QtCore.QObject` Utility class to show warning popups in the application. .. py:method:: show_warning(title: str, message: str, detailed_text: str, widget: qtpy.QtWidgets.QWidget = None) Show a warning message with the given title, message, and detailed text. :param title: The title of the warning message. :type title: str :param message: The main text of the warning message. :type message: str :param detailed_text: The detailed text to show when the user expands the message. :type detailed_text: str :param widget: The parent widget for the message box. :type widget: QWidget .. py:method:: show_warning_message(title, message, detailed_text, widget) .. py:class:: _ErrorPopupUtility(parent=None) Bases: :py:obj:`qtpy.QtCore.QObject` Utility class to manage error popups in the application to show error messages to the users. This class is singleton and the error popup can be enabled or disabled globally or attach to widget methods with decorator @error_managed. .. py:method:: custom_exception_hook(exctype, value, tb, popup_error=False) .. py:method:: enable_global_error_popups(state: bool) Enable or disable global error popups for all applications. :param state: True to enable error popups, False to disable error popups. :type state: bool .. py:method:: format_traceback(traceback_message: str) -> str Format the traceback message to be displayed in the error popup by adding indentation to each line. :param traceback_message: The traceback message to be formatted. :type traceback_message: str :returns: The formatted traceback message. :rtype: str .. py:method:: get_error_message(exctype, value, tb) .. py:method:: parse_error_message(traceback_message) .. py:method:: show_error_message(title, message, widget) .. py:method:: show_property_error(title, message, widget) Show a property-specific error message. .. py:attribute:: enable_error_popup :value: False .. py:attribute:: error_occurred .. py:function:: ErrorPopupUtility() .. py:function:: SafeConnect(instance, signal, slot) Method to safely handle Qt signal-slot connections. The python object is only forwarded as a weak reference to avoid stale objects. :param instance: The instance to connect. :param signal: The signal to connect to. :param slot: The slot to connect. .. rubric:: Example >>> SafeConnect(self, qapp.theme.theme_changed, self._update_theme) .. py:function:: SafeProperty(prop_type, *prop_args, popup_error: bool = False, default: Any = None, auto_emit: bool = False, emit_value: Literal['stored', 'input'] | Callable[[object, object], object] = 'stored', emit_on_change: bool = True, **prop_kwargs) Decorator to create a Qt Property with safe getter and setter so that Qt Designer won't crash if an exception occurs in either method. :param prop_type: The property type (e.g., str, bool, int, custom classes, etc.) :param popup_error: If True, show a popup for any error; otherwise, ignore or log silently. :type popup_error: bool :param default: Any default/fallback value to return if the getter raises an exception. :param auto_emit: If True, automatically emit property_changed signal when setter is called. Requires the widget to have a property_changed signal (str, object). Note: This is different from Qt's 'notify' parameter which expects a Signal. :type auto_emit: bool :param emit_value: Controls which value is emitted when auto_emit=True. - "stored" (default): emit the value from the getter after setter runs - "input": emit the raw setter input - callable: called as emit_value(self_, value) after setter and must return the value to emit :param emit_on_change: If True, emit only when the stored value changes. :type emit_on_change: bool :param \*prop_args: Passed along to the underlying Qt Property constructor (check https://doc.qt.io/qt-6/properties.html). :param **prop_kwargs: Passed along to the underlying Qt Property constructor (check https://doc.qt.io/qt-6/properties.html). Usage: @SafeProperty(int, default=-1) def some_value(self) -> int: # your getter logic return ... # if an exception is raised, returns -1 @some_value.setter def some_value(self, val: int): # your setter logic ... # With auto-emit for toolbar sync: @SafeProperty(bool, auto_emit=True) def fft(self) -> bool: return self._fft @fft.setter def fft(self, value: bool): self._fft = value # property_changed.emit("fft", value) is called automatically # With custom emit modes: @SafeProperty(int, auto_emit=True, emit_value="stored") def precision_stored(self) -> int: return self._precision_stored @precision_stored.setter def precision_stored(self, value: int): self._precision_stored = max(0, int(value)) @SafeProperty(int, auto_emit=True, emit_value="input") def precision_input(self) -> int: return self._precision_input @precision_input.setter def precision_input(self, value: int): self._precision_input = max(0, int(value)) @SafeProperty(int, auto_emit=True, emit_value=lambda _self, v: int(v) * 10) def precision_callable(self) -> int: return self._precision_callable @precision_callable.setter def precision_callable(self, value: int): self._precision_callable = max(0, int(value)) .. py:function:: SafeSlot(*slot_args, **slot_kwargs) Function with args, acting like a decorator, applying "error_managed" decorator + Qt Slot to the passed function, to display errors instead of potentially raising an exception 'popup_error' keyword argument can be passed with boolean value if a dialog should pop up, otherwise error display is left to the original exception hook 'verify_sender' keyword argument can be passed with boolean value if the sender should be verified before executing the slot. If True, the slot will only execute if the sender is a QObject. This is useful to prevent function calls from already deleted objects. 'raise_error' keyword argument can be passed with boolean value if the error should be raised after the error is displayed. This is useful to propagate the error to the caller but should be used with great care to avoid segfaults. The keywords above are stored in a container which can be overridden by passing '_override_slot_params' keyword argument with a dictionary containing the keywords to override. This is useful to override the default behavior of the decorator for a specific function call. .. py:function:: _safe_connect_slot(weak_instance, weak_slot, *connect_args) Internal function used by SafeConnect to handle weak references to slots. .. py:data:: RAISE_ERROR_DEFAULT :value: False