Beispiel #1
0
    def update_widget_state(self, condition=None):
        # Update the state of the menu bar
        state = not self.gui_vars["gui_state"]["running_computations"]
        self.menuBar().setEnabled(state)

        state_computations = self.gui_vars["gui_state"]["running_computations"]
        if state_computations:
            if not self._cursor_set:
                QGuiApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                self._cursor_set = True
        else:
            if self._cursor_set:
                QGuiApplication.restoreOverrideCursor()
                self._cursor_set = False

        # Forward to children
        self.central_widget.update_widget_state(condition)

        # Forward the updates to open windows
        self.wnd_manage_emission_lines.update_widget_state(condition)
        self.wnd_compute_roi_maps.update_widget_state(condition)
        self.wnd_image_wizard.update_widget_state(condition)
        self.wnd_load_quantitative_calibration.update_widget_state(condition)
        self.wnd_general_fitting_settings.update_widget_state(condition)
        self.wnd_fitting_parameters_shared.update_widget_state(condition)
        self.wnd_fitting_parameters_lines.update_widget_state(condition)
Beispiel #2
0
 def switchToCli(self):
     if config.isHtmlTextInstalled:
         config.pluginContext = self.name
         QGuiApplication.instance().setApplicationName(
             "UniqueBible.app CLI")
         config.pluginContext = ""
     else:
         self.displayMessage(
             "CLI feature is not enabled! \n Install module 'html-text' first, by running 'pip3 install html-text'!"
         )
Beispiel #3
0
def _get_splash_image():
    # gets the width of the screen where the main window was initialised
    width = QGuiApplication.primaryScreen().size().width()
    height = QGuiApplication.primaryScreen().size().height()

    # the proportion of the whole window size for the splash screen
    splash_screen_scaling = 0.25
    return QPixmap(':/images/MantidSplashScreen_4k.jpg').scaled(
        width * splash_screen_scaling, height * splash_screen_scaling,
        Qt.KeepAspectRatio, Qt.SmoothTransformation)
Beispiel #4
0
class Client(QWebEnginePage):
    def __init__(self, url):
        self.app = QGuiApplication(sys.argv)
        QWebEnginePage.__init__(self)
        self.loadFinished.connect(self.on_page_load)
        self.mainFrame().load(QUrl(url))
        self.app.exec_()

    def on_page_load(self):
        self.app.quit()
Beispiel #5
0
def main():
    import sys

    app = QGuiApplication(sys.argv)

    w = PaintedWindow()
    w.create()
    w.show()

    sys.exit(app.exec_())
Beispiel #6
0
def test_qt_viewer_clipboard_without_flash(make_napari_viewer):
    viewer = make_napari_viewer()
    # make sure clipboard is empty
    QGuiApplication.clipboard().clear()
    clipboard_image = QGuiApplication.clipboard().image()
    assert clipboard_image.isNull()

    # capture screenshot
    with pytest.warns(FutureWarning):
        viewer.window.qt_viewer.clipboard(flash=False)

    viewer.window.clipboard(flash=False, canvas_only=True)

    clipboard_image = QGuiApplication.clipboard().image()
    assert not clipboard_image.isNull()

    # ensure the flash effect is not applied
    assert viewer.window._qt_viewer._canvas_overlay.graphicsEffect() is None
    assert not hasattr(viewer.window._qt_viewer._canvas_overlay,
                       "_flash_animation")

    # clear clipboard and grab image from application view
    QGuiApplication.clipboard().clear()
    clipboard_image = QGuiApplication.clipboard().image()
    assert clipboard_image.isNull()

    # capture screenshot of the entire window
    viewer.window.clipboard(flash=False)
    clipboard_image = QGuiApplication.clipboard().image()
    assert not clipboard_image.isNull()

    # ensure the flash effect is not applied
    assert viewer.window._qt_window.graphicsEffect() is None
    assert not hasattr(viewer.window._qt_window, "_flash_animation")
Beispiel #7
0
    def dropEvent(self, event):
        """Add local files and web URLS with drag and drop.

        For each file, attempt to open with existing associated reader
        (if available). If no reader is associated or opening fails,
        and more than one reader is available, open dialog and ask
        user to choose among available readers. User can choose to persist
        this choice.

        Parameters
        ----------
        event : qtpy.QtCore.QEvent
            Event from the Qt context.
        """
        shift_down = QGuiApplication.keyboardModifiers() & Qt.ShiftModifier
        filenames = []
        for url in event.mimeData().urls():
            if url.isLocalFile():
                filenames.append(url.toLocalFile())
            else:
                filenames.append(url.toString())

        # if trying to open as a stack, open with any available reader
        if shift_down:
            self.viewer.open(filenames, stack=bool(shift_down))
            return

        for filename in filenames:
            # get available readers for this file from all registered plugins
            readers = get_potential_readers(filename)
            if not readers:
                warnings.warn(
                    trans._(
                        'No readers found to try reading {filename}.',
                        deferred=True,
                        filename=filename,
                    )
                )
                continue

            # see whether an existing setting can be used
            _, extension = os.path.splitext(filename)
            error_message = self._try_reader_from_settings(
                readers, extension, filename
            )
            # we've successfully opened file, move to the next one
            if error_message is None:
                continue

            # there is no existing setting, or it failed, get choice from user
            readerDialog = QtReaderDialog(
                parent=self,
                pth=filename,
                extension=extension,
                error_message=error_message,
                readers=readers,
            )
            self._get_and_try_preferred_reader(
                readerDialog, readers, error_message
            )
    def __init__(self, items=[], checkedItems=[], toolTips=None, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Set up initial checked items
        self.checkItems = checkedItems

        # Make the combo editable to set a custom text, but readonly
        self.setEditable(True)
        self.lineEdit().setReadOnly(True)
        # Make the lineedit the same color as QPushButton
        palette = QGuiApplication.instance().palette()
        palette.setBrush(QPalette.Base, palette.button())
        self.lineEdit().setPalette(palette)

        # Use custom delegate
        self.setItemDelegate(CheckableComboBox.Delegate())

        # Update the text when an item is toggled
        self.model().dataChanged.connect(self.updateText)

        # Hide and show popup when clicking the line edit
        self.lineEdit().installEventFilter(self)
        self.closeOnLineEditClick = False

        # Prevent popup from closing when clicking on an item
        self.view().viewport().installEventFilter(self)

        # Fill in items
        self.addItems(items, toolTips=toolTips)
def create_screenshots(app, window, is_darkstyle):
    """Save screenshots for different application views and quit."""
    from qtpy.QtCore import QCoreApplication
    from qtpy.QtGui import QGuiApplication
    from qtpy.QtWidgets import QDockWidget, QTabWidget

    theme = 'dark' if is_darkstyle else 'normal'
    print('\nCreating {} screenshots'.format(theme))
    docks = window.findChildren(QDockWidget)
    tabs = window.findChildren(QTabWidget)
    widget_data = {
        'containers_buttons.png': [
            'Containers - No Tabs',
            'Buttons',
        ],
        'containers_tabs_displays.png': [
            'Containers - Tabs',
            'Displays',
        ],
        'views_inputs_no_fields.png': [
            'Views',
            'Inputs - No Fields',
        ],
        'widgets_inputs_fields.png': [
            'Widgets',
            'Inputs - Fields',
        ],
    }
    prefix = 'qdarkstyle_' if is_darkstyle else 'no_dark_'
    screen = QGuiApplication.primaryScreen()
    QCoreApplication.processEvents()
    tab = [tab for tab in tabs if tab.count() >= 12][0]
    tab.setCurrentIndex(11)
    QCoreApplication.processEvents()

    for fname_suffix, widgets in widget_data.items():
        QCoreApplication.processEvents()
        png_path = os.path.join(SCREENSHOTS_PATH, prefix + fname_suffix)
        print('\t' + png_path)

        for dockwidget_name in widgets:
            dockwidget = [dw for dw in docks if dw.windowTitle() == dockwidget_name]
            if dockwidget:
                dockwidget = dockwidget[0]
                dockwidget.show()
                dockwidget.raise_()
                QCoreApplication.processEvents()

            dockwidget = None

        QCoreApplication.processEvents()
        pixmap = screen.grabWindow(window.winId())
        img = pixmap.toImage()
        img.save(png_path)
        QCoreApplication.processEvents()

    window.showNormal()
    QCoreApplication.processEvents()
    print('\n')
    app.exit()
Beispiel #10
0
 def _setup_window_size(self, fraction):
     """Setup default window dimensions"""
     screen = QGuiApplication.primaryScreen()
     geometry = screen.geometry()
     width = geometry.width() * fraction
     height = geometry.height() * fraction
     self.resize(width, height)
Beispiel #11
0
    def dropEvent(self, event):
        """Add local files and web URLS with drag and drop.

        For each file, attempt to open with existing associated reader
        (if available). If no reader is associated or opening fails,
        and more than one reader is available, open dialog and ask
        user to choose among available readers. User can choose to persist
        this choice.

        Parameters
        ----------
        event : qtpy.QtCore.QEvent
            Event from the Qt context.
        """
        shift_down = QGuiApplication.keyboardModifiers() & Qt.ShiftModifier
        filenames = []
        for url in event.mimeData().urls():
            if url.isLocalFile():
                # directories get a trailing "/", Path conversion removes it
                filenames.append(str(Path(url.toLocalFile())))
            else:
                filenames.append(url.toString())

        # if trying to open as a stack, open with any available reader
        if shift_down:
            self._qt_open(filenames, stack=bool(shift_down))
            return

        for filename in filenames:
            self._qt_open([filename], stack=bool(shift_down))
Beispiel #12
0
    def show_dpi_change_message(self, dpi):
        """Show message to restart Spyder since the DPI scale changed."""
        if not self.get_conf('show_dpi_message'):
            return

        if self.current_dpi != dpi:
            # Check the window state to not show the message if the window
            # is in fullscreen mode.
            window = self._window.windowHandle()
            if (window.windowState() == Qt.WindowFullScreen
                    and sys.platform == 'darwin'):
                return

            if self.get_conf('high_dpi_scaling'):
                return

            if self.dpi_messagebox is not None:
                self.dpi_messagebox.activateWindow()
                self.dpi_messagebox.raise_()
                return

            self.dpi_messagebox = MessageCheckBox(icon=QMessageBox.Warning,
                                                  parent=self)

            self.dpi_messagebox.set_checkbox_text(_("Don't show again."))
            self.dpi_messagebox.set_checked(False)
            self.dpi_messagebox.set_check_visible(True)

            self.dpi_messagebox.setText(
                _("A monitor scale change was detected. <br><br>"
                  "We recommend restarting Spyder to ensure that it's properly "
                  "displayed. If you don't want to do that, please be sure to "
                  "activate the option<br><br><tt>Enable auto high DPI scaling"
                  "</tt><br><br>in <tt>Preferences > Application > "
                  "Interface</tt>, in case Spyder is not displayed "
                  "correctly.<br><br>"
                  "Do you want to restart Spyder?"))

            self.dpi_messagebox.addButton(_('Restart now'), QMessageBox.NoRole)
            dismiss_button = self.dpi_messagebox.addButton(
                _('Dismiss'), QMessageBox.NoRole)
            self.dpi_messagebox.setDefaultButton(dismiss_button)
            self.dpi_messagebox.finished.connect(
                lambda result: self.handle_dpi_change_response(result, dpi))
            self.dpi_messagebox.open()

            # Show dialog always in the primary screen to prevent not being
            # able to see it if a screen gets disconnected while
            # in suspended state. See spyder-ide/spyder#16390
            dpi_messagebox_width = self.dpi_messagebox.rect().width()
            dpi_messagebox_height = self.dpi_messagebox.rect().height()
            screen_geometry = QGuiApplication.primaryScreen().geometry()
            x = (screen_geometry.width() - dpi_messagebox_width) / 2
            y = (screen_geometry.height() - dpi_messagebox_height) / 2

            # Convert coordinates to int to avoid a TypeError in Python 3.10
            # Fixes spyder-ide/spyder#17677
            self.dpi_messagebox.move(int(x), int(y))
            self.dpi_messagebox.adjustSize()
Beispiel #13
0
def _get_splash_image_name():
    # gets the width of the screen where the main window was initialised
    width = QGuiApplication.primaryScreen().size().width()

    if width > 2048:
        return ':/images/MantidSplashScreen_4k.jpg'
    else:
        return ':/images/MantidSplashScreen.png'
Beispiel #14
0
def _get_splash_image_name():
    # gets the width of the screen where the main window was initialised
    width = QGuiApplication.primaryScreen().size().width()

    if width > 2048:
        return ':/images/MantidSplashScreen_4k.jpg'
    else:
        return ':/images/MantidSplashScreen.png'
Beispiel #15
0
def main(config):
	# Set default style to "fusion"
	# https://doc.qt.io/qt-5/qtquickcontrols2-styles.html#using-styles-in-qt-quick-controls-2
	#os.environ.setdefault('QT_QUICK_CONTROLS_STYLE', 'fusion')

	qt_app = QGuiApplication(sys.argv)
	qt_app.setOrganizationName("EPFL")
	qt_app.setOrganizationDomain("ch")

	# Init QML
	qml_engine = QQmlApplicationEngine()

	# tell it the location of qml files
	qml_engine.addImportPath(str(DIR_RESOURCES))

	# Register backend classes
	backend = LabelBackend()
	backend.load_config(Path(config))
	backend.set_image_path(DIR_RESOURCES / 'images' / 'test.jpg')
	qml_engine.rootContext().setContextProperty('backend', backend)

	# QML loads image from the backend using an image provider
	qml_engine.addImageProvider('backend', backend.image_provider)

	# Load main window
	qml_engine.load(QUrl.fromLocalFile(str(DIR_RESOURCES / 'main.qml')))

	if qml_engine.rootObjects():
		exit_code = qt_app.exec_()
		del qml_engine
		sys.exit(exit_code)
	else:
		print('QML failed to load')
		sys.exit(1)
Beispiel #16
0
def run(config=None, dir=None):

    try:
        config, start_dir = get_config_and_start_dir(config=config, dir=dir)
        config = config or CONFIG_DEFAULT

        # Set default style to "fusion"
        # https://doc.qt.io/qt-5/qtquickcontrols2-styles.html#using-styles-in-qt-quick-controls-2
        os.environ.setdefault('QT_QUICK_CONTROLS_STYLE', 'Fusion')

        qt_app = QGuiApplication(sys.argv)
        qt_app.setOrganizationName("EPFL")
        qt_app.setOrganizationDomain("ch")

        qt_app.setWindowIcon(QIcon(str(DIR_RESOURCES / 'label-grab-icon.svg')))

        # Init QML
        qml_engine = QQmlApplicationEngine()

        # tell it the location of qml files
        qml_engine.addImportPath(str(DIR_RESOURCES))

        # Register backend classes
        backend = LabelBackend()
        backend.load_config(Path(config))
        backend.set_starting_directory(start_dir)
        backend.set_image_path(DIR_RESOURCES / 'images' / 'test.jpg')
        qml_engine.rootContext().setContextProperty('backend', backend)

        qtutils = QtUtils()
        qml_engine.rootContext().setContextProperty('utils', qtutils)

        # QML loads image from the backend using an image provider
        qml_engine.addImageProvider('backend', backend.image_provider)

        # Load main window
        qml_engine.load(
            QUrl.fromLocalFile(str(DIR_RESOURCES / 'qml' / 'main.qml')))
        #qml_engine.load('qml/main.qml')

        if qml_engine.rootObjects():
            exit_code = qt_app.exec_()
            del qml_engine
            sys.exit(exit_code)
        else:
            log.error('QML failed to load')
            sys.exit(1)
    except Exception as e:
        log.exception('Exception in main application')
        sys.exit(1)
Beispiel #17
0
    def save_result(self):
        if self.settings.image_path is not None and QMessageBox.Yes == QMessageBox.question(
                self, "Copy", "Copy name to clipboard?",
                QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes):
            clipboard = QGuiApplication.clipboard()
            clipboard.setText(
                os.path.splitext(os.path.basename(
                    self.settings.image_path))[0])

        if self.settings.roi is None or len(self.settings.sizes) == 1:
            QMessageBox.warning(self, "No components", "No components to save")
            return
        dial = PSaveDialog(
            io_functions.save_components_dict,
            system_widget=False,
            settings=self.settings,
            file_mode=PSaveDialog.Directory,
            path="io.save_components_directory",
        )
        dial.selectFile(
            os.path.splitext(os.path.basename(self.settings.image_path))[0])
        if not dial.exec_():
            return
        res = dial.get_result()
        potential_names = self.settings.get_file_names_for_save_result(
            res.save_destination)
        conflict = []
        for el in potential_names:
            if os.path.exists(el):
                conflict.append(el)
        if len(conflict) > 0:
            # TODO modify because of long lists
            conflict_str = "\n".join(conflict)
            if QMessageBox.No == QMessageBox.warning(
                    self,
                    "Overwrite",
                    f"Overwrite files:\n {conflict_str}",
                    QMessageBox.Yes | QMessageBox.No,
                    QMessageBox.No,
            ):
                self.save_result()

        def exception_hook(exception):
            QMessageBox.critical(
                self, "Save error",
                f"Error on disc operation. Text: {exception}", QMessageBox.Ok)

        dial = ExecuteFunctionDialog(
            res.save_class.save,
            [
                res.save_destination,
                self.settings.get_project_info(), res.parameters
            ],
            text="Save components",
            exception_hook=exception_hook,
        )
        dial.exec_()
Beispiel #18
0
    def determine_dialog_dimensions(self):
        width = REFERENCE_WIDTH
        height = REFERENCE_HEIGHT

        screen = None
        try:
            if hasattr(QGuiApplication, "screenAt"):
                screen = QGuiApplication.screenAt(
                    self.parent().parent().geometry().center())
            else:
                # get the screen from the last top level window
                windows = QGuiApplication.topLevelWindows()
                screen = windows[-1].screen()
        except Exception:
            # something failed just take the primary screen
            screen = QGuiApplication.primaryScreen()

        if screen is not None:
            screen_width = screen.availableSize().width()
            screen_height = screen.availableSize().height()

            # the proportion of the whole window size for the about screen
            window_scaling = 0.4
            width = int(screen_width * window_scaling)

            # also calculate the intended width but using the hieght and a standard screen aspect ratio
            width_by_height = int(screen_height * WIDESCREEN_ASPECT_RATIO *
                                  window_scaling)
            # take the smaller of the width from the screen width and height
            if width_by_height < width:
                width = width_by_height

            # set a minimum size
            if width < REFERENCE_WIDTH:
                width = REFERENCE_WIDTH

            # calculate height from the width and aspect ratio
            height = int(width / REFERENCE_ASPECT_RATIO)

            if width > screen_width or height > screen_height:
                self.is_widget_too_big = True

        return width, height
Beispiel #19
0
    def clipboard(self, flash=True):
        """Take a screenshot of the currently displayed screen and copy the
        image to the clipboard.

        Parameters
        ----------
        flash : bool
            Flag to indicate whether flash animation should be shown after
            the screenshot was captured.
        """
        cb = QGuiApplication.clipboard()
        cb.setImage(self._screenshot(flash))
Beispiel #20
0
    def pasteShape(self):
        from qtpy.QtGui import QGuiApplication

        clipboard = QGuiApplication.clipboard()
        if not clipboard.ownsClipboard():
            return
        shapes_json = clipboard.text()
        added_shapes = self.canvas.pasteShapes(shapes_json)
        self.labelList.clearSelection()
        for shape in added_shapes:
            self.addLabel(shape)
        self.setDirty()
Beispiel #21
0
    def event(self, e: QEvent) -> bool:
        '''
        Event

        Parameters
        ----------
        e : QEvent

        Returns
        -------
        value : bool
        '''
        state = self.d.dragging_state
        if state == DragState.inactive:
            # Normally we would check here, if the left mouse button is pressed.
            # But from QT version 5.12.2 on the mouse events from
            # QEvent.NonClientAreaMouseButtonPress return the wrong mouse
            # button The event always returns Qt.RightButton even if the left
            # button is clicked.
            if e.type() == QEvent.NonClientAreaMouseButtonPress:
                if QT_VERSION_TUPLE >= (5, 12, 2):
                    # and QGuiApplication.mouseButtons().testFlag(Qt.LeftButton ...
                    logger.debug('FloatingWidget.event Event.NonClientAreaMouseButtonPress %s', e.type())
                    self.d.set_state(DragState.mouse_pressed)
                elif QGuiApplication.mouseButtons() == Qt.LeftButton:
                    logger.debug('FloatingWidget.event Event.NonClientAreaMouseButtonPress %s', e.type())
                    self.d.set_state(DragState.mouse_pressed)
        elif state == DragState.mouse_pressed:
            if e.type() == QEvent.NonClientAreaMouseButtonDblClick:
                logger.debug('FloatingWidget.event QEvent.NonClientAreaMouseButtonDblClick')
                self.d.set_state(DragState.inactive)
            elif e.type() == QEvent.Resize:
                # If the first event after the mouse press is a resize event, then
                # the user resizes the window instead of dragging it around.
                # But there is one exception. If the window is maximized,
                # then dragging the window via title bar will cause the widget to
                # leave the maximized state. This in turn will trigger a resize event.
                # To know, if the resize event was triggered by user via moving a
                # corner of the window frame or if it was caused by a windows state
                # change, we check, if we are not in maximized state.
                if not self.isMaximized():
                    self.d.set_state(DragState.inactive)
        elif state == DragState.floating_widget:
            if e.type() == QEvent.NonClientAreaMouseButtonRelease:
                logger.debug('FloatingWidget.event QEvent.NonClientAreaMouseButtonRelease')
                self.d.title_mouse_release_event()

        return super().event(e)
def test_error_reporter(qtbot, monkeypatch):
    """test that QtPluginErrReporter shows any instantiated PluginErrors."""

    monkeypatch.setattr(
        qt_plugin_report,
        'standard_metadata',
        lambda x: {'url': 'https://github.com/example/example'},
    )

    error_message = 'my special error'
    try:
        # we need to raise to make sure a __traceback__ is attached to the error.
        raise PluginError(error_message,
                          plugin_name='test_plugin',
                          plugin="mock")
    except PluginError:
        pass
    report_widget = qt_plugin_report.QtPluginErrReporter()
    qtbot.addWidget(report_widget)

    # the null option plus the one we created
    assert report_widget.plugin_combo.count() >= 2

    # the message should appear somewhere in the text area
    report_widget.set_plugin('test_plugin')
    assert error_message in report_widget.text_area.toPlainText()

    # mock_webbrowser_open
    def mock_webbrowser_open(url, new=0):
        assert new == 2
        assert "Errors for plugin 'test_plugin'" in url
        assert "Traceback from napari" in url

    monkeypatch.setattr(webbrowser, 'open', mock_webbrowser_open)

    qtbot.mouseClick(report_widget.github_button, Qt.LeftButton)

    # make sure we can copy traceback to clipboard
    report_widget.copyToClipboard()
    clipboard_text = QGuiApplication.clipboard().text()
    assert "Errors for plugin 'test_plugin'" in clipboard_text

    # plugins without errors raise an error
    with pytest.raises(ValueError):
        report_widget.set_plugin('non_existent')

    report_widget.set_plugin(None)
    assert not report_widget.text_area.toPlainText()
Beispiel #23
0
    def dropEvent(self, event):
        """Add local files and web URLS with drag and drop.

        Parameters
        ----------
        event : qtpy.QtCore.QEvent
            Event from the Qt context.
        """
        shift_down = QGuiApplication.keyboardModifiers() & Qt.ShiftModifier
        filenames = []
        for url in event.mimeData().urls():
            if url.isLocalFile():
                filenames.append(url.toLocalFile())
            else:
                filenames.append(url.toString())
        self.viewer.open(filenames, stack=bool(shift_down))
Beispiel #24
0
    def clipboard(self, flash=True):
        """Take a screenshot of the currently displayed screen and copy the
        image to the clipboard.

        Parameters
        ----------
        flash : bool
            Flag to indicate whether flash animation should be shown after
            the screenshot was captured.
        """
        import warnings

        warnings.warn(
            trans.
            _("'window.qt_viewer.screenshot' is deprecated and will be removed in v0.4.14.  Please use 'window.screenshot(canvas_only=True)' instead"
              ),
            FutureWarning,
            stacklevel=2,
        )
        cb = QGuiApplication.clipboard()
        cb.setImage(self._screenshot(flash))
Beispiel #25
0
def test_qt_viewer_clipboard_with_flash(make_napari_viewer, qtbot):
    viewer = make_napari_viewer()
    # make sure clipboard is empty
    QGuiApplication.clipboard().clear()
    clipboard_image = QGuiApplication.clipboard().image()
    assert clipboard_image.isNull()

    # capture screenshot
    viewer.window.qt_viewer.clipboard(flash=True)
    clipboard_image = QGuiApplication.clipboard().image()
    assert not clipboard_image.isNull()

    # ensure the flash effect is applied
    assert viewer.window.qt_viewer._canvas_overlay.graphicsEffect() is not None
    assert hasattr(viewer.window.qt_viewer._canvas_overlay, "_flash_animation")
    qtbot.wait(500)  # wait for the animation to finish
    assert viewer.window.qt_viewer._canvas_overlay.graphicsEffect() is None
    assert not hasattr(viewer.window.qt_viewer._canvas_overlay,
                       "_flash_animation")

    # clear clipboard and grab image from application view
    QGuiApplication.clipboard().clear()
    clipboard_image = QGuiApplication.clipboard().image()
    assert clipboard_image.isNull()

    # capture screenshot of the entire window
    viewer.window.clipboard(flash=True)
    clipboard_image = QGuiApplication.clipboard().image()
    assert not clipboard_image.isNull()

    # ensure the flash effect is applied
    assert viewer.window._qt_window.graphicsEffect() is not None
    assert hasattr(viewer.window._qt_window, "_flash_animation")
    qtbot.wait(500)  # wait for the animation to finish
    assert viewer.window._qt_window.graphicsEffect() is None
    assert not hasattr(viewer.window._qt_window, "_flash_animation")
Beispiel #26
0
 def __init__(self, parent, history):
     super().__init__(parent=parent)
     self.setWindowTitle("History")
     layout = QVBoxLayout()
     text = QPlainTextEdit()
     font = QFont()
     font.setFamily("monospace")
     font.setStyleHint(QFont.Monospace)
     text.setFont(font)
     highlighter = PythonHighlighter(text.document())  # noqa: F841
     text.setReadOnly(True)
     text.setPlainText(history)
     layout.addWidget(text)
     buttonbox = QDialogButtonBox(QDialogButtonBox.Ok)
     clipboardbutton = QPushButton("Copy to clipboard")
     buttonbox.addButton(clipboardbutton, QDialogButtonBox.ActionRole)
     clipboard = QGuiApplication.clipboard()
     clipboardbutton.clicked.connect(
         lambda: clipboard.setText(history + "\n"))
     layout.addWidget(buttonbox)
     self.setLayout(layout)
     buttonbox.accepted.connect(self.accept)
     self.resize(700, 500)
Beispiel #27
0
def main():
    import sys

    app = QGuiApplication(sys.argv)

    a = Window()
    a.setFramePosition(QPoint(10, 10))
    a.setTitle("Window A")
    a.setObjectName(a.title())
    a.setVisible(True)

    b = Window()
    b.setFramePosition(QPoint(100, 100))
    b.setTitle("Window B")
    b.setObjectName(b.title())
    b.setVisible(True)

    child = Window(b)
    child.setObjectName("ChildOfB")
    child.setVisible(True)

    windows = []
    screens = app.screens()
    for screen in screens:
        if screen == app.primaryScreen():
            continue
        window = Window(screen)
        geometry = window.geometry()
        geometry.moveCenter(screen.availableGeometry().center())
        window.setGeometry(geometry)
        window.setVisible(True)
        window.setTitle(screen.name())
        window.setObjectName(window.title())
        windows.append(window)

    return app.exec()

    sys.exit(app.exec_())
Beispiel #28
0
 def __to_clipboard(widget):
     QGuiApplication.clipboard().setText('\n'.join([widget.item(i).text() for i in range(widget.count())]))
Beispiel #29
0
    def move_to(self, position='top', *, win_ratio=0.9, min_length=0):
        """Move popup to a position relative to the QMainWindow.

        Parameters
        ----------
        position : {str, tuple}, optional
            position in the QMainWindow to show the pop, by default 'top'
            if str: must be one of {'top', 'bottom', 'left', 'right' }
            if tuple: must be length 4 with (left, top, width, height)
        win_ratio : float, optional
            Fraction of the width (for position = top/bottom) or height (for
            position = left/right) of the QMainWindow that the popup will
            occupy.  Only valid when isinstance(position, str).
            by default 0.9
        min_length : int, optional
            Minimum size of the long dimension (width for top/bottom or
            height fort left/right).

        Raises
        ------
        ValueError
            if position is a string and not one of
            {'top', 'bottom', 'left', 'right' }
        """
        if isinstance(position, str):
            window = self.parent().window() if self.parent() else None
            if not window:
                raise ValueError(
                    "Specifying position as a string is only posible if "
                    "the popup has a parent")
            left = window.pos().x()
            top = window.pos().y()
            if position in ('top', 'bottom'):
                width = window.width() * win_ratio
                width = max(width, min_length)
                left += (window.width() - width) / 2
                height = self.sizeHint().height()
                top += (24 if position == 'top' else
                        (window.height() - height - 12))
            elif position in ('left', 'right'):
                height = window.height() * win_ratio
                height = max(height, min_length)
                # 22 is for the title bar
                top += 22 + (window.height() - height) / 2
                width = self.sizeHint().width()
                left += (12 if position == 'left' else
                         (window.width() - width - 12))
            else:
                raise ValueError('position must be one of '
                                 '["top", "left", "bottom", "right"]')
        elif isinstance(position, (tuple, list)):
            assert len(position) == 4, '`position` argument must have length 4'
            left, top, width, height = position
        else:
            raise ValueError(f"Wrong type of position {position}")

        # necessary for transparent round corners
        self.resize(self.sizeHint())
        # make sure the popup is completely on the screen
        # In Qt ≥5.10 we can use screenAt to know which monitor the mouse is on

        if hasattr(QGuiApplication, "screenAt"):
            screen_geometry: QRect = QGuiApplication.screenAt(
                QCursor.pos()).geometry()
        else:
            # This widget is deprecated since Qt 5.11
            from qtpy.QtWidgets import QDesktopWidget

            screen_num = QDesktopWidget().screenNumber(QCursor.pos())
            screen_geometry = QGuiApplication.screens()[screen_num].geometry()

        left = max(min(screen_geometry.right() - width, left),
                   screen_geometry.left())
        top = max(min(screen_geometry.bottom() - height, top),
                  screen_geometry.top())
        self.setGeometry(left, top, width, height)
Beispiel #30
0
def create_screenshots(app, window, is_darkstyle):
    """Save screenshots for different application views and quit."""
    from qtpy.QtCore import QCoreApplication
    from qtpy.QtGui import QGuiApplication
    from qtpy.QtWidgets import QDockWidget, QTabWidget

    theme = 'dark' if is_darkstyle else 'normal'
    print('\nCreating {} screenshots'.format(theme))
    docks = window.findChildren(QDockWidget)
    tabs = window.findChildren(QTabWidget)
    widget_data = {
        'containers_buttons.png': [
            'Containers - No Tabs',
            'Buttons',
        ],
        'containers_tabs_displays.png': [
            'Containers - Tabs',
            'Displays',
        ],
        'views_inputs_no_fields.png': [
            'Views',
            'Inputs - No Fields',
        ],
        'widgets_inputs_fields.png': [
            'Widgets',
            'Inputs - Fields',
        ],
    }
    prefix = 'qdarkstyle_' if is_darkstyle else 'no_dark_'
    screen = QGuiApplication.primaryScreen()
    QCoreApplication.processEvents()
    tab = [tab for tab in tabs if tab.count() >= 12][0]
    tab.setCurrentIndex(11)
    QCoreApplication.processEvents()

    for fname_suffix, widgets in widget_data.items():
        QCoreApplication.processEvents()
        png_path = os.path.join(SCREENSHOTS_PATH, prefix + fname_suffix)
        print('\t' + png_path)

        for dockwidget_name in widgets:
            dockwidget = [
                dw for dw in docks if dw.windowTitle() == dockwidget_name
            ]
            if dockwidget:
                dockwidget = dockwidget[0]
                dockwidget.show()
                dockwidget.raise_()
                QCoreApplication.processEvents()

            dockwidget = None

        QCoreApplication.processEvents()
        pixmap = screen.grabWindow(window.winId())
        img = pixmap.toImage()
        img.save(png_path)
        QCoreApplication.processEvents()

    window.showNormal()
    QCoreApplication.processEvents()
    print('\n')
    app.exit()
Beispiel #31
0
 def copyToClipboard(self) -> None:
     """Copy current plugin traceback info to clipboard as plain text."""
     plugin = self.plugin_combo.currentText()
     err_string = format_exceptions(plugin, as_html=False)
     cb = QGuiApplication.clipboard()
     cb.setText(err_string)
Beispiel #32
0
    def copySelectedShape(self):
        from qtpy.QtGui import QGuiApplication

        shapes_json = self.canvas.copySelectedShapes()
        clipboard = QGuiApplication.clipboard()
        clipboard.setText(shapes_json)