Beispiel #1
0
def execute():
    # all data will be row-major, so this needs to be specified as the default is col-major
    pyqtgraph.setConfigOptions(imageAxisOrder="row-major")

    # create the GUI event loop
    q_application = QApplication(sys.argv)
    q_application.setApplicationName("Mantid Imaging")
    application_window = MainWindowView()

    sys.excepthook = lambda exc_type, exc_value, exc_traceback: application_window.uncaught_exception(
        "".join(traceback.format_exception_only(exc_type, exc_value)), "".join(
            traceback.format_exception(exc_type, exc_value, exc_traceback)))

    def dont_let_qt_shutdown_while_debugging(type, value, tback):
        # log the exception here
        logging.getLogger(__name__).error(
            f"Exception {type} encountered:\n{traceback.format_exception(type, value, tback)}"
        )
        # then call the default handler
        sys.__excepthook__(type, value, tback)

    if os.environ.get("PYDEVD_LOAD_VALUES_ASYNC", False):
        sys.excepthook = dont_let_qt_shutdown_while_debugging
    application_window.show()

    return sys.exit(q_application.exec_())
Beispiel #2
0
class EyesManager:
    def __init__(self, application_name="Mantid Imaging", test_name=None):
        self.application_name = application_name
        self.eyes = Eyes()
        self.eyes.match_level = MatchLevel.CONTENT
        self.image_directory = None
        self.imaging = None
        if test_name is None:
            test_name = self.application_name + " Tests"
        self.test_name = test_name

    def set_match_level(self, level: MatchLevel):
        self.eyes.match_level = level

    def set_batch(self, batch_id):
        batch_info = BatchInfo()
        batch_info.name = self.test_name
        batch_info.id = batch_id
        self.eyes.batch = batch_info

    def abort(self):
        self.eyes.abort_if_not_closed()

    def check_target(self, widget: QWidget = None):
        test_file_name = os.path.basename(inspect.stack()[2][1])
        test_method_name = inspect.stack()[2][3]
        test_image_name = test_file_name.rpartition(
            ".")[0] + "_" + test_method_name

        image = self._take_screenshot(widget=widget,
                                      image_name=test_image_name)

        if self.eyes.api_key == "local":
            return

        if not self.eyes.is_open:
            self.eyes.open(self.application_name,
                           test_file_name,
                           dimension={
                               'width': VIEWPORT_WIDTH,
                               'height': VIEWPORT_HEIGHT
                           })
        self.eyes.check_image(image, test_method_name)

    def close_imaging(self):
        self.imaging.close()

    def start_imaging(self):
        self.imaging = MainWindowView(open_dialogs=False)
        self.imaging.ask_to_use_closest_to_180 = mock.Mock(return_value=False)
        self.imaging.show()
        QApplication.processEvents()

    def _take_screenshot(self, widget: QWidget = None, image_name=None):
        """
        :param widget: Widget to take screen shot of or main window if None.
        :param image_name: File name for screenshot
        :return: Will return the path to the saved image, or None if failed.
        """
        if self.image_directory is None:
            directory = mkdtemp()
        else:
            directory = self.image_directory

        if widget is None and self.imaging is not None:
            widget = self.imaging

        if not isinstance(widget, QWidget):
            raise ValueError("widget is not a QWidget")

        time.sleep(0.2)
        QApplication.processEvents()
        window_image = widget.grab()

        if image_name is None:
            image_name = str(uuid4())

        file_path = os.path.join(directory, image_name) + ".png"

        if window_image.save(file_path, "PNG"):
            return file_path
        else:
            raise IOError("Failed to save", file_path)

    def close_eyes(self):
        if self.eyes.is_open:
            self.eyes.close()
class GuiSystemBase(unittest.TestCase):
    app: QApplication

    def setUp(self) -> None:
        self.main_window = MainWindowView()
        self.main_window.show()
        QTest.qWait(SHORT_DELAY)

    def tearDown(self) -> None:
        QTimer.singleShot(SHORT_DELAY, lambda: self._click_messageBox("Yes"))
        self.main_window.close()
        QTest.qWait(SHORT_DELAY)

    @classmethod
    def _click_messageBox(cls, button_text: str):
        """Needs to be queued with QTimer.singleShot before triggering the message box"""
        for widget in cls.app.topLevelWidgets():
            if isinstance(widget, QMessageBox) and widget.isVisible():
                for button in widget.buttons():
                    if button.text().replace("&", "") == button_text:
                        QTest.mouseClick(button, Qt.LeftButton)
                        return
                button_texts = [button.text() for button in widget.buttons()]
                raise ValueError(
                    f"Could not find button '{button_text}' in {button_texts}.\n"
                    f"Message box: {widget.windowTitle()} {widget.text()}")

    @classmethod
    def _click_InputDialog(cls, set_int: Optional[int] = None):
        """Needs to be queued with QTimer.singleShot before triggering the message box"""
        for widget in cls.app.topLevelWidgets():
            if isinstance(widget, QInputDialog) and widget.isVisible():
                if set_int:
                    widget.setIntValue(set_int)
                QTest.qWait(SHORT_DELAY)
                widget.accept()

    def _close_welcome(self):
        self.main_window.welcome_window.view.close()

    @classmethod
    def _wait_until(cls,
                    test_func: Callable[[], bool],
                    delay=0.1,
                    max_retry=100):
        """
        Repeat test_func every delay seconds until is becomes true. Or if max_retry is reached return false.
        """
        for _ in range(max_retry):
            if test_func():
                return True
            QTest.qWait(int(delay * 1000))
        raise RuntimeError("_wait_until reach max retries")

    @classmethod
    def _wait_for_widget_visible(cls, widget_type, delay=0.1, max_retry=100):
        for _ in range(max_retry):
            for widget in cls.app.topLevelWidgets():
                if isinstance(widget, widget_type) and widget.isVisible():
                    return True
            QTest.qWait(delay * 1000)
        raise RuntimeError("_wait_for_stack_selector reach max retries")

    @mock.patch(
        "mantidimaging.gui.windows.load_dialog.view.MWLoadDialog.select_file")
    def _load_data_set(self, mocked_select_file):
        mocked_select_file.return_value = LOAD_SAMPLE
        initial_stacks = len(
            self.main_window.presenter.get_active_stack_visualisers())

        def test_func() -> bool:
            current_stacks = len(
                self.main_window.presenter.get_active_stack_visualisers())
            return (current_stacks - initial_stacks) >= 5

        self.main_window.actionLoadDataset.trigger()
        QTest.qWait(SHOW_DELAY)
        self.main_window.load_dialogue.presenter.notify(
            Notification.UPDATE_ALL_FIELDS)
        QTest.qWait(SHOW_DELAY)
        self.main_window.load_dialogue.accept()
        self._wait_until(test_func, max_retry=600)

    def _open_operations(self):
        self.main_window.actionFilters.trigger()

    def _open_reconstruction(self):
        self.main_window.actionRecon.trigger()

    def _close_stack_tabs(self):
        while self.main_window.dataset_tree_widget.topLevelItemCount():
            self.main_window.dataset_tree_widget.topLevelItem(0).setSelected(
                True)
            self.main_window._delete_container()