Esempio n. 1
0
def qapplication():
    """Either return a reference to an existing application instance
    or create a new one
    :return: A reference to the QApplication object
    """
    app = QApplication.instance()
    if app is None:
        # attributes that must be set before creating QApplication
        QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts)

        argv = sys.argv[:]
        argv[0] = APPNAME  # replace application name
        # Workaround a segfault importing readline with PyQt5
        # This is because PyQt5 messes up pystate (internal) modules_by_index
        # so PyState_FindModule will return null instead of the module address.
        # Readline (so far) is the only module that falls over during init as it blindly uses FindModules result
        # The workaround mentioned in https://groups.google.com/forum/#!topic/leo-editor/ghiIN7irzY0
        if sys.platform == "linux" or sys.platform == "linux2" or sys.platform == "darwin":
            importlib.import_module("readline")

        app = QApplication(argv)
        app.setOrganizationName(ORGANIZATION)
        app.setOrganizationDomain(ORG_DOMAIN)
        app.setApplicationName(APPNAME)
        app.setApplicationVersion(mantid_version_str())
        # Spin up the usage service and set the name for the usage reporting
        # The report is sent when the FrameworkManager kicks up
        UsageService.setApplicationName(APPNAME)

        app.setAttribute(Qt.AA_UseHighDpiPixmaps)
        if hasattr(Qt, 'AA_DisableWindowContextHelpButton'):
            app.setAttribute(Qt.AA_DisableWindowContextHelpButton)

    return app
Esempio n. 2
0
def qapplication():
    """Either return a reference to an existing application instance
    or create a new one
    :return: A reference to the QApplication object
    """
    app = QApplication.instance()
    if app is None:
        QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts)
        argv = sys.argv[:]
        argv[0] = APPNAME  # replace application name
        # Workaround a segfault with the IPython console when using Python 3.5 + PyQt 5
        # Without this using this fix the above combination causes a segfault when the IPython
        # console is started
        # The workaround mentioned in https://groups.google.com/forum/#!topic/leo-editor/ghiIN7irzY0
        # is to ensure readline is imported before the QApplication object is created
        if sys.version_info[0] == 3 and sys.version_info[1] == 5:
            importlib.import_module("readline")
        app = QApplication(argv)
        app.setOrganizationName(ORGANIZATION)
        app.setOrganizationDomain(ORG_DOMAIN)
        app.setApplicationName(APPNAME)
        app.setApplicationVersion(mantid_version_str())
        # Spin up the usage service and set the name for the usage reporting
        # The report is sent when the FrameworkManager kicks up
        UsageService.setApplicationName(APPNAME)

    return app
Esempio n. 3
0
def qapplication():
    """Either return a reference to an existing application instance
    or create a new one
    :return: A reference to the QApplication object
    """
    app = QApplication.instance()
    if app is None:
        QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts)
        argv = sys.argv[:]
        argv[0] = APPNAME  # replace application name
        # Workaround a segfault with the IPython console when using Python 3.5 + PyQt 5
        # Without this using this fix the above combination causes a segfault when the IPython
        # console is started
        # The workaround mentioned in https://groups.google.com/forum/#!topic/leo-editor/ghiIN7irzY0
        # is to ensure readline is imported before the QApplication object is created
        if sys.version_info[0] == 3 and sys.version_info[1] == 5:
            importlib.import_module("readline")
        app = QApplication(argv)
        app.setOrganizationName(ORGANIZATION)
        app.setOrganizationDomain(ORG_DOMAIN)
        app.setApplicationName(APPNAME)
        app.setApplicationVersion(mantid_version_str())
        # Spin up the usage service and set the name for the usage reporting
        # The report is sent when the FrameworkManager kicks up
        UsageService.setApplicationName(APPNAME)

        if is_required_version(required_version='5.10.0', version=qVersion()):
            app.setAttribute(Qt.AA_DisableWindowContextHelpButton)

    return app
Esempio n. 4
0
def init_qt_info():
    QCoreApplication.setOrganizationName('busimus')
    QCoreApplication.setOrganizationDomain('busz.me')
    QCoreApplication.setApplicationName('cutelog')
    version = get_distribution(QCoreApplication.applicationName()).version
    QCoreApplication.setApplicationVersion(version)
    if not QT55_COMPAT:  # this attribute was introduced in Qt 5.6
        QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
Esempio n. 5
0
def main():
    from qtpy.QtCore import Qt, QCoreApplication
    from qtpy.QtWidgets import QApplication
    from qtpy import API

    import hyperspyui.info
    from hyperspyui.settings import Settings

    QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts)
    # Need to set early to make QSettings accessible
    QCoreApplication.setApplicationName("HyperSpyUI")
    QCoreApplication.setOrganizationName("Hyperspy")
    QCoreApplication.setApplicationVersion(hyperspyui.info.__version__)

    # First, clear all default settings!
    # TODO: This will cause a concurrency issue with multiple launch
    Settings.clear_defaults()
    # Setup default for single/multi-instance
    settings = Settings(group="General")
    settings.set_default('allow_multiple_instances', False)
    if settings['allow_multiple_instances', bool]:
        # Using multiple instances, get a new application
        app = QApplication(sys.argv)
    else:
        # Make sure we only have a single instance
        from hyperspyui.singleapplication import get_app
        app = get_app('hyperspyui')

    splash = get_splash()

    log_file = _get_logfile()
    if log_file:
        sys.stdout = sys.stderr = log_file
    else:
        @contextmanager
        def dummy_context_manager(*args, **kwargs):
            yield
        log_file = dummy_context_manager()

    with log_file:
        # Need to have import here, since QApplication needs to be called first
        from hyperspyui.mainwindow import MainWindow

        form = MainWindow(splash=splash)
        if not settings['allow_multiple_instances', bool]:
            if "pyqt" in API:
                app.messageAvailable.connect(form.handleSecondInstance)
            elif API == 'pyside':
                app.messageReceived.connect(form.handleSecondInstance)
        form.showMaximized()

        form.splash.hide()
        form.load_complete.emit()
        # Ensure logging is OK
        import hyperspy.api as hs
        hs.set_log_level(LOGLEVEL)

        app.exec_()
Esempio n. 6
0
def use_software_rendering():
    """
    Instruct Qt to use software rendering.

    This is necessary for some buggy graphics drivers (e.g. nvidia).
    This function should be run before the QApplication is created.
    """
    QCoreApplication.setAttribute(Qt.AA_UseSoftwareOpenGL)
    QQuickWindow.setSceneGraphBackend(QSGRendererInterface.Software)
Esempio n. 7
0
def qapplication():
    """Either return a reference to an existing application instance
    or create a new one
    :return: A reference to the QApplication object
    """
    app = QApplication.instance()
    if app is None:
        QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts)
        app = QApplication(['Mantid Workbench'])
    return app
Esempio n. 8
0
    def __init__(self, viewer):
        super().__init__()

        QCoreApplication.setAttribute(
            Qt.AA_UseStyleSheetPropagationInWidgetStyles, True)
        self.setStyleSheet(self.themed_stylesheet)

        self.viewer = viewer
        self.viewer._qtviewer = self

        self.canvas = SceneCanvas(keys=None, vsync=True)
        self.canvas.native.setMinimumSize(QSize(100, 100))

        self.canvas.connect(self.on_mouse_move)
        self.canvas.connect(self.on_mouse_press)
        self.canvas.connect(self.on_mouse_release)
        self.canvas.connect(self.on_key_press)
        self.canvas.connect(self.on_key_release)

        self.view = self.canvas.central_widget.add_view()
        # Set 2D camera (the camera will scale to the contents in the scene)
        self.view.camera = PanZoomCamera(aspect=1)
        # flip y-axis to have correct aligment
        self.view.camera.flip = (0, 1, 0)
        self.view.camera.set_range()

        self.view.camera.viewbox_key_event = viewbox_key_event

        center = QWidget()
        layout = QVBoxLayout()
        layout.setContentsMargins(15, 20, 15, 10)
        layout.addWidget(self.canvas.native)
        dimsview = QtDims(self.viewer.dims)
        layout.addWidget(dimsview)
        center.setLayout(layout)

        # Add controls, center, and layerlist
        self.control_panel = QtControls(viewer)
        self.addWidget(self.control_panel)
        self.addWidget(center)
        self.addWidget(self.viewer.layers._qt)

        self._cursors = {
            'disabled':
            QCursor(
                QPixmap(':/icons/cursor/cursor_disabled.png').scaled(20, 20)),
            'cross':
            Qt.CrossCursor,
            'forbidden':
            Qt.ForbiddenCursor,
            'pointing':
            Qt.PointingHandCursor,
            'standard':
            QCursor()
        }
Esempio n. 9
0
def setup_renderer():
    """
    This utility function reverts the renderer to Software rendering if it is
    running in a SSH session.
    """
    if is_ssh_session():
        logger.info('Using PyDM via SSH. Reverting to Software Rendering.')
        from qtpy.QtCore import QCoreApplication, Qt
        from qtpy.QtQuick import QQuickWindow, QSGRendererInterface

        QCoreApplication.setAttribute(Qt.AA_UseSoftwareOpenGL)
        QQuickWindow.setSceneGraphBackend(QSGRendererInterface.Software)
Esempio n. 10
0
def main():
    import sys
    from qtpy.QtWidgets import QApplication
    from qtpy.QtCore import QCoreApplication
    from util.ConfigUtil import ConfigUtil
    from util.LanguageUtil import LanguageUtil

    ConfigUtil.setup()
    config.noQt = False
    config.thisTranslation = LanguageUtil.loadTranslation("en_US")
    QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts)
    app = QApplication(sys.argv)
    dialog = DownloadBibleMp3Dialog(DummyParent())
    dialog.exec_()
Esempio n. 11
0
def qapplication():
    """Either return a reference to an existing application instance
    or create a new one
    :return: A reference to the QApplication object
    """
    app = QApplication.instance()
    if app is None:
        QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts)
        argv = sys.argv[:]
        argv[0] = APPNAME  # replace application name
        app = QApplication(argv)
        app.setOrganizationName(ORGANIZATION)
        app.setOrganizationDomain(ORG_DOMAIN)
        app.setApplicationName(APPNAME)
        # not calling app.setApplicationVersion(mantid.kernel.version_str())
        # because it needs to happen after logging is monkey-patched in
    return app
Esempio n. 12
0
def set_opengl_implementation(option):
    """
    Set the OpenGL implementation used by Spyder.

    See spyder-ide/spyder#7447 for the details.
    """
    if option == 'software':
        QCoreApplication.setAttribute(Qt.AA_UseSoftwareOpenGL)
        if QQuickWindow is not None:
            QQuickWindow.setSceneGraphBackend(QSGRendererInterface.Software)
    elif option == 'desktop':
        QCoreApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
        if QQuickWindow is not None:
            QQuickWindow.setSceneGraphBackend(QSGRendererInterface.OpenGL)
    elif option == 'gles':
        QCoreApplication.setAttribute(Qt.AA_UseOpenGLES)
        if QQuickWindow is not None:
            QQuickWindow.setSceneGraphBackend(QSGRendererInterface.OpenGL)
Esempio n. 13
0
from anaconda_navigator.static import images
from anaconda_navigator.static.fonts import load_fonts
from anaconda_navigator.utils import misc
from anaconda_navigator.utils.logs import clean_logs, setup_logger
from anaconda_navigator.utils.qthelpers import qapplication
from anaconda_navigator.widgets.dialogs import MessageBoxInformation
from anaconda_navigator.widgets.dialogs.splash import SplashScreen
from anaconda_navigator.widgets.main_window import MainWindow


# yapf: enable

# For retina displays on qt5
if CONF.get('main', 'enable_high_dpi_scaling'):
    if hasattr(Qt, 'AA_UseHighDpiPixmaps'):
        QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)

    if hasattr(Qt, 'AA_EnableHighDpiScaling'):
        QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)


def except_hook(cls, exception, traceback):
    """Custom except hook to avoid crashes on PyQt5."""
    sys.__excepthook__(cls, exception, traceback)


def set_application_icon():
    """Set application icon."""
    global app
    if LINUX and UBUNTU:
        app_icon = QIcon(images.ANACONDA_LOGO_WHITE)
Esempio n. 14
0
# Requirements
# -----------------------------------------------------------------------------
from workbench import requirements  # noqa
requirements.check_qt()

# -----------------------------------------------------------------------------
# Qt
# -----------------------------------------------------------------------------
from qtpy.QtCore import QCoreApplication, Qt  # noqa
from qtpy.QtWidgets import QApplication, QMainWindow  # noqa
from mantidqt.utils.qt import load_ui, plugins  # noqa

# Pre-application startup
plugins.setup_library_paths()
if hasattr(Qt, 'AA_EnableHighDpiScaling'):
    QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)

# -----------------------------------------------------------------------------
# Create the application instance early, set the application name for window
# titles and hold on to a reference to it. Required to be performed early so
# that the splash screen can be displayed
# -----------------------------------------------------------------------------


def qapplication():
    """Either return a reference to an existing application instance
    or create a new one
    :return: A reference to the QApplication object
    """
    app = QApplication.instance()
    if app is None:
Esempio n. 15
0
    def __init__(self, viewer):
        super().__init__()
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.pool = QThreadPool()

        QCoreApplication.setAttribute(
            Qt.AA_UseStyleSheetPropagationInWidgetStyles, True)

        self.viewer = viewer
        self.dims = QtDims(self.viewer.dims)
        self.controls = QtControls(self.viewer)
        self.layers = QtLayerList(self.viewer.layers)
        self.layerButtons = QtLayerButtons(self.viewer)
        self.viewerButtons = QtViewerButtons(self.viewer)
        self.console = QtConsole({'viewer': self.viewer})

        layerList = QWidget()
        layerList.setObjectName('layerList')
        layerListLayout = QVBoxLayout()
        layerListLayout.addWidget(self.layerButtons)
        layerListLayout.addWidget(self.layers)
        layerListLayout.addWidget(self.viewerButtons)
        layerListLayout.setContentsMargins(8, 4, 8, 6)
        layerList.setLayout(layerListLayout)
        self.dockLayerList = QtViewerDockWidget(
            self,
            layerList,
            name='layer list',
            area='left',
            allowed_areas=['left', 'right'],
        )
        self.dockLayerControls = QtViewerDockWidget(
            self,
            self.controls,
            name='layer controls',
            area='left',
            allowed_areas=['left', 'right'],
        )
        self.dockConsole = QtViewerDockWidget(
            self,
            self.console,
            name='console',
            area='bottom',
            allowed_areas=['top', 'bottom'],
            shortcut='Ctrl+Shift+C',
        )
        self.dockConsole.setVisible(False)
        self.dockLayerControls.visibilityChanged.connect(self._constrain_width)
        self.dockLayerList.setMaximumWidth(258)
        self.dockLayerList.setMinimumWidth(258)

        # This dictionary holds the corresponding vispy visual for each layer
        self.layer_to_visual = {}

        if self.console.shell is not None:
            self.viewerButtons.consoleButton.clicked.connect(
                lambda: self.toggle_console())
        else:
            self.viewerButtons.consoleButton.setEnabled(False)

        self.canvas = SceneCanvas(keys=None, vsync=True, parent=self)
        self.canvas.events.ignore_callback_errors = False
        self.canvas.events.draw.connect(self.dims.enable_play)
        self.canvas.native.setMinimumSize(QSize(200, 200))
        self.canvas.context.set_depth_func('lequal')

        self.canvas.connect(self.on_mouse_move)
        self.canvas.connect(self.on_mouse_press)
        self.canvas.connect(self.on_mouse_release)
        self.canvas.connect(self.on_key_press)
        self.canvas.connect(self.on_key_release)
        self.canvas.connect(self.on_draw)

        self.view = self.canvas.central_widget.add_view()
        self._update_camera()

        main_widget = QWidget()
        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(10, 22, 10, 2)
        main_layout.addWidget(self.canvas.native)
        main_layout.addWidget(self.dims)
        main_layout.setSpacing(10)
        main_widget.setLayout(main_layout)

        self.setOrientation(Qt.Vertical)
        self.addWidget(main_widget)

        self._last_visited_dir = str(Path.home())

        self._cursors = {
            'disabled':
            QCursor(
                QPixmap(':/icons/cursor/cursor_disabled.png').scaled(20, 20)),
            'cross':
            Qt.CrossCursor,
            'forbidden':
            Qt.ForbiddenCursor,
            'pointing':
            Qt.PointingHandCursor,
            'standard':
            QCursor(),
        }

        self._update_palette(viewer.palette)

        self._key_release_generators = {}

        self.viewer.events.interactive.connect(self._on_interactive)
        self.viewer.events.cursor.connect(self._on_cursor)
        self.viewer.events.reset_view.connect(self._on_reset_view)
        self.viewer.events.palette.connect(
            lambda event: self._update_palette(event.palette))
        self.viewer.layers.events.reordered.connect(self._reorder_layers)
        self.viewer.layers.events.added.connect(self._add_layer)
        self.viewer.layers.events.removed.connect(self._remove_layer)
        self.viewer.dims.events.camera.connect(
            lambda event: self._update_camera())
        # stop any animations whenever the layers change
        self.viewer.events.layers_change.connect(lambda x: self.dims.stop())

        self.setAcceptDrops(True)
Esempio n. 16
0
        self.resetItems()


## Standalone development code


class DummyParent():
    def runTextCommand(self, command):
        print(command)


if __name__ == '__main__':
    import sys
    from qtpy.QtWidgets import QApplication
    from qtpy.QtCore import QCoreApplication
    from util.ConfigUtil import ConfigUtil
    from util.LanguageUtil import LanguageUtil

    ConfigUtil.setup()
    config.noQt = False
    config.bibleCollections["Custom"] = ['ABP', 'ACV']
    config.bibleCollections["King James"] = [
        'KJV', 'KJVx', 'KJVA', 'KJV1611', 'KJV1769x'
    ]
    config.thisTranslation = LanguageUtil.loadTranslation("en_US")
    QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts)

    app = QApplication(sys.argv)
    dialog = LibraryCatalogDialog(DummyParent())
    dialog.saveRemoteCatalogToCache()
    dialog.exec_()
Esempio n. 17
0
def main():
    from qtpy.QtCore import Qt, QCoreApplication
    from qtpy.QtWidgets import QApplication
    from qtpy import API

    import hyperspyui.info
    from hyperspyui.settings import Settings

    # QtWebEngineWidgets must be imported before a QCoreApplication instance
    # is created (used in eelsdb plugin)
    # Avoid a bug in Qt: https://bugreports.qt.io/browse/QTBUG-46720
    from qtpy import QtWebEngineWidgets

    # Need to set early to make QSettings accessible
    QCoreApplication.setApplicationName("HyperSpyUI")
    QCoreApplication.setOrganizationName("Hyperspy")
    QCoreApplication.setApplicationVersion(hyperspyui.info.__version__)
    # To avoid the warning:
    # Qt WebEngine seems to be initialized from a plugin. Please set
    # Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute before
    # constructing QGuiApplication.
    # Only available for pyqt>=5.4
    if hasattr(Qt, "AA_ShareOpenGLContexts"):
        QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts)

    # First, clear all default settings!
    # TODO: This will cause a concurrency issue with multiple launch
    Settings.clear_defaults()
    # Setup default for single/multi-instance
    settings = Settings(group="General")
    settings.set_default('allow_multiple_instances', False)
    if settings['allow_multiple_instances', bool]:
        # Using multiple instances, get a new application
        app = QApplication(sys.argv)
    else:
        # Make sure we only have a single instance
        from hyperspyui.singleapplication import get_app
        app = get_app('hyperspyui')

    splash = get_splash()

    log_file = _get_logfile()
    if log_file:
        sys.stdout = sys.stderr = log_file
    else:

        @contextmanager
        def dummy_context_manager(*args, **kwargs):
            yield

        log_file = dummy_context_manager()

    with log_file:
        # Need to have import here, since QApplication needs to be called first
        from hyperspyui.mainwindow import MainWindow

        form = MainWindow(splash=splash)
        if not settings['allow_multiple_instances', bool]:
            if "pyqt" in API:
                app.messageAvailable.connect(form.handleSecondInstance)
            elif API == 'pyside':
                app.messageReceived.connect(form.handleSecondInstance)
        form.showMaximized()

        form.splash.hide()
        form.load_complete.emit()
        # Ensure logging is OK
        import hyperspy.api as hs
        hs.set_log_level(LOGLEVEL)

        app.exec_()
Esempio n. 18
0
    def __init__(self, viewer):
        super().__init__()

        self.pool = QThreadPool()

        QCoreApplication.setAttribute(
            Qt.AA_UseStyleSheetPropagationInWidgetStyles, True)

        self.viewer = viewer
        self.dims = QtDims(self.viewer.dims)
        self.controls = QtControls(self.viewer)
        self.layers = QtLayerList(self.viewer.layers)
        self.layerButtons = QtLayerButtons(self.viewer)
        self.viewerButtons = QtViewerButtons(self.viewer)
        self.console = QtConsole({'viewer': self.viewer})

        # This dictionary holds the corresponding vispy visual for each layer
        self.layer_to_visual = {}

        if self.console.shell is not None:
            self.console.style().unpolish(self.console)
            self.console.style().polish(self.console)
            self.console.hide()
            self.viewerButtons.consoleButton.clicked.connect(
                lambda: self._toggle_console())
        else:
            self.viewerButtons.consoleButton.setEnabled(False)

        self.canvas = SceneCanvas(keys=None, vsync=True)
        self.canvas.events.ignore_callback_errors = False
        self.canvas.events.draw.connect(self.dims.enable_play)
        self.canvas.native.setMinimumSize(QSize(200, 200))
        self.canvas.context.set_depth_func('lequal')

        self.canvas.connect(self.on_mouse_move)
        self.canvas.connect(self.on_mouse_press)
        self.canvas.connect(self.on_mouse_release)
        self.canvas.connect(self.on_key_press)
        self.canvas.connect(self.on_key_release)
        self.canvas.connect(self.on_draw)

        self.view = self.canvas.central_widget.add_view()
        self._update_camera()

        main_widget = QWidget()
        main_layout = QGridLayout()
        main_layout.setContentsMargins(15, 20, 15, 10)
        main_layout.addWidget(self.canvas.native, 0, 1, 3, 1)
        main_layout.addWidget(self.dims, 3, 1)
        main_layout.addWidget(self.controls, 0, 0)
        main_layout.addWidget(self.layerButtons, 1, 0)
        main_layout.addWidget(self.layers, 2, 0)
        main_layout.addWidget(self.viewerButtons, 3, 0)
        main_layout.setColumnStretch(1, 1)
        main_layout.setSpacing(10)
        main_widget.setLayout(main_layout)

        self.setOrientation(Qt.Vertical)
        self.addWidget(main_widget)
        if self.console.shell is not None:
            self.addWidget(self.console)

        self._last_visited_dir = str(Path.home())

        self._cursors = {
            'disabled':
            QCursor(
                QPixmap(':/icons/cursor/cursor_disabled.png').scaled(20, 20)),
            'cross':
            Qt.CrossCursor,
            'forbidden':
            Qt.ForbiddenCursor,
            'pointing':
            Qt.PointingHandCursor,
            'standard':
            QCursor(),
        }

        self._update_palette(viewer.palette)

        self._key_release_generators = {}

        self.viewer.events.interactive.connect(self._on_interactive)
        self.viewer.events.cursor.connect(self._on_cursor)
        self.viewer.events.reset_view.connect(self._on_reset_view)
        self.viewer.events.palette.connect(
            lambda event: self._update_palette(event.palette))
        self.viewer.layers.events.reordered.connect(self._reorder_layers)
        self.viewer.layers.events.added.connect(self._add_layer)
        self.viewer.layers.events.removed.connect(self._remove_layer)
        self.viewer.dims.events.camera.connect(
            lambda event: self._update_camera())
        # stop any animations whenever the layers change
        self.viewer.events.layers_change.connect(lambda x: self.dims.stop())

        self.setAcceptDrops(True)
Esempio n. 19
0
    def __init__(self, viewer):
        super().__init__()

        QCoreApplication.setAttribute(
            Qt.AA_UseStyleSheetPropagationInWidgetStyles, True
        )

        self.viewer = viewer
        self.dims = QtDims(self.viewer.dims)
        self.controls = QtControls(self.viewer)
        self.layers = QtLayerList(self.viewer.layers)
        self.buttons = QtLayersButtons(self.viewer)
        self.console = QtConsole({'viewer': self.viewer})

        if self.console.shell is not None:
            self.console.style().unpolish(self.console)
            self.console.style().polish(self.console)
            self.console.hide()
            self.buttons.consoleButton.clicked.connect(
                lambda: self._toggle_console()
            )
        else:
            self.buttons.consoleButton.setEnabled(False)

        self.canvas = SceneCanvas(keys=None, vsync=True)
        self.canvas.native.setMinimumSize(QSize(200, 200))

        self.canvas.connect(self.on_mouse_move)
        self.canvas.connect(self.on_mouse_press)
        self.canvas.connect(self.on_mouse_release)
        self.canvas.connect(self.on_key_press)
        self.canvas.connect(self.on_key_release)
        self.canvas.connect(self.on_draw)

        self.view = self.canvas.central_widget.add_view()
        self._update_camera()

        center = QWidget()
        center_layout = QVBoxLayout()
        center_layout.setContentsMargins(15, 20, 15, 10)
        center_layout.addWidget(self.canvas.native)
        center_layout.addWidget(self.dims)
        center.setLayout(center_layout)

        right = QWidget()
        right_layout = QVBoxLayout()
        right_layout.addWidget(self.layers)
        right_layout.addWidget(self.buttons)
        right.setLayout(right_layout)
        right.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)

        left = self.controls

        top = QWidget()
        top_layout = QHBoxLayout()
        top_layout.addWidget(left)
        top_layout.addWidget(center)
        top_layout.addWidget(right)
        top.setLayout(top_layout)

        self.setOrientation(Qt.Vertical)
        self.addWidget(top)

        if self.console.shell is not None:
            self.addWidget(self.console)

        self._last_visited_dir = str(Path.home())

        self._cursors = {
            'disabled': QCursor(
                QPixmap(':/icons/cursor/cursor_disabled.png').scaled(20, 20)
            ),
            'cross': Qt.CrossCursor,
            'forbidden': Qt.ForbiddenCursor,
            'pointing': Qt.PointingHandCursor,
            'standard': QCursor(),
        }

        self._update_palette(viewer.palette)

        self._key_release_generators = {}

        self.viewer.events.interactive.connect(self._on_interactive)
        self.viewer.events.cursor.connect(self._on_cursor)
        self.viewer.events.reset_view.connect(self._on_reset_view)
        self.viewer.events.palette.connect(
            lambda event: self._update_palette(event.palette)
        )
        self.viewer.layers.events.reordered.connect(self._update_canvas)
        self.viewer.dims.events.display.connect(
            lambda event: self._update_camera()
        )

        self.setAcceptDrops(True)
Esempio n. 20
0
    def save_perspective(self):
        perspective_name = QInputDialog.getText(self, 'Save perspective', 'Enter unique name:')
        if perspective_name:
            self.dock_manager.add_perspective(perspective_name)
            _ = QSignalBlocker(self.perspective_combo_box)
            self.perspective_combo_box.clear()
            self.perspective_combo_box.addItems(self.dock_manager.perspective_names())
            self.perspective_combo_box.setCurrentIndex(perspective_name)
            self.save_perspectives()


def main(app_):
    main_window = MainWindow()
    main_window.show()
    state = main_window.dock_manager.save_state()
    print('This is what the saved state looks like in XML:')
    print(str(state, 'utf-8'))
    print()
    main_window.dock_manager.restore_state(state)
    return main_window


if __name__ == '__main__':
    logging.basicConfig(level='DEBUG')
    QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
    QGuiApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    app = QtWidgets.QApplication([])
    window = main(app)
    window.show()
    app.exec_()
Esempio n. 21
0
    def __init__(self, viewer):
        super().__init__()

        QCoreApplication.setAttribute(
            Qt.AA_UseStyleSheetPropagationInWidgetStyles, True
        )

        self.viewer = viewer

        self.canvas = SceneCanvas(keys=None, vsync=True)
        self.canvas.native.setMinimumSize(QSize(100, 100))

        self.canvas.connect(self.on_mouse_move)
        self.canvas.connect(self.on_mouse_press)
        self.canvas.connect(self.on_mouse_release)
        self.canvas.connect(self.on_key_press)
        self.canvas.connect(self.on_key_release)
        self.canvas.connect(self.on_draw)

        self.view = self.canvas.central_widget.add_view()

        # Set 2D camera (the camera will scale to the contents in the scene)
        self.view.camera = PanZoomCamera(aspect=1)
        # flip y-axis to have correct aligment
        self.view.camera.flip = (0, 1, 0)
        self.view.camera.set_range()
        self.view.camera.viewbox_key_event = viewbox_key_event

        # TO DO: Remove
        self.viewer._view = self.view

        center = QWidget()
        center_layout = QVBoxLayout()
        center_layout.setContentsMargins(15, 20, 15, 10)
        center_layout.addWidget(self.canvas.native)
        self.dims = QtDims(self.viewer.dims)
        center_layout.addWidget(self.dims)
        center.setLayout(center_layout)

        # Add controls, center, and layerlist
        self.control_panel = QtControls(viewer)
        self.addWidget(self.control_panel)
        self.addWidget(center)

        right = QWidget()
        right_layout = QVBoxLayout()
        self.layers = QtLayerList(self.viewer.layers)
        right_layout.addWidget(self.layers)
        self.buttons = QtLayersButtons(viewer)
        right_layout.addWidget(self.buttons)
        right.setLayout(right_layout)
        right.setMinimumSize(QSize(308, 250))

        self.addWidget(right)

        self._last_visited_dir = str(Path.home())

        self._cursors = {
            'disabled': QCursor(
                QPixmap(':/icons/cursor/cursor_disabled.png').scaled(20, 20)
            ),
            'cross': Qt.CrossCursor,
            'forbidden': Qt.ForbiddenCursor,
            'pointing': Qt.PointingHandCursor,
            'standard': QCursor(),
        }

        self._update_palette(viewer.palette)

        self._key_release_generators = {}

        self.viewer.events.interactive.connect(self._on_interactive)
        self.viewer.events.cursor.connect(self._on_cursor)
        self.viewer.events.reset_view.connect(self._on_reset_view)
        self.viewer.events.palette.connect(
            lambda event: self._update_palette(event.palette)
        )
        self.viewer.layers.events.reordered.connect(self._update_canvas)

        self.setAcceptDrops(True)
Esempio n. 22
0
    def __init__(self, viewer):
        from .layer_controls import QtLayerControlsContainer

        super().__init__()
        self.setAttribute(Qt.WA_DeleteOnClose)

        QCoreApplication.setAttribute(
            Qt.AA_UseStyleSheetPropagationInWidgetStyles, True)

        self.viewer = viewer
        self.dims = QtDims(self.viewer.dims)
        self.controls = QtLayerControlsContainer(self.viewer)
        self.layers = QtLayerList(self.viewer.layers)
        self.layerButtons = QtLayerButtons(self.viewer)
        self.viewerButtons = QtViewerButtons(self.viewer)
        self._console = None

        layerList = QWidget()
        layerList.setObjectName('layerList')
        layerListLayout = QVBoxLayout()
        layerListLayout.addWidget(self.layerButtons)
        layerListLayout.addWidget(self.layers)
        layerListLayout.addWidget(self.viewerButtons)
        layerListLayout.setContentsMargins(8, 4, 8, 6)
        layerList.setLayout(layerListLayout)
        self.dockLayerList = QtViewerDockWidget(
            self,
            layerList,
            name='layer list',
            area='left',
            allowed_areas=['left', 'right'],
        )
        self.dockLayerControls = QtViewerDockWidget(
            self,
            self.controls,
            name='layer controls',
            area='left',
            allowed_areas=['left', 'right'],
        )
        self.dockConsole = QtViewerDockWidget(
            self,
            QWidget(),
            name='console',
            area='bottom',
            allowed_areas=['top', 'bottom'],
            shortcut='Ctrl+Shift+C',
        )
        self.dockConsole.setVisible(False)
        # because the console is loaded lazily in the @getter, this line just
        # gets (or creates) the console when the dock console is made visible.
        self.dockConsole.visibilityChanged.connect(lambda visible: self.console
                                                   if visible else None)
        self.dockLayerControls.visibilityChanged.connect(self._constrain_width)
        self.dockLayerList.setMaximumWidth(258)
        self.dockLayerList.setMinimumWidth(258)

        self.dockPerformance = self._create_performance_dock_widget()

        # This dictionary holds the corresponding vispy visual for each layer
        self.layer_to_visual = {}
        self.viewerButtons.consoleButton.clicked.connect(
            self.toggle_console_visibility)

        self.canvas = KeyModifierFilterSceneCanvas(keys=None,
                                                   vsync=True,
                                                   parent=self)
        self.canvas.events.ignore_callback_errors = False
        self.canvas.events.draw.connect(self.dims.enable_play)
        self.canvas.native.setMinimumSize(QSize(200, 200))
        self.canvas.context.set_depth_func('lequal')

        self.canvas.connect(self.on_mouse_move)
        self.canvas.connect(self.on_mouse_press)
        self.canvas.connect(self.on_mouse_release)
        self.canvas.connect(self.on_key_press)
        self.canvas.connect(self.on_key_release)
        self.canvas.connect(self.on_mouse_wheel)

        self.view = self.canvas.central_widget.add_view()
        self._update_camera()

        main_widget = QWidget()
        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(10, 22, 10, 2)
        main_layout.addWidget(self.canvas.native)
        main_layout.addWidget(self.dims)
        main_layout.setSpacing(10)
        main_widget.setLayout(main_layout)

        self.setOrientation(Qt.Vertical)
        self.addWidget(main_widget)

        self._last_visited_dir = str(Path.home())

        self._cursors = {
            'cross': Qt.CrossCursor,
            'forbidden': Qt.ForbiddenCursor,
            'pointing': Qt.PointingHandCursor,
            'standard': QCursor(),
        }

        self._update_palette()

        self.viewer.events.interactive.connect(self._on_interactive)
        self.viewer.events.cursor.connect(self._on_cursor)
        self.viewer.events.reset_view.connect(self._on_reset_view)
        self.viewer.events.palette.connect(self._update_palette)
        self.viewer.layers.events.reordered.connect(self._reorder_layers)
        self.viewer.layers.events.added.connect(self._add_layer)
        self.viewer.layers.events.removed.connect(self._remove_layer)
        self.viewer.dims.events.camera.connect(
            lambda event: self._update_camera())
        # stop any animations whenever the layers change
        self.viewer.events.layers_change.connect(lambda x: self.dims.stop())

        self.setAcceptDrops(True)
Esempio n. 23
0
    def setup(self):
        # menus must be done first so they can be filled by the
        # plugins in register_plugin
        self.create_menus()

        # widgets
        # Log message display must be imported first
        self.set_splash("Loading message display")
        from workbench.plugins.logmessagedisplay import LogMessageDisplay
        self.messagedisplay = LogMessageDisplay(self)
        # this takes over stdout/stderr
        self.messagedisplay.register_plugin()
        # read settings early so that logging level is in place before framework mgr created
        self.messagedisplay.readSettings(CONF)
        self.widgets.append(self.messagedisplay)

        self.set_splash("Loading Algorithm Selector")
        from workbench.plugins.algorithmselectorwidget import AlgorithmSelector
        self.algorithm_selector = AlgorithmSelector(self)
        self.algorithm_selector.register_plugin()
        self.widgets.append(self.algorithm_selector)

        self.set_splash("Loading Plot Selector")
        from workbench.plugins.plotselectorwidget import PlotSelector
        self.plot_selector = PlotSelector(self)
        self.plot_selector.register_plugin()
        self.widgets.append(self.plot_selector)

        self.set_splash("Loading code editing widget")
        from workbench.plugins.editor import MultiFileEditor
        self.editor = MultiFileEditor(self)
        self.messagedisplay.display.setActiveScript(
            self.editor.editors.current_tab_filename)
        self.editor.register_plugin()
        self.widgets.append(self.editor)
        self.editor.editors.sig_code_exec_start.connect(
            self.messagedisplay.script_executing)
        self.editor.editors.sig_file_name_changed.connect(
            self.messagedisplay.file_name_modified)
        self.editor.editors.sig_current_tab_changed.connect(
            self.messagedisplay.current_tab_changed)

        self.set_splash("Loading IPython console")
        from workbench.plugins.jupyterconsole import JupyterConsole
        self.ipythonconsole = JupyterConsole(self)
        self.ipythonconsole.register_plugin()
        self.widgets.append(self.ipythonconsole)

        from workbench.plugins.workspacewidget import WorkspaceWidget
        self.workspacewidget = WorkspaceWidget(self)
        self.workspacewidget.register_plugin()
        prompt = CONF.get('project/prompt_on_deleting_workspace')
        self.workspacewidget.workspacewidget.enableDeletePrompt(bool(prompt))
        self.widgets.append(self.workspacewidget)

        self.set_splash("Loading memory widget")
        from workbench.plugins.memorywidget import MemoryWidget
        self.memorywidget = MemoryWidget(self)
        self.memorywidget.register_plugin()
        self.widgets.append(self.memorywidget)

        # set the link between the algorithm and workspace widget
        self.algorithm_selector.algorithm_selector.set_get_selected_workspace_fn(
            self.workspacewidget.workspacewidget.getSelectedWorkspaceNames)

        from workbench.plugins.workspacecalculatorwidget import WorkspaceCalculatorWidget
        self.workspacecalculator = WorkspaceCalculatorWidget(self)
        self.workspacecalculator.register_plugin()
        self.widgets.append(self.workspacecalculator)

        # Set up the project, recovery and interface manager objects
        self.project = Project(GlobalFigureManager,
                               find_all_windows_that_are_savable)
        self.project_recovery = ProjectRecovery(
            globalfiguremanager=GlobalFigureManager,
            multifileinterpreter=self.editor.editors,
            main_window=self)

        self.interface_executor = PythonCodeExecution()
        self.interface_executor.sig_exec_error.connect(
            lambda errobj: logger.warning(str(errobj)))
        self.interface_manager = InterfaceManager()

        # uses default configuration as necessary
        self.setup_default_layouts()
        self.create_actions()
        self.readSettings(CONF)
        self.config_updated()

        self.override_python_input()

        # Ensure windows created after the main window have their own menu bars (on mac)
        QCoreApplication.setAttribute(Qt.AA_DontUseNativeMenuBar, True)
Esempio n. 24
0
def create_window(WindowClass, app, splash, options, args):
    """
    Create and show Spyder's main window and start QApplication event loop.

    Parameters
    ----------
    WindowClass: QMainWindow
        Subclass to instantiate the Window.
    app: QApplication
        Instance to start the application.
    splash: QSplashScreen
        Splash screen instamce.
    options: argparse.Namespace
        Command line options passed to Spyder
    args: list
        List of file names passed to the Spyder executable in the
        command line.
    """
    # Main window
    main = WindowClass(splash, options)
    try:
        main.setup()
    except BaseException:
        if main.console is not None:
            try:
                main.console.exit_interpreter()
            except BaseException:
                pass
        raise

    main.pre_visible_setup()
    main.show()
    main.post_visible_setup()

    if main.console:
        namespace = CONF.get('internal_console', 'namespace', {})
        main.console.start_interpreter(namespace)
        main.console.set_namespace_item('spy', Spy(app=app, window=main))

    # Propagate current configurations to all configuration observers
    CONF.notify_all_observers()

    # Don't show icons in menus for Mac
    if sys.platform == 'darwin':
        QCoreApplication.setAttribute(Qt.AA_DontShowIconsInMenus, True)

    # Open external files with our Mac app
    if running_in_mac_app():
        app.sig_open_external_file.connect(main.open_external_file)
        app._has_started = True
        if hasattr(app, '_pending_file_open'):
            if args:
                args = app._pending_file_open + args
            else:
                args = app._pending_file_open

    # Open external files passed as args
    if args:
        for a in args:
            main.open_external_file(a)

    # To give focus again to the last focused widget after restoring
    # the window
    app.focusChanged.connect(main.change_last_focused_widget)

    if not running_under_pytest():
        app.exec_()
    return main
Esempio n. 25
0
    def __init__(self, viewer, welcome=False):

        # Avoid circular import.
        from .layer_controls import QtLayerControlsContainer

        super().__init__()
        self.setAttribute(Qt.WA_DeleteOnClose)

        QCoreApplication.setAttribute(
            Qt.AA_UseStyleSheetPropagationInWidgetStyles, True
        )

        self.viewer = viewer
        self.dims = QtDims(self.viewer.dims)
        self.controls = QtLayerControlsContainer(self.viewer)
        self.layers = QtLayerList(self.viewer.layers)
        self.layerButtons = QtLayerButtons(self.viewer)
        self.viewerButtons = QtViewerButtons(self.viewer)
        self._key_map_handler = KeymapHandler()
        self._key_map_handler.keymap_providers = [self.viewer]
        self._active_layer = None
        self._console = None

        layerList = QWidget()
        layerList.setObjectName('layerList')
        layerListLayout = QVBoxLayout()
        layerListLayout.addWidget(self.layerButtons)
        layerListLayout.addWidget(self.layers)
        layerListLayout.addWidget(self.viewerButtons)
        layerListLayout.setContentsMargins(8, 4, 8, 6)
        layerList.setLayout(layerListLayout)
        self.dockLayerList = QtViewerDockWidget(
            self,
            layerList,
            name='layer list',
            area='left',
            allowed_areas=['left', 'right'],
        )
        self.dockLayerControls = QtViewerDockWidget(
            self,
            self.controls,
            name='layer controls',
            area='left',
            allowed_areas=['left', 'right'],
        )
        self.dockConsole = QtViewerDockWidget(
            self,
            QWidget(),
            name='console',
            area='bottom',
            allowed_areas=['top', 'bottom'],
            shortcut='Ctrl+Shift+C',
        )
        self.dockConsole.setVisible(False)
        # because the console is loaded lazily in the @getter, this line just
        # gets (or creates) the console when the dock console is made visible.
        self.dockConsole.visibilityChanged.connect(
            lambda visible: self.console if visible else None
        )
        self.dockLayerControls.visibilityChanged.connect(self._constrain_width)
        self.dockLayerList.setMaximumWidth(258)
        self.dockLayerList.setMinimumWidth(258)

        # Only created if using perfmon.
        self.dockPerformance = self._create_performance_dock_widget()

        # This dictionary holds the corresponding vispy visual for each layer
        self.layer_to_visual = {}
        self.viewerButtons.consoleButton.clicked.connect(
            self.toggle_console_visibility
        )

        self._create_canvas()

        main_widget = QWidget()
        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(10, 22, 10, 2)
        main_layout.addWidget(self.canvas.native)
        main_layout.addWidget(self.dims)
        main_layout.setSpacing(10)
        main_widget.setLayout(main_layout)

        self.setOrientation(Qt.Vertical)
        self.addWidget(main_widget)

        self._last_visited_dir = str(Path.home())

        self._cursors = {
            'cross': Qt.CrossCursor,
            'forbidden': Qt.ForbiddenCursor,
            'pointing': Qt.PointingHandCursor,
            'standard': QCursor(),
        }

        self._update_theme()
        self._on_active_layer_change()

        self.viewer.events.active_layer.connect(self._on_active_layer_change)
        self.viewer.events.theme.connect(self._update_theme)
        self.viewer.camera.events.interactive.connect(self._on_interactive)
        self.viewer.cursor.events.style.connect(self._on_cursor)
        self.viewer.cursor.events.size.connect(self._on_cursor)
        self.viewer.layers.events.reordered.connect(self._reorder_layers)
        self.viewer.layers.events.inserted.connect(self._on_add_layer_change)
        self.viewer.layers.events.removed.connect(self._remove_layer)

        # stop any animations whenever the layers change
        self.viewer.events.layers_change.connect(lambda x: self.dims.stop())

        self.setAcceptDrops(True)

        for layer in self.viewer.layers:
            self._add_layer(layer)

        self.view = self.canvas.central_widget.add_view()
        self.camera = VispyCamera(
            self.view, self.viewer.camera, self.viewer.dims
        )
        self.canvas.connect(self.camera.on_draw)

        # Add axes, scale bar and welcome visuals.
        self._add_visuals(welcome)

        # Create the experimental QtPool for octree and/or monitor.
        self._qt_poll = _create_qt_poll(self, self.viewer.camera)

        # Create the experimental RemoteManager for the monitor.
        self._remote_manager = _create_remote_manager(
            self.viewer.layers, self._qt_poll
        )
Esempio n. 26
0
    def __init__(self, viewer: ViewerModel, show_welcome_screen: bool = False):
        # Avoid circular import.
        from .layer_controls import QtLayerControlsContainer

        super().__init__()
        self._instances.add(self)
        self.setAttribute(Qt.WA_DeleteOnClose)

        self._show_welcome_screen = show_welcome_screen

        QCoreApplication.setAttribute(
            Qt.AA_UseStyleSheetPropagationInWidgetStyles, True
        )

        self.viewer = viewer
        self.dims = QtDims(self.viewer.dims)
        self.controls = QtLayerControlsContainer(self.viewer)
        self.layers = QtLayerList(self.viewer.layers)
        self.layerButtons = QtLayerButtons(self.viewer)
        self.viewerButtons = QtViewerButtons(self.viewer)
        self._key_map_handler = KeymapHandler()
        self._key_map_handler.keymap_providers = [self.viewer]
        self._console = None

        layerList = QWidget()
        layerList.setObjectName('layerList')
        layerListLayout = QVBoxLayout()
        layerListLayout.addWidget(self.layerButtons)
        layerListLayout.addWidget(self.layers)
        layerListLayout.addWidget(self.viewerButtons)
        layerListLayout.setContentsMargins(8, 4, 8, 6)
        layerList.setLayout(layerListLayout)

        self.dockLayerList = QtViewerDockWidget(
            self,
            layerList,
            name=trans._('layer list'),
            area='left',
            allowed_areas=['left', 'right'],
            object_name='layer list',
            close_btn=False,
        )
        self.dockLayerControls = QtViewerDockWidget(
            self,
            self.controls,
            name=trans._('layer controls'),
            area='left',
            allowed_areas=['left', 'right'],
            object_name='layer controls',
            close_btn=False,
        )
        self.dockConsole = QtViewerDockWidget(
            self,
            QWidget(),
            name=trans._('console'),
            area='bottom',
            allowed_areas=['top', 'bottom'],
            object_name='console',
            close_btn=False,
        )
        self.dockConsole.setVisible(False)
        # because the console is loaded lazily in the @getter, this line just
        # gets (or creates) the console when the dock console is made visible.
        self.dockConsole.visibilityChanged.connect(self._ensure_connect)

        # Only created if using perfmon.
        self.dockPerformance = self._create_performance_dock_widget()

        # This dictionary holds the corresponding vispy visual for each layer
        self.layer_to_visual = {}

        self._create_canvas()

        # Stacked widget to provide a welcome page
        self._canvas_overlay = QtWidgetOverlay(self, self.canvas.native)
        self._canvas_overlay.set_welcome_visible(show_welcome_screen)
        self._canvas_overlay.sig_dropped.connect(self.dropEvent)
        self._canvas_overlay.leave.connect(self._leave_canvas)
        self._canvas_overlay.enter.connect(self._enter_canvas)

        main_widget = QWidget()
        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(0, 2, 0, 2)
        main_layout.addWidget(self._canvas_overlay)
        main_layout.addWidget(self.dims)
        main_layout.setSpacing(0)
        main_widget.setLayout(main_layout)

        self.setOrientation(Qt.Vertical)
        self.addWidget(main_widget)

        self._cursors = {
            'cross': Qt.CrossCursor,
            'forbidden': Qt.ForbiddenCursor,
            'pointing': Qt.PointingHandCursor,
            'standard': QCursor(),
        }

        self._on_active_change()
        self.viewer.layers.events.inserted.connect(self._update_welcome_screen)
        self.viewer.layers.events.removed.connect(self._update_welcome_screen)
        self.viewer.layers.selection.events.active.connect(
            self._on_active_change
        )
        self.viewer.camera.events.interactive.connect(self._on_interactive)
        self.viewer.cursor.events.style.connect(self._on_cursor)
        self.viewer.cursor.events.size.connect(self._on_cursor)
        self.viewer.layers.events.reordered.connect(self._reorder_layers)
        self.viewer.layers.events.inserted.connect(self._on_add_layer_change)
        self.viewer.layers.events.removed.connect(self._remove_layer)

        self.setAcceptDrops(True)

        for layer in self.viewer.layers:
            self._add_layer(layer)

        self.view = self.canvas.central_widget.add_view(border_width=0)
        self.camera = VispyCamera(
            self.view, self.viewer.camera, self.viewer.dims
        )
        self.canvas.events.draw.connect(self.camera.on_draw)

        # Add axes, scale bar
        self._add_visuals()

        # Create the experimental QtPool for octree and/or monitor.
        self._qt_poll = _create_qt_poll(self, self.viewer.camera)

        # Create the experimental RemoteManager for the monitor.
        self._remote_manager = _create_remote_manager(
            self.viewer.layers, self._qt_poll
        )

        # moved from the old layerlist... still feels misplaced.
        # can you help me move this elsewhere?
        if config.async_loading:
            from .experimental.qt_chunk_receiver import QtChunkReceiver

            # The QtChunkReceiver object allows the ChunkLoader to pass newly
            # loaded chunks to the layers that requested them.
            self.chunk_receiver = QtChunkReceiver(self.layers)
        else:
            self.chunk_receiver = None

        # bind shortcuts stored in settings last.
        self._bind_shortcuts()