Exemplo n.º 1
0
def init_resources():
    dirpath = pkg_resources.resource_filename(__name__, 'icons') #@UndefinedVariable
    for filepath in glob.glob(os.path.join(dirpath, '*.rcc')):
        if not QResource.registerResource(filepath):
            warnings.warn('Could not register rcc: %s filepath')
            continue
    QIcon.setThemeName('pyhmsa')
Exemplo n.º 2
0
def convert_svg_to_png(svg_path, png_path, height, width):
    """Convert svg files to png files using Qt."""
    size = QSize(height, width)
    icon = QIcon(svg_path)
    pixmap = icon.pixmap(size)
    img = pixmap.toImage()
    img.save(png_path)
Exemplo n.º 3
0
Arquivo: gui.py Projeto: Ulm-IQO/qudi
 def setTheme(self, theme, path):
     """ Set icon theme for qudi app.
         
         @param str theme: Qudi theme name
         @param str path: search path for qudi icons
     """
     # Make icons work on non-X11 platforms, set custom theme
     # if not sys.platform.startswith('linux') and not sys.platform.startswith('freebsd'):
     #
     # To enable the use of custom action icons, for now the above if statement has been
     # removed and the QT theme is being set to our artwork/icons folder for
     # all OSs.
     themepaths = QIcon.themeSearchPaths()
     themepaths.append(path)
     QIcon.setThemeSearchPaths(themepaths)
     QIcon.setThemeName(theme)
Exemplo n.º 4
0
def get_icon(name, default=None, resample=False):
    """Return image inside a QIcon object.

    default: default image name or icon
    resample: if True, manually resample icon pixmaps for usual sizes
    (16, 24, 32, 48, 96, 128, 256). This is recommended for QMainWindow icons
    created from SVG images on non-Windows platforms due to a Qt bug (see
    Issue 1314).
    """

    icon_path = get_image_path(name, default=None)
    if icon_path is not None:
        icon = QIcon(icon_path)
    elif isinstance(default, QIcon):
        icon = default
    elif default is None:
        try:
            icon = get_std_icon(name[:-4])
        except AttributeError:
            icon = QIcon(get_image_path(name, default))
    else:
        icon = QIcon(get_image_path(name, default))
    if resample:
        icon0 = QIcon()
        for size in (16, 24, 32, 48, 96, 128, 256, 512):
            icon0.addPixmap(icon.pixmap(size, size))
        return icon0
    else:
        return icon
Exemplo n.º 5
0
Arquivo: gui.py Projeto: Ulm-IQO/qudi
 def setAppIcon(self):
     """ Set up the Qudi application icon.
     """
     iconpath = 'artwork/logo/logo-qudi-'
     self.appIcon = QIcon()
     self.appIcon.addFile('{0}16x16.png'.format(iconpath), QSize(16, 16))
     self.appIcon.addFile('{0}24x24.png'.format(iconpath), QSize(24, 24))
     self.appIcon.addFile('{0}32x32.png'.format(iconpath), QSize(32, 32))
     self.appIcon.addFile('{0}48x48.png'.format(iconpath), QSize(48, 48))
     self.appIcon.addFile('{0}256x256.png'.format(iconpath),
                          QSize(256, 256))
     QApplication.instance().setWindowIcon(self.appIcon)
Exemplo n.º 6
0
    def __init__(self) -> None:
        """Init UI."""
        super(Csgogsi, self).__init__()
        # Widgets
        self.server_thread = None
        self.connect_btn = QPushButton('Connect')
        self.connect_btn.clicked.connect(self.connect)

        self.comcb = QComboBox()
        list_ports_device = [port.device for port in list_ports.comports()]
        self.comcb.addItems(list_ports_device)
        if list_ports_device == []:
            self.connect_btn.setDisabled(True)
        else:
            self.connect_btn.setDisabled(False)

        self.refresh_btn = QPushButton('Refresh')
        self.refresh_btn.resize(self.refresh_btn.sizeHint())
        self.refresh_btn.clicked.connect(self.refresh)

        self.payload_viewer_btn = QPushButton('View payload')
        self.payload_viewer_btn.setDisabled(True)

        # Container
        vbox = QVBoxLayout()
        hbox = QHBoxLayout()
        vbox.addStretch(1)
        hbox.addWidget(self.comcb)
        hbox.addWidget(self.refresh_btn)
        vbox.addLayout(hbox)
        vbox.addWidget(self.payload_viewer_btn)
        vbox.addWidget(self.connect_btn)
        self.setLayout(vbox)
        # Icon
        app_icon = QIcon()
        app_icon.addFile(__dir__ + "\\data\\csgo-16.ico", QSize(16, 16))
        app_icon.addFile(__dir__ + "\\data\\csgo-20.ico", QSize(20, 20))
        app_icon.addFile(__dir__ + "\\data\\csgo-24.ico", QSize(24, 24))
        app_icon.addFile(__dir__ + "\\data\\csgo-32.ico", QSize(32, 32))
        app_icon.addFile(__dir__ + "\\data\\csgo-48.ico", QSize(48, 48))
        app_icon.addFile(__dir__ + "\\data\\csgo-64.ico", QSize(64, 64))
        app_icon.addFile(__dir__ + "\\data\\csgo-128.ico", QSize(128, 128))
        app_icon.addFile(__dir__ + "\\data\\csgo-256.ico", QSize(256, 256))
        app_icon.addFile(__dir__ + "\\data\\csgo-512.ico", QSize(512, 512))
        # Window
        self.setWindowIcon(app_icon)
        self.setWindowTitle('CSGO GSI on LCD')
        self.setWindowFlags(Qt.WindowCloseButtonHint)

        self.show()
        self.setFixedSize(self.size())
Exemplo n.º 7
0
Arquivo: gui.py Projeto: Ulm-IQO/qudi
class Gui(QObject):
    """ Set up all necessary GUI elements, like application icons, themes, etc.
    """

    def __init__(self):
        super().__init__()
        QApplication.instance().setQuitOnLastWindowClosed(False)

    def setAppIcon(self):
        """ Set up the Qudi application icon.
        """
        iconpath = 'artwork/logo/logo-qudi-'
        self.appIcon = QIcon()
        self.appIcon.addFile('{0}16x16.png'.format(iconpath), QSize(16, 16))
        self.appIcon.addFile('{0}24x24.png'.format(iconpath), QSize(24, 24))
        self.appIcon.addFile('{0}32x32.png'.format(iconpath), QSize(32, 32))
        self.appIcon.addFile('{0}48x48.png'.format(iconpath), QSize(48, 48))
        self.appIcon.addFile('{0}256x256.png'.format(iconpath),
                             QSize(256, 256))
        QApplication.instance().setWindowIcon(self.appIcon)

    def setTheme(self, theme, path):
        """ Set icon theme for qudi app.
            
            @param str theme: Qudi theme name
            @param str path: search path for qudi icons
        """
        # Make icons work on non-X11 platforms, set custom theme
        # if not sys.platform.startswith('linux') and not sys.platform.startswith('freebsd'):
        #
        # To enable the use of custom action icons, for now the above if statement has been
        # removed and the QT theme is being set to our artwork/icons folder for
        # all OSs.
        themepaths = QIcon.themeSearchPaths()
        themepaths.append(path)
        QIcon.setThemeSearchPaths(themepaths)
        QIcon.setThemeName(theme)

    def setStyleSheet(self, stylesheetpath):
        """ Set qss style sheet for application.

            @param str stylesheetpath: path to style sheet file
        """
        with open(stylesheetpath, 'r') as stylesheetfile:
            stylesheet = stylesheetfile.read()

        # see issue #12 on qdarkstyle github
        if platform.system().lower() == 'darwin' and stylesheetpath.endswith('qdark.qss'):
            mac_fix = '''
            QDockWidget::title
            {
                background-color: #31363b;
                text-align: center;
                height: 12px;
            }
            '''
            stylesheet += mac_fix
        QApplication.instance().setStyleSheet(stylesheet)

    def closeWindows(self):
        """ Close all application windows.
        """
        QApplication.instance().closeAllWindows()
Exemplo n.º 8
0
 def getIcon(self, name):
     # icon_name = 'axis-%(axis_letter).png' % {'axis_letter': self._anum}
     return QIcon(os.path.join(ICON_PATH, name))
Exemplo n.º 9
0
def get_icon_by_extension_or_type(fname, scale_factor):
    """Return the icon depending on the file extension"""
    application_icons = {}
    application_icons.update(BIN_FILES)
    application_icons.update(DOCUMENT_FILES)
    if osp.isdir(fname):
        return icon('DirOpenIcon', scale_factor)
    else:
        basename = osp.basename(fname)
        __, extension = osp.splitext(basename.lower())
        mime_type, __ = mime.guess_type(basename)
        if is_dark_interface():
            icon_by_extension = QIcon(get_image_path('binary.svg'))
        else:
            icon_by_extension = QIcon(get_image_path('binary_light.svg'))

        if extension in OFFICE_FILES:
            icon_by_extension = icon(OFFICE_FILES[extension], scale_factor)

        elif extension in LANGUAGE_ICONS:
            icon_by_extension = icon(LANGUAGE_ICONS[extension], scale_factor)
        else:
            if extension == '.ipynb':
                if is_dark_interface():
                    icon_by_extension = QIcon(
                        get_image_path('notebook_dark.svg'))
                else:
                    icon_by_extension = QIcon(
                        get_image_path('notebook_light.svg'))
            elif extension == '.tex':
                if is_dark_interface():
                    icon_by_extension = QIcon(
                        get_image_path('file_type_tex.svg'))
                else:
                    icon_by_extension = QIcon(
                        get_image_path('file_type_light_tex.svg'))
            elif is_text_file(fname):
                icon_by_extension = icon('TextFileIcon', scale_factor)
            elif mime_type is not None:
                try:
                    # Fix for spyder-ide/spyder#5080. Even though
                    # mimetypes.guess_type documentation states that
                    # the return value will be None or a tuple of
                    # the form type/subtype, in the Windows registry,
                    # .sql has a mimetype of text\plain
                    # instead of text/plain therefore mimetypes is
                    # returning it incorrectly.
                    file_type, bin_name = mime_type.split('/')
                except ValueError:
                    file_type = None
                if file_type is None:
                    if is_dark_interface():
                        icon_by_extension = QIcon(get_image_path('binary.svg'))
                    else:
                        icon_by_extension = QIcon(
                            get_image_path('binary_light.svg'))
                elif file_type == 'audio':
                    icon_by_extension = icon('AudioFileIcon', scale_factor)
                elif file_type == 'video':
                    icon_by_extension = icon('VideoFileIcon', scale_factor)
                elif file_type == 'image':
                    icon_by_extension = icon('ImageFileIcon', scale_factor)
                elif file_type == 'application':
                    if bin_name in application_icons:
                        icon_by_extension = icon(application_icons[bin_name],
                                                 scale_factor)
    return icon_by_extension
Exemplo n.º 10
0
def color_icon(name: str, size: int = 20) -> QIcon:
    """Get color block as QIcon by name."""
    color_block = QPixmap(QSize(size, size))
    color_block.fill(color_qt(name))
    return QIcon(color_block)
Exemplo n.º 11
0
 def _icon_by_painter(self, painter, options):
     """Return the icon corresponding to the given painter."""
     engine = CharIconEngine(self, painter, options)
     return QIcon(engine)
Exemplo n.º 12
0
    def scan_devices_update_list_view(self):
        """
        Scan for new devices; and update the list view
        :return:
        """
        # self.devices_view.clear()
        device_exists_in_view = False
        paired_devices = []
        for index in range(self.devices_view.count()):
            paired_devices.append(self.devices_view.item(index))

        __devices = self.adb.devices_detailed()
        log(__devices)
        for i in __devices:
            device_is_wifi = i["identifier"].count(".") >= 3 and (
                ":" in i["identifier"])

            if i["identifier"] not in self.config["device"].keys():
                device_paired_and_exists = False
                self.config["device"][i["identifier"]] = {"rotation": 0}
            else:
                device_paired_and_exists = True

            if device_is_wifi:
                _icon_suffix = "_wifi"
            else:
                _icon_suffix = "_usb"

            icon = ":/icons/icons/portrait_mobile_white{}.svg".format(
                _icon_suffix)

            if i["status"] == "offline":
                icon = ":/icons/icons/portrait_mobile_error.svg"
            elif i["status"] == "unauthorized":
                icon = ":/icons/icons/portrait_mobile_warning.svg"

            if i["status"] == "no_permission":
                log("pairfilter: 5")
                # https://stackoverflow.com/questions/
                # 53887322/adb-devices-no-permissions-user-in-
                # plugdev-group-are-your-udev-rules-wrong
                udev_error = (
                    "Error connecting to device. Your udev rules are"
                    " incorrect. See https://stackoverflow.com/questions"
                    "/53887322/adb-devices-no-permissions-user-in-plugdev-"
                    "group-are-your-udev-rules-wrong")
                self.display_public_message(udev_error)
                print(udev_error)
                return []
            # Check if device is unauthorized
            elif i["status"] == "unauthorized":
                log("unauthorized device detected: Click Allow on your device")
                log("pairfilter: 4")
                # The device is connected; and might/might't paired in the past
                # And is connected to the same IP address
                # It is possibly a bug with the connection;
                # Temporarily create a new QListItem to display the
                # device with the error
                paired = False
                device_paired_and_exists = False
                self.display_public_message(
                    f"{i['identifier']} is unauthorized. Please click allow "
                    f"on your device.")
                # Remove other devices with the same id and offline and
                # unauthorized
                self.remove_device_device_view(
                    i["identifier"], statuses=["offline", "unauthorized"])
                # Unauthorized device cannot be considered as a paired device
                devices_view_list_item = QListWidgetItem()
            else:
                # check if device is paired
                # if yes, just update the list item
                if not device_paired_and_exists:
                    paired = False
                    devices_view_list_item = QListWidgetItem()
                else:
                    for paired_device in paired_devices:
                        if paired_device.text().split()[0] == i["model"]:
                            log("pairfilter: 1")
                            paired = True
                            devices_view_list_item = paired_device
                            # as we have found a paired device
                            # we know by assumption; there cannot be two
                            # devices with the same local IP address;
                            # lets scan the devices_view once more in a loop
                            # to check for any device with the same
                            # identifier and remove them; based on this same
                            # assumption
                            self.remove_device_device_view(
                                i["identifier"],
                                statuses=["offline", "unauthorized"])
                            break
                        elif paired_device.text().split(
                        )[1] == i["identifier"]:
                            log("pairfilter: 2")
                            self.remove_device_device_view(
                                i["identifier"],
                                statuses=["offline", "unauthorized"])
                            devices_view_list_item = QListWidgetItem()
                            paired = False
                            break
                    else:
                        log("pairfilter: 3")
                        paired = False
                        devices_view_list_item = QListWidgetItem()

            devices_view_list_item.setIcon(QIcon(icon))

            devices_view_list_item.setText("{device}\n{mode}\n{status}".format(
                device=i["model"], mode=i["identifier"], status=i["status"]))
            __sha_shift = self.config.get("sha_shift", 5)
            __sha = hashlib.sha256(str(i["identifier"]).encode()).hexdigest(
            )[__sha_shift:__sha_shift + 6]
            devices_view_list_item.setToolTip(
                "Device: "
                "<span style='color: #{inv_color};background-color: #{color}'>"
                "<b>{d}</b></span>\n"
                "<br>"
                "Model: {m}\n<br>"
                "Alias: {a}\n<br>"
                "Status: {s}\n<br>"
                "Transport ID: {t}\n<br>"
                "Paired: {p}".format(
                    d=i["identifier"],
                    m=i["model"],
                    a=i["product"],
                    s=i["status"],
                    t=i["transport_id"],
                    p=paired,
                    color=__sha,
                    inv_color=str(hex(0xFFFFFF - int(__sha, 16))[2:]),
                ))

            devices_view_list_item.setFont(QFont("Noto Sans", 8))
            log(f"Pairing status: {device_paired_and_exists}")
            if device_paired_and_exists and device_is_wifi:
                # we need to only neglect wifi devices
                # paired usb device need to still show in the display
                continue
            elif device_exists_in_view:
                # devices exists in the list with the same status and
                # we should not add the new detected list item
                continue
            # If and only if the device doesn't exist; add it
            self.devices_view.addItem(devices_view_list_item)
        return __devices
Exemplo n.º 13
0
    def create_file_manage_actions(self, fnames):
        """Return file management actions."""
        only_files = all(osp.isfile(_fn) for _fn in fnames)
        fname = fnames[0]
        #        only_modules = all(
        #            [
        #                osp.splitext(_fn)[1] in ('.py', '.pyw', '.ipy')
        #                for _fn in fnames
        #            ]
        #        )
        #        only_notebooks = all(
        #            [osp.splitext(_fn)[1] == '.ipynb' for _fn in fnames]
        #        )
        #        only_valid = all([encoding.is_text_file(_fn) for _fn in
        #                          fnames])
        #        run_action = create_action(
        #            self,
        #            "Run",
        #            icon=QIcon(),  # ima.icon('run'),
        #            triggered=self.run,
        #        )
        #        edit_action = create_action(
        #            self,
        #            "Edit",
        #            icon=QIcon(),  # ima.icon('edit'),
        #            triggered=self.clicked,
        #        )
        move_action = create_action(
            self,
            "Move...",
            icon=QIcon(),  # "move.png",
            triggered=self.move,
        )
        delete_action = create_action(
            self,
            "Delete...",
            icon=QIcon(),  # ima.icon('editdelete'),
            triggered=self.delete)
        add_to_project_action = create_action(
            self,
            "Add to project...",
            icon=QIcon(),  # ima.icon('rename'),
            triggered=lambda x, fname=fname: self.add_to_project(fname),
        )
        rename_action = create_action(
            self,
            "Rename...",
            icon=QIcon(),  # ima.icon('rename'),
            triggered=self.rename)
        #        open_action = create_action(self, "Open", triggered=self.open)
        #        ipynb_convert_action = create_action(
        #            self,
        #            "Convert to Python script",
        #            icon=QIcon(),  # ima.icon('python'),
        #            triggered=self.convert_notebooks
        #        )

        actions = []
        #        if only_modules:
        #            actions.append(run_action)
        #        if only_valid and only_files:
        #            actions.append(edit_action)
        #        else:
        #            actions.append(open_action)
        actions += [delete_action, rename_action]
        basedir = fixpath(osp.dirname(fnames[0]))
        if all(fixpath(osp.dirname(_fn)) == basedir for _fn in fnames):
            actions.append(move_action)

        if only_files and os.path.dirname(fname) != self.project_path:
            actions += [None, add_to_project_action]

#        if only_notebooks and nbexporter is not None:
#            actions.append(ipynb_convert_action)

        return actions
Exemplo n.º 14
0
    def __init__(self, name, plugin, parent=None, configuration=CONF):
        if PYQT5:
            super().__init__(parent=parent,
                             class_parent=plugin,
                             configuration=configuration)
        else:
            QWidget.__init__(self, parent)
            SpyderWidgetMixin.__init__(self,
                                       class_parent=plugin,
                                       configuration=configuration)

        # Attributes
        # --------------------------------------------------------------------
        self._is_tab = False
        self._name = name
        self._plugin = plugin
        self._parent = parent
        self._default_margins = None
        self.is_maximized = None
        self.is_visible = None
        self.dock_action = None
        self.undock_action = None
        self.close_action = None
        self._toolbars_already_rendered = False

        # Attribute used to access the action, toolbar, toolbutton and menu
        # registries
        self.PLUGIN_NAME = name

        # We create our toggle action instead of using the one that comes with
        # dockwidget because it was not possible to raise and focus the plugin
        self.toggle_view_action = None
        self._toolbars = OrderedDict()
        self._auxiliary_toolbars = OrderedDict()

        # Widgets
        # --------------------------------------------------------------------
        self.windowwidget = None
        self.dockwidget = None
        self._icon = QIcon()
        self._spinner = None

        if self.ENABLE_SPINNER:
            self._spinner = create_waitspinner(size=16, parent=self)

        self._corner_widget = MainCornerWidget(
            parent=self,
            name=PluginMainWidgetWidgets.CornerWidget,
        )
        self._corner_widget.ID = 'main_corner'

        self._main_toolbar = MainWidgetToolbar(
            parent=self,
            title=_("Main widget toolbar"),
        )
        self._main_toolbar.ID = 'main_toolbar'

        TOOLBAR_REGISTRY.register_reference(self._main_toolbar,
                                            self._main_toolbar.ID,
                                            self.PLUGIN_NAME,
                                            self.CONTEXT_NAME)

        self._corner_toolbar = MainWidgetToolbar(
            parent=self,
            title=_("Main widget corner toolbar"),
        )
        self._corner_toolbar.ID = 'corner_toolbar',

        TOOLBAR_REGISTRY.register_reference(self._corner_toolbar,
                                            self._corner_toolbar.ID,
                                            self.PLUGIN_NAME,
                                            self.CONTEXT_NAME)

        self._corner_toolbar.setSizePolicy(QSizePolicy.Minimum,
                                           QSizePolicy.Expanding)
        self._options_menu = self.create_menu(
            PluginMainWidgetMenus.Options,
            title=_('Options menu'),
        )

        # Layout
        # --------------------------------------------------------------------
        # These margins are necessary to give some space between the widgets
        # inside this widget and the window vertical separator.
        self._margin_left = 1
        self._margin_right = 1

        self._main_layout = QVBoxLayout()
        self._toolbars_layout = QVBoxLayout()
        self._main_toolbar_layout = QHBoxLayout()

        self._toolbars_layout.setContentsMargins(self._margin_left, 0,
                                                 self._margin_right, 0)
        self._toolbars_layout.setSpacing(0)
        self._main_toolbar_layout.setContentsMargins(0, 0, 0, 0)
        self._main_toolbar_layout.setSpacing(0)
        self._main_layout.setContentsMargins(0, 0, 0, 0)
        self._main_layout.setSpacing(0)

        # Add inititals layouts
        self._main_toolbar_layout.addWidget(self._main_toolbar, stretch=10000)
        self._main_toolbar_layout.addWidget(self._corner_toolbar, stretch=1)
        self._toolbars_layout.addLayout(self._main_toolbar_layout)
        self._main_layout.addLayout(self._toolbars_layout, stretch=1)
Exemplo n.º 15
0
def get_app(
    *,
    app_name: str = None,
    app_version: str = None,
    icon: str = None,
    org_name: str = None,
    org_domain: str = None,
    app_id: str = None,
    ipy_interactive: bool = None,
) -> QApplication:
    """Get or create the Qt QApplication.

    There is only one global QApplication instance, which can be retrieved by
    calling get_app again, (or by using QApplication.instance())

    Parameters
    ----------
    app_name : str, optional
        Set app name (if creating for the first time), by default 'napari'
    app_version : str, optional
        Set app version (if creating for the first time), by default __version__
    icon : str, optional
        Set app icon (if creating for the first time), by default
        NAPARI_ICON_PATH
    org_name : str, optional
        Set organization name (if creating for the first time), by default
        'napari'
    org_domain : str, optional
        Set organization domain (if creating for the first time), by default
        'napari.org'
    app_id : str, optional
        Set organization domain (if creating for the first time).  Will be
        passed to set_app_id (which may also be called independently), by
        default NAPARI_APP_ID
    ipy_interactive : bool, optional
        Use the IPython Qt event loop ('%gui qt' magic) if running in an
        interactive IPython terminal.

    Returns
    -------
    QApplication
        [description]

    Notes
    -----
    Substitutes QApplicationWithTracing when the NAPARI_PERFMON env variable
    is set.

    """
    # napari defaults are all-or nothing.  If any of the keywords are used
    # then they are all used.
    set_values = {k for k, v in locals().items() if v}
    kwargs = locals() if set_values else _defaults
    global _app_ref

    app = QApplication.instance()
    if app:
        set_values.discard("ipy_interactive")
        if set_values:

            warn(
                trans._(
                    "QApplication already existed, these arguments to to 'get_app' were ignored: {args}",
                    deferred=True,
                    args=set_values,
                ))
        if perf_config and perf_config.trace_qt_events:
            warn(
                trans._(
                    "Using NAPARI_PERFMON with an already-running QtApp (--gui qt?) is not supported.",
                    deferred=True,
                ))

    else:
        # automatically determine monitor DPI.
        # Note: this MUST be set before the QApplication is instantiated
        if PYQT5:
            QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
            QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)

        argv = sys.argv.copy()
        if sys.platform == "darwin" and not argv[0].endswith("napari"):
            # Make sure the app name in the Application menu is `napari`
            # which is taken from the basename of sys.argv[0]; we use
            # a copy so the original value is still available at sys.argv
            argv[0] = "napari"

        if perf_config and perf_config.trace_qt_events:
            from .perf.qt_event_tracing import QApplicationWithTracing

            app = QApplicationWithTracing(argv)
        else:
            app = QApplication(argv)

        # if this is the first time the Qt app is being instantiated, we set
        # the name and metadata
        app.setApplicationName(kwargs.get('app_name'))
        app.setApplicationVersion(kwargs.get('app_version'))
        app.setOrganizationName(kwargs.get('org_name'))
        app.setOrganizationDomain(kwargs.get('org_domain'))
        set_app_id(kwargs.get('app_id'))

        # Intercept tooltip events in order to convert all text to rich text
        # to allow for text wrapping of tooltips
        app.installEventFilter(QtToolTipEventFilter())

    if app.windowIcon().isNull():
        app.setWindowIcon(QIcon(kwargs.get('icon')))

    if ipy_interactive is None:
        ipy_interactive = get_settings().application.ipy_interactive
    if _IPYTHON_WAS_HERE_FIRST:
        _try_enable_ipython_gui('qt' if ipy_interactive else None)

    if not _ipython_has_eventloop():
        notification_manager.notification_ready.connect(
            NapariQtNotification.show_notification)
        notification_manager.notification_ready.connect(
            show_console_notification)

    if perf_config and not perf_config.patched:
        # Will patch based on config file.
        perf_config.patch_callables()

    if not _app_ref:  # running get_app for the first time
        # see docstring of `wait_for_workers_to_quit` for caveats on killing
        # workers at shutdown.
        app.aboutToQuit.connect(wait_for_workers_to_quit)

        # this will register all of our resources (icons) with Qt, so that they
        # can be used in qss files and elsewhere.
        _register_napari_resources()

    _app_ref = app  # prevent garbage collection

    # Add the dispatcher attribute to the application to be able to dispatch
    # notifications coming from threads

    return app
Exemplo n.º 16
0
def resourceStateIcon(on, off):
    """Load two images as an icon with on and off states"""
    icon = QIcon()
    icon.addPixmap(resourceImage(on), state=QIcon.On)
    icon.addPixmap(resourceImage(off), state=QIcon.Off)
    return icon
Exemplo n.º 17
0
def resourceIcon(name):
    """Load an image as an icon"""
    # print("Icon used: %s" % name)
    return QIcon(resource_filename("ert_gui", "resources/gui/img/" + name))
Exemplo n.º 18
0
    def setup(self):
        """Setup the ShortcutEditor with the provided arguments."""
        # Widgets
        icon_info = HelperToolButton()
        icon_info.setIcon(get_std_icon('MessageBoxInformation'))
        layout_icon_info = QVBoxLayout()
        layout_icon_info.setContentsMargins(0, 0, 0, 0)
        layout_icon_info.setSpacing(0)
        layout_icon_info.addWidget(icon_info)
        layout_icon_info.addStretch(100)

        self.label_info = QLabel()
        self.label_info.setText(
            _("Press the new shortcut and select 'Ok' to confirm, "
              "click 'Cancel' to revert to the previous state, "
              "or use 'Clear' to unbind the command from a shortcut."))
        self.label_info.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        self.label_info.setWordWrap(True)
        layout_info = QHBoxLayout()
        layout_info.setContentsMargins(0, 0, 0, 0)
        layout_info.addLayout(layout_icon_info)
        layout_info.addWidget(self.label_info)
        layout_info.setStretch(1, 100)

        self.label_current_sequence = QLabel(_("Current shortcut:"))
        self.text_current_sequence = QLabel(self.current_sequence)

        self.label_new_sequence = QLabel(_("New shortcut:"))
        self.text_new_sequence = ShortcutLineEdit(self)
        self.text_new_sequence.setPlaceholderText(_("Press shortcut."))

        self.helper_button = HelperToolButton()
        self.helper_button.setIcon(QIcon())
        self.label_warning = QLabel()
        self.label_warning.setWordWrap(True)
        self.label_warning.setAlignment(Qt.AlignTop | Qt.AlignLeft)

        self.button_default = QPushButton(_('Default'))
        self.button_ok = QPushButton(_('Ok'))
        self.button_ok.setEnabled(False)
        self.button_clear = QPushButton(_('Clear'))
        self.button_cancel = QPushButton(_('Cancel'))
        button_box = QHBoxLayout()
        button_box.addWidget(self.button_default)
        button_box.addStretch(100)
        button_box.addWidget(self.button_ok)
        button_box.addWidget(self.button_clear)
        button_box.addWidget(self.button_cancel)

        # New Sequence button box
        self.btn_clear_sequence = create_toolbutton(
            self, icon=ima.icon('editclear'),
            tip=_("Clear all entered key sequences"),
            triggered=self.clear_new_sequence)
        self.button_back_sequence = create_toolbutton(
            self, icon=ima.icon('ArrowBack'),
            tip=_("Remove last key sequence entered"),
            triggered=self.back_new_sequence)

        newseq_btnbar = QHBoxLayout()
        newseq_btnbar.setSpacing(0)
        newseq_btnbar.setContentsMargins(0, 0, 0, 0)
        newseq_btnbar.addWidget(self.button_back_sequence)
        newseq_btnbar.addWidget(self.btn_clear_sequence)

        # Setup widgets
        self.setWindowTitle(_('Shortcut: {0}').format(self.name))
        self.helper_button.setToolTip('')
        style = """
            QToolButton {
              margin:1px;
              border: 0px solid grey;
              padding:0px;
              border-radius: 0px;
            }"""
        self.helper_button.setStyleSheet(style)
        icon_info.setToolTip('')
        icon_info.setStyleSheet(style)

        # Layout
        layout_sequence = QGridLayout()
        layout_sequence.setContentsMargins(0, 0, 0, 0)
        layout_sequence.addLayout(layout_info, 0, 0, 1, 4)
        layout_sequence.addItem(QSpacerItem(15, 15), 1, 0, 1, 4)
        layout_sequence.addWidget(self.label_current_sequence, 2, 0)
        layout_sequence.addWidget(self.text_current_sequence, 2, 2)
        layout_sequence.addWidget(self.label_new_sequence, 3, 0)
        layout_sequence.addWidget(self.helper_button, 3, 1)
        layout_sequence.addWidget(self.text_new_sequence, 3, 2)
        layout_sequence.addLayout(newseq_btnbar, 3, 3)
        layout_sequence.addWidget(self.label_warning, 4, 2, 1, 2)
        layout_sequence.setColumnStretch(2, 100)
        layout_sequence.setRowStretch(4, 100)

        layout = QVBoxLayout(self)
        layout.addLayout(layout_sequence)
        layout.addSpacing(10)
        layout.addLayout(button_box)
        layout.setSizeConstraint(layout.SetFixedSize)

        # Signals
        self.button_ok.clicked.connect(self.accept_override)
        self.button_clear.clicked.connect(self.unbind_shortcut)
        self.button_cancel.clicked.connect(self.reject)
        self.button_default.clicked.connect(self.set_sequence_to_default)

        # Set all widget to no focus so that we can register <Tab> key
        # press event.
        widgets = (
            self.label_warning, self.helper_button, self.text_new_sequence,
            self.button_clear, self.button_default, self.button_cancel,
            self.button_ok, self.btn_clear_sequence, self.button_back_sequence)
        for w in widgets:
            w.setFocusPolicy(Qt.NoFocus)
            w.clearFocus()
Exemplo n.º 19
0
 def icon(self):
     return QIcon()
Exemplo n.º 20
0
def get_app(
    *,
    app_name: str = None,
    app_version: str = None,
    icon: str = None,
    org_name: str = None,
    org_domain: str = None,
    app_id: str = None,
    ipy_interactive: bool = None,
) -> QApplication:
    """Get or create the Qt QApplication.

    There is only one global QApplication instance, which can be retrieved by
    calling get_app again, (or by using QApplication.instance())

    Parameters
    ----------
    app_name : str, optional
        Set app name (if creating for the first time), by default 'napari'
    app_version : str, optional
        Set app version (if creating for the first time), by default __version__
    icon : str, optional
        Set app icon (if creating for the first time), by default
        NAPARI_ICON_PATH
    org_name : str, optional
        Set organization name (if creating for the first time), by default
        'napari'
    org_domain : str, optional
        Set organization domain (if creating for the first time), by default
        'napari.org'
    app_id : str, optional
        Set organization domain (if creating for the first time).  Will be
        passed to set_app_id (which may also be called independently), by
        default NAPARI_APP_ID
    ipy_interactive : bool, optional
        Use the IPython Qt event loop ('%gui qt' magic) if running in an
        interactive IPython terminal.

    Returns
    -------
    QApplication
        [description]

    Notes
    -----
    Substitutes QApplicationWithTracing when the NAPARI_PERFMON env variable
    is set.

    If the QApplication already exists, we call convert_app_for_tracing() which
    deletes the QApplication and creates a new one. However here with get_app
    we need to create the correct QApplication up front, or we will crash
    because we'd be deleting the QApplication after we created QWidgets with
    it, such as we do for the splash screen.
    """
    # napari defaults are all-or nothing.  If any of the keywords are used
    # then they are all used.
    set_values = {k for k, v in locals().items() if v}
    kwargs = locals() if set_values else _defaults
    global _app_ref

    app = QApplication.instance()
    if app:
        set_values.discard("ipy_interactive")
        if set_values:

            warn(
                "QApplication already existed, these arguments to to 'get_app'"
                " were ignored: {}".format(set_values))
        if perf_config and perf_config.trace_qt_events:
            from .perf.qt_event_tracing import convert_app_for_tracing

            # no-op if app is already a QApplicationWithTracing
            app = convert_app_for_tracing(app)
    else:
        # automatically determine monitor DPI.
        # Note: this MUST be set before the QApplication is instantiated
        QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)

        if perf_config and perf_config.trace_qt_events:
            from .perf.qt_event_tracing import QApplicationWithTracing

            app = QApplicationWithTracing(sys.argv)
        else:
            app = QApplication(sys.argv)

        # if this is the first time the Qt app is being instantiated, we set
        # the name and metadata
        app.setApplicationName(kwargs.get('app_name'))
        app.setApplicationVersion(kwargs.get('app_version'))
        app.setOrganizationName(kwargs.get('org_name'))
        app.setOrganizationDomain(kwargs.get('org_domain'))
        set_app_id(kwargs.get('app_id'))

        notification_manager.notification_ready.connect(
            NapariQtNotification.show_notification)
        notification_manager.notification_ready.connect(
            show_console_notification)

    if app.windowIcon().isNull():
        app.setWindowIcon(QIcon(kwargs.get('icon')))

    if ipy_interactive is None:
        ipy_interactive = SETTINGS.application.ipy_interactive
    _try_enable_ipython_gui('qt' if ipy_interactive else None)

    if perf_config and not perf_config.patched:
        # Will patch based on config file.
        perf_config.patch_callables()

    if not _app_ref:  # running get_app for the first time
        # see docstring of `wait_for_workers_to_quit` for caveats on killing
        # workers at shutdown.
        app.aboutToQuit.connect(wait_for_workers_to_quit)

        # this will register all of our resources (icons) with Qt, so that they
        # can be used in qss files and elsewhere.
        _register_napari_resources()

    _app_ref = app  # prevent garbage collection
    return app
Exemplo n.º 21
0
 def setup_command_link_button(self, link_button, text, image_location, width=40, height=40):
     link_button.setText(text)
     link_button.setIconSize(QSize(self.rescale_w(width), self.rescale_h(height)))
     link_button.setIcon(QIcon(QPixmap(image_location)))
     return link_button
Exemplo n.º 22
0
 def get_icon(self):
     """Return the widget tooltip text."""
     return QIcon()
Exemplo n.º 23
0
 def get_icon(self):
     return QIcon()
Exemplo n.º 24
0
def start_workbench(app, command_line_options):
    """Given an application instance create the MainWindow,
    show it and start the main event loop
    """
    # MainWindow needs to be imported locally to ensure the matplotlib
    # backend is not imported too early.
    from workbench.app.mainwindow import MainWindow

    # The ordering here is very delicate. Test thoroughly when
    # changing anything!
    main_window = MainWindow()

    # Set the mainwindow as the parent for additional QMainWindow instances
    from workbench.config import set_additional_windows_parent
    set_additional_windows_parent(main_window)

    # decorates the excepthook callback with the reference to the main window
    # this is used in case the user wants to terminate the workbench from the error window shown
    sys.excepthook = partial(exception_logger, main_window)

    # Load matplotlib as early as possible and set our defaults
    # Setup our custom backend and monkey patch in custom current figure manager
    main_window.set_splash('Preloading matplotlib')
    from workbench.plotting.config import initialize_matplotlib  # noqa
    initialize_matplotlib()

    # Setup widget layouts etc. mantid.simple cannot be used before this
    # or the log messages don't get through to the widget
    main_window.setup()
    # start mantid
    main_window.set_splash('Initializing mantid framework')
    FrameworkManagerImpl.Instance()
    main_window.post_mantid_init()

    if main_window.splash:
        main_window.splash.hide()

    if command_line_options.script is not None:
        main_window.editor.open_file_in_new_tab(command_line_options.script)
        editor_task = None
        if command_line_options.execute:
            # if the quit flag is not specified, this task reference will be
            # GC'ed, and the task will be finished alongside the GUI startup
            editor_task = main_window.editor.execute_current_async()

        if command_line_options.quit:
            # wait for the code interpreter thread to finish executing the script
            editor_task.join()
            main_window.close()

            # for task exit code descriptions see the classes AsyncTask and TaskExitCode
            return int(editor_task.exit_code) if editor_task else 0

    main_window.show()
    main_window.setWindowIcon(QIcon(':/images/MantidIcon.ico'))
    # Project Recovery on startup
    main_window.project_recovery.repair_checkpoints()
    if main_window.project_recovery.check_for_recover_checkpoint():
        main_window.project_recovery.attempt_recovery()
    else:
        main_window.project_recovery.start_recovery_thread()

    if not (command_line_options.execute or command_line_options.quit):
        if AboutPresenter.should_show_on_startup():
            AboutPresenter(main_window).show()

    # lift-off!
    return app.exec_()
Exemplo n.º 25
0
 def _window_load_icons(self):
     self._icons["help"] = QIcon.fromTheme("help")
     self._icons["play"] = QIcon.fromTheme("play")
     self._icons["pause"] = QIcon.fromTheme("pause")
     self._icons["reset"] = QIcon.fromTheme("reset")
     self._icons["scale"] = QIcon.fromTheme("scale")
     self._icons["clear"] = QIcon.fromTheme("clear")
     self._icons["movie"] = QIcon.fromTheme("movie")
     self._icons["restore"] = QIcon.fromTheme("restore")
     self._icons["screenshot"] = QIcon.fromTheme("screenshot")
     self._icons["visibility_on"] = QIcon.fromTheme("visibility_on")
     self._icons["visibility_off"] = QIcon.fromTheme("visibility_off")
     self._icons["folder"] = QIcon.fromTheme("folder")
Exemplo n.º 26
0
def main():
    #==========================================================================
    # Proper high DPI scaling is available in Qt >= 5.6.0. This attribute must
    # be set before creating the application.
    #==========================================================================
    if CONF.get('main', 'high_dpi_custom_scale_factor'):
        factors = str(CONF.get('main', 'high_dpi_custom_scale_factors'))
        f = list(filter(None, factors.split(';')))
        if len(f) == 1:
            os.environ['QT_SCALE_FACTOR'] = f[0]
        else:
            os.environ['QT_SCREEN_SCALE_FACTORS'] = factors
    else:
        os.environ['QT_SCALE_FACTOR'] = ''
        os.environ['QT_SCREEN_SCALE_FACTORS'] = ''

    # Splash screen
    # -------------------------------------------------------------------------
    # Start Qt Splash to inform the user of the current status
    app = qapplication()
    restarter = Restarter()

    if PYQT5:
        APP_ICON = QIcon(get_image_path("spyder.svg"))
    else:
        APP_ICON = QIcon(get_image_path("spyder.png"))
    app.setWindowIcon(APP_ICON)
    restarter.set_splash_message(_('Closing Spyder'))

    # Get variables
    # Note: Variables defined in app/mainwindow.py 'restart()' method
    spyder_args = os.environ.pop('SPYDER_ARGS', None)
    pid = os.environ.pop('SPYDER_PID', None)
    is_bootstrap = os.environ.pop('SPYDER_IS_BOOTSTRAP', None)
    reset = os.environ.pop('SPYDER_RESET', None)

    # Get the spyder base folder based on this file
    this_folder = osp.split(osp.dirname(osp.abspath(__file__)))[0]
    spyder_folder = osp.split(this_folder)[0]

    if not any([spyder_args, pid, is_bootstrap, reset]):
        error = "This script can only be called from within a Spyder instance"
        raise RuntimeError(error)

    # Variables were stored as string literals in the environment, so to use
    # them we need to parse them in a safe manner.
    is_bootstrap = ast.literal_eval(is_bootstrap)
    pid = ast.literal_eval(pid)
    args = ast.literal_eval(spyder_args)
    reset = ast.literal_eval(reset)

    # Enforce the --new-instance flag when running spyder
    if '--new-instance' not in args:
        if is_bootstrap and '--' not in args:
            args = args + ['--', '--new-instance']
        else:
            args.append('--new-instance')

    # Create the arguments needed for resetting
    if '--' in args:
        args_reset = ['--', '--reset']
    else:
        args_reset = ['--reset']

    # Arrange arguments to be passed to the restarter and reset subprocess
    args = ' '.join(args)
    args_reset = ' '.join(args_reset)

    # Get python executable running this script
    python = sys.executable

    # Build the command
    if is_bootstrap:
        spyder = osp.join(spyder_folder, 'bootstrap.py')
    else:
        spyderdir = osp.join(spyder_folder, 'spyder')
        spyder = osp.join(spyderdir, 'app', 'start.py')

    command = '"{0}" "{1}" {2}'.format(python, spyder, args)

    # Adjust the command and/or arguments to subprocess depending on the OS
    shell = not IS_WINDOWS

    # Before launching a new Spyder instance we need to make sure that the
    # previous one has closed. We wait for a fixed and "reasonable" amount of
    # time and check, otherwise an error is launched
    wait_time = 90 if IS_WINDOWS else 30  # Seconds
    for counter in range(int(wait_time / SLEEP_TIME)):
        if not is_pid_running(pid):
            break
        time.sleep(SLEEP_TIME)  # Throttling control
        QApplication.processEvents()  # Needed to refresh the splash
    else:
        # The old spyder instance took too long to close and restart aborts
        restarter.launch_error_message(error_type=CLOSE_ERROR)

    env = os.environ.copy()

    # Reset Spyder (if required)
    # -------------------------------------------------------------------------
    if reset:
        restarter.set_splash_message(_('Resetting Spyder to defaults'))
        command_reset = '"{0}" "{1}" {2}'.format(python, spyder, args_reset)

        try:
            p = subprocess.Popen(command_reset, shell=shell, env=env)
        except Exception as error:
            restarter.launch_error_message(error_type=RESET_ERROR, error=error)
        else:
            p.communicate()
            pid_reset = p.pid

        # Before launching a new Spyder instance we need to make sure that the
        # reset subprocess has closed. We wait for a fixed and "reasonable"
        # amount of time and check, otherwise an error is launched.
        wait_time = 20  # Seconds
        for counter in range(int(wait_time / SLEEP_TIME)):
            if not is_pid_running(pid_reset):
                break
            time.sleep(SLEEP_TIME)  # Throttling control
            QApplication.processEvents()  # Needed to refresh the splash
        else:
            # The reset subprocess took too long and it is killed
            try:
                p.kill()
            except OSError as error:
                restarter.launch_error_message(error_type=RESET_ERROR,
                                               error=error)
            else:
                restarter.launch_error_message(error_type=RESET_ERROR)

    # Restart
    # -------------------------------------------------------------------------
    restarter.set_splash_message(_('Restarting'))
    try:
        subprocess.Popen(command, shell=shell, env=env)
    except Exception as error:
        restarter.launch_error_message(error_type=RESTART_ERROR, error=error)
Exemplo n.º 27
0
        logging.debug(e)
        total = "Error"

    return {'mean': spectrum.flux.mean(),
            'median': np.median(spectrum.flux),
            'stddev': spectrum.flux.std(),
            'centroid': cent,
            'snr': snr_val,
            'fwhm': fwhm_val,
            'ew': ew,
            'total': total,
            'maxval': spectrum.flux.max(),
            'minval': spectrum.flux.min()}


@plugin.plugin_bar("Statistics", icon=QIcon(":/icons/012-file.svg"), priority=1)
class StatisticsWidget(QWidget):
    """
    This widget controls the statistics box. It is responsible for calling
    stats computation functions and updating the stats widget. It only takes
    the owner workspace's current data item and selected region for stats
    computations. The stats box can be updated by calling the update_statistics
    function.
    """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._current_spectrum = None  # Current `Spectrum1D`
        self._current_plot_item = None  # Current plot item
        self.stats = None  # dict with stats

        self._init_ui()
Exemplo n.º 28
0
def get_icon(name, default=None, resample=False):
    """Return image inside a QIcon object.

    default: default image name or icon
    resample: if True, manually resample icon pixmaps for usual sizes
    (16, 24, 32, 48, 96, 128, 256). This is recommended for QMainWindow icons
    created from SVG images on non-Windows platforms due to a Qt bug.
    See spyder-ide/spyder#1314.
    """

    icon_path = get_image_path(name, default=None)
    if icon_path is not None:
        icon = QIcon(icon_path)
    elif isinstance(default, QIcon):
        icon = default
    elif default is None:
        try:
            icon = get_std_icon(name[:-4])
        except AttributeError:
            icon = QIcon(get_image_path(name, default))
    else:
        icon = QIcon(get_image_path(name, default))
    if resample:
        icon0 = QIcon()
        for size in (16, 24, 32, 48, 96, 128, 256, 512):
            icon0.addPixmap(icon.pixmap(size, size))
        return icon0
    else:
        return icon
Exemplo n.º 29
0
    def __init__(self, parent=None):
        super().__init__(parent)
        self._ui = locSaveClass()
        self._ui.setupUi(self)

        self._ui.saveButton.setIcon(QIcon.fromTheme("document-save"))
Exemplo n.º 30
0
    def __init__(
        self, config_folder=CONFIG_FOLDER, title="PartSeg", settings=None, signal_fun=None, initial_image=None
    ):
        super().__init__(config_folder, title, settings, io_functions.load_dict, signal_fun)
        self.channel_info = "channelcontrol"
        self.channel_control = ChannelProperty(self.settings, start_name="channelcontrol")
        self.image_view = StackImageView(self.settings, self.channel_control, name="channelcontrol")
        self.image_view.setMinimumWidth(450)
        self.info_text = QLabel()
        self.info_text.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)
        self.image_view.text_info_change.connect(self.info_text.setText)
        self.options_panel = Options(self.settings, self.image_view)
        self.main_menu = MainMenu(self.settings, self)
        self.main_menu.image_loaded.connect(self.image_read)
        self.settings.image_changed.connect(self.image_read)
        self.color_bar = ColorBar(self.settings, self.image_view)
        self.multiple_files = MultipleFileWidget(self.settings, io_functions.load_dict)
        self.multiple_files.setVisible(self.options_panel.image_properties.multiple_files.isChecked())
        self.options_panel.algorithm_options.batch_process.multiple_result.connect(
            partial(self.multiple_files.save_state_action, custom_name=False)
        )

        icon = QIcon(os.path.join(PartSegData.icons_dir, "icon_stack.png"))
        self.setWindowIcon(icon)

        menu_bar = self.menuBar()
        file_menu = menu_bar.addMenu("File")
        file_menu.addAction("&Open").triggered.connect(self.main_menu.load_image)
        file_menu.addMenu(self.recent_file_menu)
        file_menu.addAction("&Save segmentation").triggered.connect(self.main_menu.save_segmentation)
        file_menu.addAction("&Save components").triggered.connect(self.main_menu.save_result)
        view_menu = menu_bar.addMenu("View")
        view_menu.addAction("Settings and Measurement").triggered.connect(self.main_menu.show_advanced_window)
        view_menu.addAction("Additional output").triggered.connect(self.additional_layers_show)
        view_menu.addAction("Additional output with data").triggered.connect(lambda: self.additional_layers_show(True))
        view_menu.addAction("Napari viewer").triggered.connect(self.napari_viewer_show)
        view_menu.addAction("Toggle Multiple Files").triggered.connect(self.toggle_multiple_files)
        action = view_menu.addAction("Screenshot")
        action.triggered.connect(self.screenshot(self.image_view))
        action.setShortcut(QKeySequence.Print)
        image_menu = menu_bar.addMenu("Image operations")
        image_menu.addAction("Image adjustment").triggered.connect(self.image_adjust_exec)
        help_menu = menu_bar.addMenu("Help")
        help_menu.addAction("State directory").triggered.connect(self.show_settings_directory)
        help_menu.addAction("About").triggered.connect(self.show_about_dialog)

        layout = QVBoxLayout()
        layout.addWidget(self.main_menu)
        sub_layout = QHBoxLayout()
        sub2_layout = QVBoxLayout()
        sub3_layout = QVBoxLayout()
        sub_layout.addWidget(self.multiple_files)
        sub_layout.addWidget(self.color_bar, 0)
        sub3_layout.addWidget(self.image_view, 1)
        sub3_layout.addWidget(self.info_text, 0)
        sub2_layout.addWidget(self.options_panel, 1)
        sub2_layout.addWidget(self.channel_control, 0)

        sub_layout.addLayout(sub3_layout, 1)
        sub_layout.addLayout(sub2_layout, 0)
        layout.addLayout(sub_layout)
        self.widget = QWidget()
        self.widget.setLayout(layout)
        self.setCentralWidget(self.widget)
        if initial_image is None:
            reader = TiffImageReader()
            im = reader.read(self.initial_image_path)
            im.file_path = ""
            self.settings.image = im
        elif initial_image is False:
            # FIXME This is for test opening
            pass
        else:
            self.settings.image = initial_image
        try:
            geometry = self.settings.get_from_profile("main_window_geometry")
            self.restoreGeometry(QByteArray.fromHex(bytes(geometry, "ascii")))
        except KeyError:
            pass
Exemplo n.º 31
0
    def __init__(self, model):
        """Initialize MNELAB main window.

        Parameters
        ----------
        model : mnelab.model.Model instance
            The main window needs to connect to a model containing all data
            sets. This decouples the GUI from the data (model/view).
        """
        super().__init__()
        self.model = model  # data model
        self.setWindowTitle("MNELAB")

        # restore settings
        settings = read_settings()
        self.recent = settings["recent"]  # list of recent files
        self.resize(settings["size"])
        self.move(settings["pos"])

        # trigger theme setting
        QIcon.setThemeSearchPaths([str(Path(__file__).parent / "icons")])
        self.event(QEvent(QEvent.PaletteChange))

        self.actions = {}  # contains all actions

        # initialize menus
        file_menu = self.menuBar().addMenu("&File")
        icon = QIcon.fromTheme("open-file")
        self.actions["open_file"] = file_menu.addAction(
            icon, "&Open...", self.open_data, QKeySequence.Open)
        self.recent_menu = file_menu.addMenu("Open recent")
        self.recent_menu.aboutToShow.connect(self._update_recent_menu)
        self.recent_menu.triggered.connect(self._load_recent)
        if not self.recent:
            self.recent_menu.setEnabled(False)
        self.actions["close_file"] = file_menu.addAction(
            "&Close", self.model.remove_data, QKeySequence.Close)
        self.actions["close_all"] = file_menu.addAction(
            "Close all", self.close_all)
        file_menu.addSeparator()
        icon = QIcon.fromTheme("meta-info")
        self.actions["meta_info"] = file_menu.addAction(
            icon, "Show information...", self.meta_info)
        file_menu.addSeparator()
        self.actions["import_bads"] = file_menu.addAction(
            "Import bad channels...", lambda: self.import_file(
                model.import_bads, "Import bad channels", "*.csv"))
        self.actions["import_events"] = file_menu.addAction(
            "Import events...", lambda: self.import_file(
                model.import_events, "Import events", "*.csv"))
        self.actions["import_annotations"] = file_menu.addAction(
            "Import annotations...", lambda: self.import_file(
                model.import_annotations, "Import annotations", "*.csv"))
        self.actions["import_ica"] = file_menu.addAction(
            "Import &ICA...", lambda: self.open_file(
                model.import_ica, "Import ICA", "*.fif *.fif.gz"))
        file_menu.addSeparator()
        self.export_menu = file_menu.addMenu("Export data")
        for ext, description in writers.items():
            action = "export_data" + ext.replace(".", "_")
            self.actions[action] = self.export_menu.addAction(
                f"{ext[1:].upper()} ({description[1]})...",
                partial(self.export_file, model.export_data, "Export data",
                        ext))
        self.actions["export_bads"] = file_menu.addAction(
            "Export &bad channels...", lambda: self.export_file(
                model.export_bads, "Export bad channels", "*.csv"))
        self.actions["export_events"] = file_menu.addAction(
            "Export &events...", lambda: self.export_file(
                model.export_events, "Export events", "*.csv"))
        self.actions["export_annotations"] = file_menu.addAction(
            "Export &annotations...", lambda: self.export_file(
                model.export_annotations, "Export annotations", "*.csv"))
        self.actions["export_ica"] = file_menu.addAction(
            "Export ICA...", lambda: self.export_file(
                model.export_ica, "Export ICA", "*.fif *.fif.gz"))
        file_menu.addSeparator()
        self.actions["quit"] = file_menu.addAction("&Quit", self.close,
                                                   QKeySequence.Quit)

        edit_menu = self.menuBar().addMenu("&Edit")
        self.actions["pick_chans"] = edit_menu.addAction(
            "P&ick channels...", self.pick_channels)
        icon = QIcon.fromTheme("chan-props")
        self.actions["chan_props"] = edit_menu.addAction(
            icon, "Channel &properties...", self.channel_properties)
        self.actions["set_montage"] = edit_menu.addAction(
            "Set &montage...", self.set_montage)
        edit_menu.addSeparator()
        self.actions["set_ref"] = edit_menu.addAction("Set &reference...",
                                                      self.set_reference)
        edit_menu.addSeparator()
        self.actions["annotations"] = edit_menu.addAction(
            "&Annotations...", self.edit_annotations)
        self.actions["events"] = edit_menu.addAction("&Events...",
                                                     self.edit_events)

        edit_menu.addSeparator()
        self.actions["crop"] = edit_menu.addAction("&Crop data...", self.crop)
        self.actions["append_data"] = edit_menu.addAction(
            "Appen&d data...", self.append_data)

        plot_menu = self.menuBar().addMenu("&Plot")
        icon = QIcon.fromTheme("plot-data")
        self.actions["plot_data"] = plot_menu.addAction(
            icon, "&Data...", self.plot_data)
        icon = QIcon.fromTheme("plot-psd")
        self.actions["plot_psd"] = plot_menu.addAction(
            icon, "&Power spectral density...", self.plot_psd)
        icon = QIcon.fromTheme("plot-locations")
        self.actions["plot_locations"] = plot_menu.addAction(
            icon, "&Channel locations...", self.plot_locations)
        self.actions["plot_erds"] = plot_menu.addAction(
            "&ERDS maps...", self.plot_erds)
        plot_menu.addSeparator()
        self.actions["plot_ica_components"] = plot_menu.addAction(
            "ICA &components...", self.plot_ica_components)
        self.actions["plot_ica_sources"] = plot_menu.addAction(
            "ICA &sources...", self.plot_ica_sources)

        tools_menu = self.menuBar().addMenu("&Tools")
        icon = QIcon.fromTheme("filter-data")
        self.actions["filter"] = tools_menu.addAction(icon, "&Filter data...",
                                                      self.filter_data)
        icon = QIcon.fromTheme("find-events")
        self.actions["find_events"] = tools_menu.addAction(
            icon, "Find &events...", self.find_events)
        self.actions["events_from_annotations"] = tools_menu.addAction(
            "Create events from annotations", self.events_from_annotations)
        self.actions["annotations_from_events"] = tools_menu.addAction(
            "Create annotations from events", self.annotations_from_events)
        tools_menu.addSeparator()
        nirs_menu = tools_menu.addMenu("NIRS")
        self.actions["convert_od"] = nirs_menu.addAction(
            "Convert to &optical density", self.convert_od)
        self.actions["convert_bl"] = nirs_menu.addAction(
            "Convert to &haemoglobin", self.convert_bl)

        tools_menu.addSeparator()
        icon = QIcon.fromTheme("run-ica")
        self.actions["run_ica"] = tools_menu.addAction(icon, "Run &ICA...",
                                                       self.run_ica)
        self.actions["apply_ica"] = tools_menu.addAction(
            "Apply &ICA", self.apply_ica)
        tools_menu.addSeparator()
        self.actions["interpolate_bads"] = tools_menu.addAction(
            "Interpolate bad channels...", self.interpolate_bads)
        tools_menu.addSeparator()
        icon = QIcon.fromTheme("epoch-data")
        self.actions["epoch_data"] = tools_menu.addAction(
            icon, "Create Epochs...", self.epoch_data)

        view_menu = self.menuBar().addMenu("&View")
        self.actions["history"] = view_menu.addAction("&History...",
                                                      self.show_history)
        self.actions["toolbar"] = view_menu.addAction("&Toolbar",
                                                      self._toggle_toolbar)
        self.actions["toolbar"].setCheckable(True)
        self.actions["statusbar"] = view_menu.addAction(
            "&Statusbar", self._toggle_statusbar)
        self.actions["statusbar"].setCheckable(True)

        help_menu = self.menuBar().addMenu("&Help")
        self.actions["about"] = help_menu.addAction("&About", self.show_about)
        self.actions["about_qt"] = help_menu.addAction("About &Qt",
                                                       self.show_about_qt)

        # actions that are always enabled
        self.always_enabled = [
            "open_file", "about", "about_qt", "quit", "toolbar", "statusbar"
        ]

        # set up toolbar
        self.toolbar = self.addToolBar("toolbar")
        self.toolbar.setObjectName("toolbar")
        self.toolbar.addAction(self.actions["open_file"])
        self.toolbar.addAction(self.actions["meta_info"])
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.actions["chan_props"])
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.actions["plot_data"])
        self.toolbar.addAction(self.actions["plot_psd"])
        self.toolbar.addAction(self.actions["plot_locations"])
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.actions["filter"])
        self.toolbar.addAction(self.actions["find_events"])
        self.toolbar.addAction(self.actions["epoch_data"])
        self.toolbar.addAction(self.actions["run_ica"])

        self.setUnifiedTitleAndToolBarOnMac(True)
        if settings["toolbar"]:
            self.toolbar.show()
            self.actions["toolbar"].setChecked(True)
        else:
            self.toolbar.hide()
            self.actions["toolbar"].setChecked(False)

        # set up data model for sidebar (list of open files)
        self.names = QStringListModel()
        self.names.dataChanged.connect(self._update_names)
        splitter = QSplitter()
        self.sidebar = QListView()
        self.sidebar.setFrameStyle(QFrame.NoFrame)
        self.sidebar.setFocusPolicy(Qt.NoFocus)
        self.sidebar.setModel(self.names)
        self.sidebar.clicked.connect(self._update_data)
        splitter.addWidget(self.sidebar)
        self.infowidget = InfoWidget()
        splitter.addWidget(self.infowidget)
        width = splitter.size().width()
        splitter.setSizes((int(width * 0.3), int(width * 0.7)))
        self.setCentralWidget(splitter)

        self.status_label = QLabel()
        self.statusBar().addPermanentWidget(self.status_label)
        if settings["statusbar"]:
            self.statusBar().show()
            self.actions["statusbar"].setChecked(True)
        else:
            self.statusBar().hide()
            self.actions["statusbar"].setChecked(False)

        self.setAcceptDrops(True)
        self.data_changed()
Exemplo n.º 32
0
def config_dialog(qtbot, request, mocker):
    mocker.patch.object(ima, 'icon', lambda x, icon_path=None: QIcon())
    dlg = ConfigDialogTester(request.param)
    qtbot.addWidget(dlg)
    dlg.show()
    return dlg
Exemplo n.º 33
0
    def __init__(self, name, plugin, parent=None, options=DEFAULT_OPTIONS):
        super().__init__(parent=parent)

        # Attributes
        # --------------------------------------------------------------------
        self._options = options
        self._is_tab = False
        self._name = name
        self._plugin = plugin
        self._parent = parent
        self._default_margins = None
        self.is_maximized = None
        self.is_visible = None
        self.dock_action = None
        self.undock_action = None
        self.close_action = None
        self._toolbars_already_rendered = False

        # We create our toggle action instead of using the one that comes with
        # dockwidget because it was not possible to raise and focus the plugin
        self.toggle_view_action = None
        self._toolbars = OrderedDict()
        self._auxiliary_toolbars = OrderedDict()

        # Widgets
        # --------------------------------------------------------------------
        self.windowwidget = None
        self.dockwidget = None
        self._icon = QIcon()
        self._spinner = None

        if self.ENABLE_SPINNER:
            self._spinner = create_waitspinner(size=16, parent=self)

        self._corner_widget = MainCornerWidget(
            parent=self,
            name=PluginMainWidgetWidgets.CornerWidget,
        )

        self._main_toolbar = MainWidgetToolbar(
            parent=self,
            title=_("Main widget toolbar"),
        )
        self._main_toolbar.ID = 'main_toolbar'
        self._corner_toolbar = MainWidgetToolbar(
            parent=self,
            title=_("Main widget corner toolbar"),
        )
        self._corner_toolbar.ID = 'corner_toolbar',
        self._corner_toolbar.setSizePolicy(QSizePolicy.Minimum,
                                           QSizePolicy.Expanding)
        self._options_menu = self.create_menu(
            PluginMainWidgetMenus.Options,
            title=_('Options menu'),
        )

        # Layout
        # --------------------------------------------------------------------
        self._main_layout = QVBoxLayout()
        self._toolbars_layout = QVBoxLayout()
        self._main_toolbar_layout = QHBoxLayout()

        self._toolbars_layout.setContentsMargins(0, 0, 0, 0)
        self._toolbars_layout.setSpacing(0)
        self._main_toolbar_layout.setContentsMargins(0, 0, 0, 0)
        self._main_toolbar_layout.setSpacing(0)
        self._main_layout.setContentsMargins(0, 0, 0, 0)
        self._main_layout.setSpacing(0)

        # Add inititals layouts
        self._main_toolbar_layout.addWidget(self._main_toolbar, stretch=10000)
        self._main_toolbar_layout.addWidget(self._corner_toolbar, stretch=1)
        self._toolbars_layout.addLayout(self._main_toolbar_layout)
        self._main_layout.addLayout(self._toolbars_layout, stretch=1)
Exemplo n.º 34
0
    def context_menu_requested(self, event, right_click=False):
        """Custom context menu."""
        if self.proxy_model is None:
            return

        self._menu = QMenu(self)
        left_click = not right_click
        index = self.currentIndex()
        model_index = self.proxy_model.mapToSource(index)
        row_data = self.source_model.row(model_index.row())
        column = model_index.column()
        name = row_data[C.COL_NAME]
        # package_type = row_data[C.COL_PACKAGE_TYPE]
        versions = self.source_model.get_package_versions(name)
        current_version = self.source_model.get_package_version(name)
        action_version = row_data[C.COL_ACTION_VERSION]
        package_status = row_data[C.COL_STATUS]
        package_type = row_data[C.COL_PACKAGE_TYPE]

        remove_actions = bool(self.source_model.count_remove_actions())
        install_actions = bool(self.source_model.count_install_actions())

        if column in [C.COL_ACTION] and left_click:
            is_installable = self.source_model.is_installable(model_index)
            is_removable = self.source_model.is_removable(model_index)
            is_upgradable = self.source_model.is_upgradable(model_index)

            action_status = self.source_model.action_status(model_index)
            actions = []
            action_unmark = create_action(
                self,
                _('Unmark'),
                triggered=lambda: self.set_action_status(
                    model_index, C.ACTION_NONE, current_version))
            action_install = create_action(
                self,
                _('Mark for installation'),
                toggled=lambda: self.set_action_status(model_index, C.
                                                       ACTION_INSTALL))
            action_upgrade = create_action(
                self,
                _('Mark for upgrade'),
                toggled=lambda: self.set_action_status(
                    model_index, C.ACTION_UPGRADE, versions[-1]))
            action_remove = create_action(
                self,
                _('Mark for removal'),
                toggled=lambda: self.set_action_status(
                    model_index, C.ACTION_REMOVE, current_version))
            version_actions = []
            for version in reversed(versions):

                def trigger(model_index=model_index,
                            action=C.ACTION_INSTALL,
                            version=version):
                    return lambda: self.set_action_status(
                        model_index, status=action, version=version)

                if version == current_version:
                    version_action = create_action(
                        self,
                        version,
                        icon=QIcon(),
                        triggered=trigger(model_index, C.ACTION_INSTALL,
                                          version))
                    if not is_installable:
                        version_action.setCheckable(True)
                        version_action.setChecked(True)
                        version_action.setDisabled(True)
                elif version != current_version:
                    if ((version in versions and versions.index(version)) >
                        (current_version in versions
                         and versions.index(current_version))):
                        upgrade_or_downgrade_action = C.ACTION_UPGRADE
                    else:
                        upgrade_or_downgrade_action = C.ACTION_DOWNGRADE

                    if is_installable:
                        upgrade_or_downgrade_action = C.ACTION_INSTALL

                    version_action = create_action(
                        self,
                        version,
                        icon=QIcon(),
                        triggered=trigger(model_index,
                                          upgrade_or_downgrade_action,
                                          version))
                if action_version == version:
                    version_action.setCheckable(True)
                    version_action.setChecked(True)

                version_actions.append(version_action)

            install_versions_menu = QMenu(
                'Mark for specific version '
                'installation', self)
            add_actions(install_versions_menu, version_actions)
            actions = [
                action_unmark, action_install, action_upgrade, action_remove
            ]
            actions += [None, install_versions_menu]

            # Disable firing of signals, while setting the checked status
            for ac in actions + version_actions:
                if ac:
                    ac.blockSignals(True)

            if action_status == C.ACTION_NONE:
                action_unmark.setEnabled(False)
                action_install.setEnabled(is_installable)
                action_upgrade.setEnabled(is_upgradable)
                action_remove.setEnabled(is_removable)

                if install_actions:
                    # Invalidate remove if install actions already selected
                    action_remove.setDisabled(True)
                elif remove_actions:
                    # Invalidate install if remove actions already selected
                    action_install.setDisabled(True)
                    action_upgrade.setDisabled(True)

                install_versions_menu.setDisabled(False)
            elif action_status == C.ACTION_INSTALL:
                action_unmark.setEnabled(True)
                action_install.setEnabled(False)
                action_install.setChecked(True)
                action_upgrade.setEnabled(False)
                action_remove.setEnabled(False)
            elif action_status == C.ACTION_REMOVE:
                action_unmark.setEnabled(True)
                action_install.setEnabled(False)
                action_upgrade.setEnabled(False)
                action_remove.setEnabled(False)
                action_remove.setChecked(True)
            elif action_status == C.ACTION_UPGRADE:
                action_unmark.setEnabled(True)
                action_install.setEnabled(False)
                action_upgrade.setEnabled(False)
                action_upgrade.setChecked(True)
                action_remove.setEnabled(False)
            elif action_status == C.ACTION_DOWNGRADE:
                action_unmark.setEnabled(True)
                action_install.setEnabled(False)
                action_upgrade.setEnabled(False)
                action_upgrade.setChecked(False)
                action_remove.setEnabled(False)

            if package_status == C.NOT_INSTALLED:
                action_remove.setEnabled(False)
                action_upgrade.setEnabled(False)

            if package_type == C.PIP_PACKAGE:
                action_unmark.setEnabled(False)
                action_install.setEnabled(False)
                action_upgrade.setEnabled(False)
                action_remove.setEnabled(False)

            # Enable firing of signals, while setting the checked status
            for ac in actions + version_actions:
                if ac:
                    ac.blockSignals(False)

                install_versions_menu.setDisabled(True)

            install_versions_menu.setEnabled(
                len(version_actions) > 1 and not remove_actions)
        elif right_click:
            license_ = row_data[C.COL_LICENSE]

            metadata = self.metadata_links.get(name, {})
            pypi = metadata.get('pypi', '')
            home = metadata.get('home', '')
            dev = metadata.get('dev', '')
            docs = metadata.get('docs', '')

            q_pypi = QIcon(get_image_path('python.png'))
            q_home = QIcon(get_image_path('home.png'))
            q_docs = QIcon(get_image_path('conda_docs.png'))

            if 'git' in dev:
                q_dev = QIcon(get_image_path('conda_github.png'))
            elif 'bitbucket' in dev:
                q_dev = QIcon(get_image_path('conda_bitbucket.png'))
            else:
                q_dev = QIcon()

            if 'mit' in license_.lower():
                lic = 'http://opensource.org/licenses/MIT'
            elif 'bsd' == license_.lower():
                lic = 'http://opensource.org/licenses/BSD-3-Clause'
            else:
                lic = None

            actions = []

            if license_ != '':
                actions.append(
                    create_action(self,
                                  _('License: ' + license_),
                                  icon=QIcon(),
                                  triggered=lambda: self.open_url(lic)))
                actions.append(None)

            if pypi != '':
                actions.append(
                    create_action(self,
                                  _('Python Package Index'),
                                  icon=q_pypi,
                                  triggered=lambda: self.open_url(pypi)))
            if home != '':
                actions.append(
                    create_action(self,
                                  _('Homepage'),
                                  icon=q_home,
                                  triggered=lambda: self.open_url(home)))
            if docs != '':
                actions.append(
                    create_action(self,
                                  _('Documentation'),
                                  icon=q_docs,
                                  triggered=lambda: self.open_url(docs)))
            if dev != '':
                actions.append(
                    create_action(self,
                                  _('Development'),
                                  icon=q_dev,
                                  triggered=lambda: self.open_url(dev)))
        if actions and len(actions) > 1:
            # self._menu = QMenu(self)
            add_actions(self._menu, actions)

            if event.type() == QEvent.KeyRelease:
                rect = self.visualRect(index)
                global_pos = self.viewport().mapToGlobal(rect.bottomRight())
            else:
                pos = QPoint(event.x(), event.y())
                global_pos = self.viewport().mapToGlobal(pos)

            self._menu.popup(global_pos)
Exemplo n.º 35
0
    def __init__(
        self,
        *,
        title='napari',
        ndisplay=2,
        order=None,
        axis_labels=None,
        show=True,
    ):
        # instance() returns the singleton instance if it exists, or None
        app = QApplication.instance()
        # if None, raise a RuntimeError with the appropriate message
        if app is None:
            message = (
                "napari requires a Qt event loop to run. To create one, "
                "try one of the following: \n"
                "  - use the `napari.gui_qt()` context manager. See "
                "https://github.com/napari/napari/tree/master/examples for"
                " usage examples.\n"
                "  - In IPython or a local Jupyter instance, use the "
                "`%gui qt` magic command.\n"
                "  - Launch IPython with the option `--gui=qt`.\n"
                "  - (recommended) in your IPython configuration file, add"
                " or uncomment the line `c.TerminalIPythonApp.gui = 'qt'`."
                " Then, restart IPython.")
            raise RuntimeError(message)

        if perf_config:
            if perf_config.trace_qt_events:
                from ._qt.qt_event_tracing import convert_app_for_tracing

                # For tracing Qt events we need a special QApplication. If
                # using `gui_qt` we already have the special one, and no
                # conversion is done here. However when running inside
                # IPython or Jupyter this is where we switch out the
                # QApplication.
                app = convert_app_for_tracing(app)

            # Will patch based on config file.
            perf_config.patch_callables()

        if (platform.system() == "Windows"
                and not getattr(sys, 'frozen', False) and self._napari_app_id):
            import ctypes

            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
                self._napari_app_id)

        logopath = join(dirname(__file__), 'resources', 'logo.png')
        app.setWindowIcon(QIcon(logopath))

        # see docstring of `wait_for_workers_to_quit` for caveats on killing
        # workers at shutdown.
        app.aboutToQuit.connect(wait_for_workers_to_quit)

        super().__init__(
            title=title,
            ndisplay=ndisplay,
            order=order,
            axis_labels=axis_labels,
        )
        qt_viewer = QtViewer(self)
        self.window = Window(qt_viewer, show=show)
Exemplo n.º 36
0
def getIcon(name):
    if not QIcon.hasThemeIcon(name):
        warnings.warn('Unknown icon theme: %s' % name)
        return QIcon()
    return QIcon.fromTheme(name)
Exemplo n.º 37
0
    def __init__(self, label_file=None):
        super(MainWindow, self).__init__()
        self.showMaximized()
        self.setWindowTitle("VTCC.Labelling")

        self.file_dirs = []
        self.file_id = -1
        self.labels = []
        with open(label_file, 'r') as f:
            lines = f.read().splitlines()
            for label in lines:
                self.labels.append(label)

        # RIGHT DOCK
        self.label_dock = QDockWidget("Label List", self)
        self.label_list_widget = QListWidget(self)
        self.load_labels(label_file)
        self.label_dock.setWidget(self.label_list_widget)

        self.object_dock = QDockWidget("Object List", self)
        self.object_list_widget = QListWidget(self)
        self.object_list_widget.currentRowChanged.connect(self.change_object)
        self.object_dock.setWidget(self.object_list_widget)

        self.file_dock = QDockWidget("File List", self)
        self.file_list_widget = QListWidget(self)
        self.file_list_widget.currentRowChanged.connect(self.change_file)
        self.file_dock.setWidget(self.file_list_widget)

        self.addDockWidget(Qt.RightDockWidgetArea, self.label_dock)
        self.addDockWidget(Qt.RightDockWidgetArea, self.object_dock)
        self.addDockWidget(Qt.RightDockWidgetArea, self.file_dock)

        # MAIN CANVAS
        self.canvas = Canvas(self)

        self.canvas_area = QScrollArea()
        self.canvas_area.setWidget(self.canvas)
        self.canvas_area.setWidgetResizable(True)
        self.scrollBars = {
            Qt.Vertical: self.canvas_area.verticalScrollBar(),
            Qt.Horizontal: self.canvas_area.horizontalScrollBar(),
        }
        self.setCentralWidget(self.canvas_area)

        # LEFT DOCK
        self.open_action = QAction(QIcon('icons/open.png'), 'Open File', self)
        self.open_action.triggered.connect(self.open_file)
        self.open_action.setShortcut(QKeySequence("Ctrl+O"))
        self.open_dir_action = QAction(QIcon('icons/open.png'), 'Open Dir',
                                       self)
        self.open_dir_action.triggered.connect(self.open_dir)

        self.next_img_action = QAction(QIcon('icons/next.png'), 'Next Image',
                                       self)
        self.next_img_action.triggered.connect(self.next_img)
        self.next_img_action.setShortcut(QKeySequence("Right"))
        self.prev_img_action = QAction(QIcon('icons/prev.png'), 'Prev Image',
                                       self)
        self.prev_img_action.triggered.connect(self.prev_img)
        self.prev_img_action.setShortcut(QKeySequence("Left"))

        self.zoom_in_action = QAction(QIcon('icons/zoom-in.png'), 'Zoom In',
                                      self)
        self.zoom_in_action.triggered.connect(self.zoom_in)
        self.zoom_out_action = QAction(QIcon('icons/zoom-out.png'), 'Zoom Out',
                                       self)
        self.zoom_out_action.triggered.connect(self.zoom_out)
        self.zoom_org_action = QAction(QIcon('icons/fit-window.png'),
                                       'Fit Window', self)
        self.zoom_org_action.triggered.connect(self.zoom_org)

        self.rectangle_action = QAction(QIcon('icons/objects.png'),
                                        'New Rectangle', self)
        self.rectangle_action.triggered.connect(self.new_rectangle)
        self.auto_polygon_action = QAction(QIcon('icons/objects.png'),
                                           'New Auto-Polygon', self)
        self.auto_polygon_action.triggered.connect(self.new_auto_polygon)
        self.polygon_action = QAction(QIcon('icons/objects.png'),
                                      'New Polygon', self)
        self.polygon_action.triggered.connect(self.new_polygon)

        self.next_obj_action = QAction(QIcon('icons/next.png'), 'Next Object',
                                       self)
        self.next_obj_action.triggered.connect(self.canvas.next_obj)
        self.next_obj_action.setShortcut(QKeySequence("Down"))
        self.prev_obj_action = QAction(QIcon('icons/prev.png'), 'Prev Object',
                                       self)
        self.prev_obj_action.triggered.connect(self.canvas.prev_obj)
        self.prev_obj_action.setShortcut(QKeySequence("Up"))
        self.del_obj_action = QAction(QIcon('icons/delete.png'),
                                      'Delete Object', self)
        self.del_obj_action.triggered.connect(self.canvas.del_obj)
        self.del_obj_action.setShortcut(QKeySequence("Del"))

        self.toolbar = QToolBar(self)
        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.toolbar.addAction(self.open_action)
        self.toolbar.addAction(self.open_dir_action)
        self.toolbar.addAction(self.next_img_action)
        self.toolbar.addAction(self.prev_img_action)
        # self.toolbar.addAction(self.zoom_in_action)
        # self.toolbar.addAction(self.zoom_out_action)
        # self.toolbar.addAction(self.zoom_org_action)
        self.toolbar.addAction(self.rectangle_action)
        self.toolbar.addAction(self.auto_polygon_action)
        self.toolbar.addAction(self.polygon_action)
        self.toolbar.addAction(self.next_obj_action)
        self.toolbar.addAction(self.prev_obj_action)
        self.toolbar.addAction(self.del_obj_action)

        self.addToolBar(Qt.LeftToolBarArea, self.toolbar)

        self.scalers = {
            self.FIT_WINDOW:
            self.scaleFitWindow,
            self.FIT_WIDTH:
            self.scaleFitWidth,
            # Set to one to scale to 100% when loading files.
            self.MANUAL_ZOOM:
            lambda: 1,
        }