diff --git a/mantidimaging/gui/utility/qt_helpers.py b/mantidimaging/gui/utility/qt_helpers.py index 7cb923ea876..ec49154b3fc 100644 --- a/mantidimaging/gui/utility/qt_helpers.py +++ b/mantidimaging/gui/utility/qt_helpers.py @@ -6,12 +6,13 @@ from __future__ import annotations import os +from abc import ABCMeta from enum import IntEnum, auto from logging import getLogger from typing import Any from collections.abc import Callable -from PyQt5 import uic # type: ignore +from PyQt5 import uic, sip # type: ignore from PyQt5.QtCore import QObject, Qt from PyQt5.QtWidgets import (QLabel, QLineEdit, QSpinBox, QDoubleSpinBox, QCheckBox, QWidget, QSizePolicy, QAction, QMenu, QPushButton, QLayout, QFileDialog, QComboBox) @@ -266,3 +267,8 @@ def populate_menu(menu: QMenu, actions_list: list[QAction]) -> None: action = QAction(menu_text, menu) action.triggered.connect(func) menu.addAction(action) + + +class _metaclass_sip_abc(sip.wrappertype, ABCMeta): + """Used for Mixins to avoid metaclass conflicts""" + ... diff --git a/mantidimaging/gui/widgets/auto_colour_menu/auto_color_menu.py b/mantidimaging/gui/widgets/auto_colour_menu/auto_color_menu.py index 781cb92075b..9aca633171c 100644 --- a/mantidimaging/gui/widgets/auto_colour_menu/auto_color_menu.py +++ b/mantidimaging/gui/widgets/auto_colour_menu/auto_color_menu.py @@ -1,10 +1,13 @@ # Copyright (C) 2024 ISIS Rutherford Appleton Laboratory UKRI # SPDX - License - Identifier: GPL-3.0-or-later from __future__ import annotations + +from abc import abstractmethod, ABC from typing import TYPE_CHECKING from PyQt5.QtWidgets import QAction +from mantidimaging.gui.utility.qt_helpers import _metaclass_sip_abc from mantidimaging.gui.widgets.palette_changer.view import PaletteChangerView if TYPE_CHECKING: @@ -13,21 +16,24 @@ from PyQt5.QtWidgets import QWidget -class AutoColorMenu: +class AutoColorMenu(ABC, metaclass=_metaclass_sip_abc): """ Mixin class to be used with MIImageView and MIMiniImageView """ def __init__(self) -> None: + super().__init__() self.auto_color_action: QAction | None = None @property + @abstractmethod def histogram(self) -> HistogramLUTItem: - raise NotImplementedError('Required histogram property not implemented') + ... @property + @abstractmethod def image_data(self) -> np.ndarray | None: - raise NotImplementedError('Required image_data property not implemented') + ... @property def other_histograms(self) -> list[HistogramLUTItem]: diff --git a/mantidimaging/gui/widgets/bad_data_overlay/bad_data_overlay.py b/mantidimaging/gui/widgets/bad_data_overlay/bad_data_overlay.py index 8c784b11db6..45ef95bc883 100644 --- a/mantidimaging/gui/widgets/bad_data_overlay/bad_data_overlay.py +++ b/mantidimaging/gui/widgets/bad_data_overlay/bad_data_overlay.py @@ -2,11 +2,13 @@ # SPDX - License - Identifier: GPL-3.0-or-later from __future__ import annotations +from abc import abstractmethod, ABC from collections.abc import Callable import numpy as np from pyqtgraph import ColorMap, ImageItem, ViewBox +from mantidimaging.gui.utility.qt_helpers import _metaclass_sip_abc from mantidimaging.gui.widgets.indicator_icon.view import IndicatorIconView from mantidimaging.core.utility import finder @@ -54,7 +56,7 @@ def clear(self) -> None: self.overlay.clear() -class BadDataOverlay: +class BadDataOverlay(ABC, metaclass=_metaclass_sip_abc): """ Mixin class to be used with MIImageView and MIMiniImageView """ @@ -69,12 +71,14 @@ def __init__(self) -> None: self.sigTimeChanged.connect(self.check_for_bad_data) @property + @abstractmethod def image_item(self) -> ImageItem: - raise NotImplementedError + ... @property + @abstractmethod def viewbox(self) -> ViewBox: - raise NotImplementedError + ... def enable_nan_check(self, enable: bool = True, actions: list[tuple[str, Callable]] | None = None) -> None: if enable: