Example #1
0
def test_autofit_figure_viewer(figbrowser, tmpdir, fmt):
    """
    Test figure diplayed when `Fit plots to window` is True.
    """
    fig = add_figures_to_browser(figbrowser, 1, tmpdir, fmt)[0]
    figviewer = figbrowser.figviewer
    figcanvas = figviewer.figcanvas

    # Calculate original figure size in pixels.
    qpix = QPixmap()
    qpix.loadFromData(fig, fmt.upper())
    fwidth, fheight = qpix.width(), qpix.height()

    # Test when `Fit plots to window` is set to True.
    # Otherwise, test should fall into `test_zoom_figure_viewer`
    figbrowser.change_auto_fit_plotting(True)

    size = figviewer.size()
    style = figviewer.style()
    width = (size.width() - style.pixelMetric(QStyle.PM_LayoutLeftMargin) -
             style.pixelMetric(QStyle.PM_LayoutRightMargin))
    height = (size.height() - style.pixelMetric(QStyle.PM_LayoutTopMargin) -
              style.pixelMetric(QStyle.PM_LayoutBottomMargin))
    if (fwidth / fheight) > (width / height):
        new_width = int(width)
        new_height = int(width / fwidth * fheight)
    else:
        new_height = int(height)
        new_width = int(height / fheight * fwidth)

    assert (figbrowser.zoom_disp.value() == np.round(figcanvas.width() /
                                                     fwidth * 100))
    assert figcanvas.width() == new_width
    assert figcanvas.height() == new_height
Example #2
0
    def __init__(self, parent):
        super(KiteIntegrationInfo, self).__init__(parent)
        # Images
        images_layout = QHBoxLayout()
        if is_dark_interface():
            icon_filename = 'spyder_kite.svg'
        else:
            icon_filename = 'spyder_kite_dark.svg'
        image_path = get_image_path(icon_filename)
        image = QPixmap(image_path)
        image_label = QLabel()
        screen = QApplication.primaryScreen()
        device_image_ratio = screen.devicePixelRatio()
        if device_image_ratio > 1:
            image.setDevicePixelRatio(device_image_ratio)
        else:
            image_height = image.height() * 0.5
            image_width = image.width() * 0.5
            image = image.scaled(image_width, image_height, Qt.KeepAspectRatio,
                                 Qt.SmoothTransformation)
        image_label.setPixmap(image)

        images_layout.addStretch()
        images_layout.addWidget(image_label)
        images_layout.addStretch()

        # Label
        integration_label = QLabel(
            _("Now Spyder can use <a href=\"{kite_url}\">Kite</a> to "
              "provide better and more accurate code completions in its "
              "editor <br>for the most important packages in the Python "
              "scientific ecosystem, such as Numpy, <br>Matplotlib and "
              "Pandas.<br><br>Would you like to install it or learn more "
              "about it?<br><br><i>Note:</i> Kite is free to use "
              "but is not an open source program.").format(
                  kite_url=KITE_SPYDER_URL))
        integration_label.setOpenExternalLinks(True)

        # Buttons
        buttons_layout = QHBoxLayout()
        learn_more_button = QPushButton(_('Learn more'))
        learn_more_button.setAutoDefault(False)
        install_button = QPushButton(_('Install Kite'))
        install_button.setAutoDefault(False)
        dismiss_button = QPushButton(_('Dismiss'))
        dismiss_button.setAutoDefault(False)
        buttons_layout.addStretch()
        buttons_layout.addWidget(install_button)
        buttons_layout.addWidget(learn_more_button)
        buttons_layout.addWidget(dismiss_button)

        general_layout = QVBoxLayout()
        general_layout.addLayout(images_layout)
        general_layout.addWidget(integration_label)
        general_layout.addLayout(buttons_layout)
        self.setLayout(general_layout)

        learn_more_button.clicked.connect(self.sig_learn_more_button_clicked)
        install_button.clicked.connect(self.sig_install_button_clicked)
        dismiss_button.clicked.connect(self.sig_dismiss_button_clicked)
Example #3
0
def test_zoom_figure_viewer(figbrowser, tmpdir, fmt):
    """
    Test zooming in and out the figure diplayed in the figure viewer.
    """
    fig = add_figures_to_browser(figbrowser, 1, tmpdir, fmt)[0]
    figcanvas = figbrowser.figviewer.figcanvas

    # Set `Fit plots to windows` to False before the test.
    figbrowser.change_auto_fit_plotting(False)

    # Calculate original figure size in pixels.
    qpix = QPixmap()
    qpix.loadFromData(fig, fmt.upper())
    fwidth, fheight = qpix.width(), qpix.height()

    assert figbrowser.zoom_disp.value() == 100
    assert figcanvas.width() == fwidth
    assert figcanvas.height() == fheight

    # Zoom in and out the figure in the figure viewer.
    scaling_factor = 0
    scaling_step = figbrowser.figviewer._scalestep
    for zoom_step in [1, 1, -1, -1, -1]:
        if zoom_step == 1:
            figbrowser.zoom_in()
        elif zoom_step == -1:
            figbrowser.zoom_out()
        scaling_factor += zoom_step
        scale = scaling_step**scaling_factor

        assert figbrowser.zoom_disp.value() == np.floor(scale * 100)
        assert figcanvas.width() == np.floor(fwidth * scale)
        assert figcanvas.height() == np.floor(fheight * scale)
Example #4
0
def test_autofit_figure_viewer(figbrowser, tmpdir, fmt):
    """
    Test figure diplayed when `Fit plots to window` is True.
    """
    fig = add_figures_to_browser(figbrowser, 1, tmpdir, fmt)[0]
    figviewer = figbrowser.figviewer
    figcanvas = figviewer.figcanvas

    # Calculate original figure size in pixels.
    qpix = QPixmap()
    qpix.loadFromData(fig, fmt.upper())
    fwidth, fheight = qpix.width(), qpix.height()

    # Test when `Fit plots to window` is set to True.
    # Otherwise, test should fall into `test_zoom_figure_viewer`
    figbrowser.change_auto_fit_plotting(True)
    size = figviewer.size()

    scrollbar_width = figviewer.verticalScrollBar().sizeHint().width()
    width = size.width() - scrollbar_width
    scrollbar_height = figviewer.horizontalScrollBar().sizeHint().height()
    height = size.height() - scrollbar_height
    if (fwidth / fheight) > (width / height):
        new_width = int(width)
        new_height = int(width / fwidth * fheight)
    else:
        new_height = int(height)
        new_width = int(height / fheight * fwidth)

    assert figcanvas.width() == new_width
    assert figcanvas.height() == new_height
Example #5
0
    def findAscent(self, font):
        dummy = "E"
        white = QColor(Qt.white)

        fm = self.fontmetrics(font)
        pm = QPixmap(fm.width(dummy), fm.height())
        pm.fill(white)

        p = QPainter(pm)
        p.setFont(font)
        p.drawText(0, 0, pm.width(), pm.height(), 0, dummy)
        p.end()

        img = pm.toImage()

        w = pm.width()
        linebytes = w * 4
        for row in range(img.height()):
            if PYSIDE2:
                line = bytes(img.scanLine(row))
            else:
                line = img.scanLine(row).asstring(linebytes)
            for col in range(w):
                color = struct.unpack("I", line[col * 4:(col + 1) * 4])[0]
                if color != white.rgb():
                    return fm.ascent() - row + 1
        return fm.ascent()
Example #6
0
def test_zoom_figure_viewer(figbrowser, tmpdir, fmt):
    """
    Test zooming in and out the figure diplayed in the figure viewer.
    """
    fig = add_figures_to_browser(figbrowser, 1, tmpdir, fmt)[0]
    figcanvas = figbrowser.figviewer.figcanvas

    # Calculate original figure size in pixels.
    qpix = QPixmap()
    qpix.loadFromData(fig, fmt.upper())
    fwidth, fheight = qpix.width(), qpix.height()

    assert figbrowser.zoom_disp.value() == 100
    assert figcanvas.width() == fwidth
    assert figcanvas.height() == fheight

    # Zoom in and out the figure in the figure viewer.
    scaling_factor = 0
    scaling_step = figbrowser.figviewer._scalestep
    for zoom_step in [1, 1, -1, -1, -1]:
        if zoom_step == 1:
            figbrowser.zoom_in()
        elif zoom_step == -1:
            figbrowser.zoom_out()
        scaling_factor += zoom_step
        scale = scaling_step**scaling_factor

        assert figbrowser.zoom_disp.value() == np.floor(scale * 100)
        assert figcanvas.width() == np.floor(fwidth * scale)
        assert figcanvas.height() == np.floor(fheight * scale)
Example #7
0
 def _set_image(self, index):
     if index > len(
             self._all_images) - 1 or index < -1 * len(self._all_images):
         l.log("error: resetting again")
         index = 0
     self._current_index = index
     l.log("setting image")
     image_pix_map = QPixmap(self._all_images[self._current_index])
     print("image: ", image_pix_map.width(), image_pix_map.height())
     self._image_label.setPixmap(image_pix_map)
     self.set_title(self._all_images[self._current_index])
class SearchLineEdit(QLineEdit):
    """Line edit search widget with icon and remove all button"""
    def __init__(self, parent=None, icon=True):
        super(SearchLineEdit, self).__init__(parent)
        self.setTextMargins(1, 0, 20, 0)

        if icon:
            self.setTextMargins(18, 0, 20, 0)
            self._label = QLabel(self)
            self._pixmap_icon = QPixmap(get_image_path('conda_search.png'))
            self._label.setPixmap(self._pixmap_icon)
            self._label.setStyleSheet('''border: 0px; padding-bottom: 0px;
                                      padding-left: 2px;''')

        self._pixmap = QPixmap(get_image_path('conda_del.png'))
        self.button_clear = QToolButton(self)
        self.button_clear.setIcon(QIcon(self._pixmap))
        self.button_clear.setIconSize(QSize(18, 18))
        self.button_clear.setCursor(Qt.ArrowCursor)
        self.button_clear.setStyleSheet("""QToolButton
            {background: transparent;
            padding-right: 2px; border: none; margin:0px; }""")
        self.button_clear.setVisible(False)

        # Layout
        self._layout = QHBoxLayout(self)
        self._layout.addWidget(self.button_clear, 0, Qt.AlignRight)
        self._layout.setSpacing(0)
        self._layout.setContentsMargins(0, 2, 2, 0)

        # Signals and slots
        self.button_clear.clicked.connect(self.clear_text)
        self.textChanged.connect(self._toggle_visibility)
        self.textEdited.connect(self._toggle_visibility)

    def _toggle_visibility(self):
        """ """
        if len(self.text()) == 0:
            self.button_clear.setVisible(False)
        else:
            self.button_clear.setVisible(True)

    def sizeHint(self):
        return QSize(200, self._pixmap_icon.height())

    # Public api
    # ----------
    def clear_text(self):
        """ """
        self.setText('')
        self.setFocus()
Example #9
0
class SearchLineEdit(QLineEdit):
    """Line edit search widget with icon and remove all button"""
    def __init__(self, parent=None, icon=True):
        super(SearchLineEdit, self).__init__(parent)
        self.setTextMargins(1, 0, 20, 0)

        if icon:
            self.setTextMargins(18, 0, 20, 0)
            self._label = QLabel(self)
            self._pixmap_icon = QPixmap(get_image_path('conda_search.png'))
            self._label.setPixmap(self._pixmap_icon)
            self._label.setStyleSheet('''border: 0px; padding-bottom: 0px;
                                      padding-left: 2px;''')

        self._pixmap = QPixmap(get_image_path('conda_del.png'))
        self.button_clear = QToolButton(self)
        self.button_clear.setIcon(QIcon(self._pixmap))
        self.button_clear.setIconSize(QSize(18, 18))
        self.button_clear.setCursor(Qt.ArrowCursor)
        self.button_clear.setStyleSheet("""QToolButton
            {background: transparent;
            padding-right: 2px; border: none; margin:0px; }""")
        self.button_clear.setVisible(False)

        # Layout
        self._layout = QHBoxLayout(self)
        self._layout.addWidget(self.button_clear, 0, Qt.AlignRight)
        self._layout.setSpacing(0)
        self._layout.setContentsMargins(0, 2, 2, 0)

        # Signals and slots
        self.button_clear.clicked.connect(self.clear_text)
        self.textChanged.connect(self._toggle_visibility)
        self.textEdited.connect(self._toggle_visibility)

    def _toggle_visibility(self):
        """ """
        if len(self.text()) == 0:
            self.button_clear.setVisible(False)
        else:
            self.button_clear.setVisible(True)

    def sizeHint(self):
        return QSize(200, self._pixmap_icon.height())

    # Public api
    # ----------
    def clear_text(self):
        """ """
        self.setText('')
        self.setFocus()
Example #10
0
class FigureCanvas(QFrame):
    """
    A basic widget on which can be painted a custom png, jpg, or svg image.
    """
    def __init__(self, parent=None):
        super(FigureCanvas, self).__init__(parent)
        self.setLineWidth(2)
        self.setMidLineWidth(1)
        self.setStyleSheet("background-color: white")

        self.fig = None
        self.fmt = None
        self.fwidth, self.fheight = 200, 200

    def clear_canvas(self):
        """Clear the figure that was painted on the widget."""
        self.fig = None
        self.fmt = None
        self._qpix_buffer = []
        self.repaint()

    def load_figure(self, fig, fmt):
        """
        Load the figure from a png, jpg, or svg image, convert it in
        a QPixmap, and force a repaint of the widget.
        """
        self.fig = fig
        self.fmt = fmt

        if fmt in ['image/png', 'image/jpeg']:
            self._qpix_orig = QPixmap()
            self._qpix_orig.loadFromData(fig, fmt.upper())
        elif fmt == 'image/svg+xml':
            self._qpix_orig = QPixmap(svg_to_image(fig))

        self._qpix_buffer = [self._qpix_orig]
        self.fwidth = self._qpix_orig.width()
        self.fheight = self._qpix_orig.height()

    def paintEvent(self, event):
        """Qt method override to paint a custom image on the Widget."""
        super(FigureCanvas, self).paintEvent(event)
        # Prepare the rect on which the image is going to be painted :
        fw = self.frameWidth()
        rect = QRect(0 + fw, 0 + fw,
                     self.size().width() - 2 * fw,
                     self.size().height() - 2 * fw)

        if self.fig is None:
            return

        # Check/update the qpixmap buffer :
        qpix2paint = None
        for qpix in self._qpix_buffer:
            if qpix.size().width() == rect.width():
                qpix2paint = qpix
                break
        else:
            if self.fmt in ['image/png', 'image/jpeg']:
                qpix2paint = self._qpix_orig.scaledToWidth(
                    rect.width(), mode=Qt.SmoothTransformation)
            elif self.fmt == 'image/svg+xml':
                qpix2paint = QPixmap(svg_to_image(self.fig, rect.size()))
            self._qpix_buffer.append(qpix2paint)

        if qpix2paint is not None:
            # Paint the image on the widget :
            qp = QPainter()
            qp.begin(self)
            qp.drawPixmap(rect, qpix2paint)
            qp.end()
Example #11
0
    def __init__(self, parent):
        super(KiteIntegrationInfo, self).__init__(parent)
        # Images
        images_layout = QHBoxLayout()
        icon_filename = 'kite_completions.png'
        image_path = get_image_path(icon_filename)
        image = QPixmap(image_path)
        image_label = QLabel()
        screen = QApplication.primaryScreen()
        image_label = QLabel()
        image_height = int(image.height() * self.ICON_SCALE_FACTOR)
        image_width = int(image.width() * self.ICON_SCALE_FACTOR)
        image = image.scaled(image_width, image_height, Qt.KeepAspectRatio,
                             Qt.SmoothTransformation)
        image_label.setPixmap(image)

        images_layout.addStretch()
        images_layout.addWidget(image_label)
        images_layout.addStretch()

        ilayout = QHBoxLayout()
        ilayout.addLayout(images_layout)

        # Label
        integration_label_title = QLabel(
            "Get better code completions in Spyder")
        integration_label_title.setStyleSheet(
            f"font-size: {self.TITLE_FONT_SIZE}")
        integration_label_title.setWordWrap(True)
        integration_label = QLabel(
            _("Now Spyder can use Kite to provide better code "
              "completions for key packages in the scientific Python "
              "Ecosystem. Install Kite for a better editor experience in "
              "Spyder. <br><br>Kite is free to use but is not open "
              "source. <a href=\"{kite_url}\">Learn more about Kite </a>").
            format(kite_url=KITE_SPYDER_URL))
        integration_label.setStyleSheet(f"font-size: {self.CONTENT_FONT_SIZE}")
        integration_label.setOpenExternalLinks(True)
        integration_label.setWordWrap(True)
        integration_label.setFixedWidth(360)
        label_layout = QVBoxLayout()
        label_layout.addWidget(integration_label_title)
        label_layout.addWidget(integration_label)

        # Buttons
        buttons_layout = QHBoxLayout()
        install_button = QPushButton(_('Install Kite'))
        install_button.setAutoDefault(False)
        install_button.setStyleSheet("background-color: #3775A9;"
                                     f"font-size: {self.BUTTONS_FONT_SIZE};"
                                     f"padding: {self.BUTTONS_PADDING}")
        dismiss_button = QPushButton(_('Dismiss'))
        dismiss_button.setAutoDefault(False)
        dismiss_button.setStyleSheet("background-color: #60798B;"
                                     f"font-size: {self.BUTTONS_FONT_SIZE};"
                                     f"padding: {self.BUTTONS_PADDING}")
        buttons_layout.addStretch()
        buttons_layout.addWidget(install_button)
        if not MAC:
            buttons_layout.addSpacing(10)
        buttons_layout.addWidget(dismiss_button)

        # Buttons with label
        vertical_layout = QVBoxLayout()
        if not MAC:
            vertical_layout.addStretch()
            vertical_layout.addLayout(label_layout)
            vertical_layout.addSpacing(20)
            vertical_layout.addLayout(buttons_layout)
            vertical_layout.addStretch()
        else:
            vertical_layout.addLayout(label_layout)
            vertical_layout.addLayout(buttons_layout)

        general_layout = QHBoxLayout()
        general_layout.addStretch()
        general_layout.addLayout(ilayout)
        general_layout.addSpacing(15)
        general_layout.addLayout(vertical_layout)
        general_layout.addStretch()

        self.setLayout(general_layout)

        # Signals
        install_button.clicked.connect(self.sig_install_button_clicked)
        dismiss_button.clicked.connect(self.sig_dismiss_button_clicked)

        if is_dark_interface():
            self.setStyleSheet("background-color: #262E38")
        self.setContentsMargins(18, 40, 18, 40)
        if not MAC:
            self.setFixedSize(800, 350)
Example #12
0
    def __init__(self, parent):
        super(KiteInstallation, self).__init__(parent)

        # Left side
        action_layout = QVBoxLayout()
        progress_layout = QHBoxLayout()
        self._progress_widget = QWidget(self)
        self._progress_widget.setFixedHeight(50)
        self._progress_filter = HoverEventFilter()
        self._progress_bar = QProgressBar(self)
        self._progress_bar.setFixedWidth(180)
        self._progress_widget.installEventFilter(self._progress_filter)
        self.cancel_button = QPushButton()
        self.cancel_button.setIcon(ima.icon('DialogCloseButton'))
        self.cancel_button.hide()
        progress_layout.addWidget(self._progress_bar, alignment=Qt.AlignLeft)
        progress_layout.addWidget(self.cancel_button)
        self._progress_widget.setLayout(progress_layout)

        self._progress_label = QLabel(_('Downloading'))
        install_info = QLabel(
            _("Kite comes with a native app called the Copilot <br>"
              "which provides you with real time <br>"
              "documentation as you code.<br><br>"
              "When Kite is done installing, the Copilot will <br>"
              "launch automatically and guide you throught the <br>"
              "rest of the setup process."))

        button_layout = QHBoxLayout()
        self.ok_button = QPushButton(_('OK'))
        button_layout.addStretch()
        button_layout.addWidget(self.ok_button)
        button_layout.addStretch()

        action_layout.addStretch()
        action_layout.addWidget(self._progress_label)
        action_layout.addWidget(self._progress_widget)
        action_layout.addWidget(install_info)
        action_layout.addSpacing(10)
        action_layout.addLayout(button_layout)
        action_layout.addStretch()

        # Right side
        copilot_image_source = get_image_path('kite_copilot.png')

        copilot_image = QPixmap(copilot_image_source)
        copilot_label = QLabel()
        screen = QApplication.primaryScreen()
        device_pixel_ratio = screen.devicePixelRatio()
        if device_pixel_ratio > 1:
            copilot_image.setDevicePixelRatio(device_pixel_ratio)
            copilot_label.setPixmap(copilot_image)
        else:
            image_height = int(copilot_image.height() * 0.4)
            image_width = int(copilot_image.width() * 0.4)
            copilot_label.setPixmap(
                copilot_image.scaled(image_width, image_height,
                                     Qt.KeepAspectRatio,
                                     Qt.SmoothTransformation))

        # Layout
        general_layout = QHBoxLayout()
        general_layout.addLayout(action_layout)
        general_layout.addWidget(copilot_label)

        self.setLayout(general_layout)

        # Signals
        self._progress_filter.sig_hover_enter.connect(
            lambda: self.cancel_button.show())
        self._progress_filter.sig_hover_leave.connect(
            lambda: self.cancel_button.hide())
Example #13
0
 def is_image_landscape(self, image: QPixmap):
     if image.width() / image.height() > 1:
         return True
     else:
         return False
Example #14
0
class Canvas(QWidget):
    def __init__(self, parent):
        super(Canvas, self).__init__()

        self.SELECT, self.RECTANGLE, self.AUTO_POLYGON, self.POLYGON = 0, 1, 2, 3

        self._painter = QPainter()
        self.pixmap = None
        self.cv2_image = None
        self.scale = 1.0
        self.mode = self.SELECT
        self.label_dir = ""
        self.parent = parent
        self.reset()

        self.labelDialog = LabelDialog(parent=self,
                                       listItem=self.parent.labels)

    def reset(self):
        self.points = []
        self.objects = []
        self.cur_object = -1
        self.parent.load_object_list(self.objects)

    # load image and label file
    def load_file(self, image_dir):
        self.reset()
        self.pixmap = QPixmap(image_dir)
        self.cv2_image = cv2.imread(image_dir)
        self.label_dir = os.path.splitext(image_dir)[0] + '.json'
        if QFile.exists(self.label_dir):
            with open(self.label_dir) as json_file:
                data = json.load(json_file)
                self.objects = []
                for obj in data['objects']:
                    points = []
                    for point in obj['points']:
                        points.append(QPointF(point['x'], point['y']))
                    if (obj['type'] == 'rectangle'):
                        self.objects.append(Rectangle(points, obj['label']))
                    elif (obj['type'] == 'polygon'):
                        self.objects.append(Polygon(points, obj['label']))
                self.cur_object = len(self.objects) - 1
                self.parent.load_object_list(self.objects)
                self.parent.object_list_widget.setCurrentRow(self.cur_object)

        self.repaint()

    def offset_to_center(self):
        s = self.scale
        area = super(Canvas, self).size()
        w, h = self.pixmap.width() * s, self.pixmap.height() * s
        aw, ah = area.width(), area.height()
        x = (aw - w) / (2 * s) if aw > w else 0
        y = (ah - h) / (2 * s) if ah > h else 0
        return QPointF(x, y)

    def transform_pos(self, point):
        return point / self.scale - self.offset_to_center()

    def rescale(self, value):
        if value >= 0.2 and value <= 5:
            self.scale = value
            self.repaint()

    def in_pixmap(self, p):
        w, h = self.pixmap.width(), self.pixmap.height()
        return (0 <= p.x() < w and 0 <= p.y() < h)

    def close_enough(self, p1, p2):
        epsilon = 0.01
        return  abs(p1.x() - p2.x()) <= max(5, epsilon * self.pixmap.width()) and \
                abs(p1.y() - p2.y()) <= max(5, epsilon * self.pixmap.height())

    def next_obj(self):
        if len(self.objects) > 0:
            self.cur_object = (self.cur_object + 1) % len(self.objects)
            self.parent.object_list_widget.setCurrentRow(self.cur_object)

    def prev_obj(self):
        if len(self.objects) > 0:
            self.cur_object = (self.cur_object + len(self.objects) - 1) % len(
                self.objects)
            self.parent.object_list_widget.setCurrentRow(self.cur_object)

    def del_obj(self):
        if len(self.objects) > 0:
            if self.cur_object == len(self.objects) - 1:
                new_id = self.cur_object - 1
            else:
                new_id = self.cur_object
            self.objects = self.objects[:self.cur_object] + self.objects[
                self.cur_object + 1:]
            self.cur_object = new_id
            self.parent.load_object_list(self.objects)
            self.parent.object_list_widget.setCurrentRow(self.cur_object)
            self.repaint()
            self.auto_export_json()

    def add_obj(self, obj):
        self.objects.append(obj)
        self.cur_object = len(self.objects) - 1
        self.parent.load_object_list(self.objects)
        self.parent.object_list_widget.setCurrentRow(self.cur_object)
        self.repaint()
        self.auto_export_json()

    def auto_export_json(self):
        data = {}
        data['date'] = str(datetime.datetime.now())
        data['objects'] = []
        for obj in self.objects:
            data_obj = {}
            obj.export_json(data_obj)
            data['objects'].append(data_obj)

        with open(self.label_dir, 'w') as json_file:
            json.dump(data, json_file)

        self.parent.load_file_list()
        self.parent.file_list_widget.setCurrentRow(self.parent.file_id)

    def paintEvent(self, event):
        if self.pixmap == None:
            return super(Canvas, self).paintEvent(event)

        p = self._painter
        p.begin(self)

        p.setRenderHint(QPainter.Antialiasing)
        p.setRenderHint(QPainter.HighQualityAntialiasing)
        p.setRenderHint(QPainter.SmoothPixmapTransform)

        p.scale(self.scale, self.scale)
        p.translate(self.offset_to_center())
        p.drawPixmap(0, 0, self.pixmap)

        pen = QPen()
        pen.setWidth(2 / self.scale)
        p.setPen(pen)

        for i, obj in enumerate(self.objects):
            if self.cur_object == i:
                p.setBrush(QColor(255, 0, 0, 100))
            else:
                p.setBrush(QColor(255, 0, 0, 0))
            obj.draw(p)

        if self.mode != self.SELECT:
            for point in self.points:
                p.drawEllipse(point, 2 / self.scale, 2 / self.scale)
            for i in range(len(self.points) - 1):
                p.drawLine(self.points[i], self.points[i + 1])

        p.end()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            pos = self.transform_pos(event.localPos())
            if self.in_pixmap(pos):
                self.points.append(pos)
                self.repaint()

                if self.mode == self.RECTANGLE and len(self.points) == 2:
                    left_x = int(min(self.points[0].x(), self.points[1].x()))
                    right_x = int(max(self.points[0].x(), self.points[1].x()))
                    left_y = int(min(self.points[0].y(), self.points[1].y()))
                    right_y = int(max(self.points[0].y(), self.points[1].y()))

                    text = self.labelDialog.pop_up()
                    self.add_obj(Rectangle(self.points, text))
                    self.points = []

                if self.mode == self.AUTO_POLYGON and len(self.points) == 2:
                    left_x = int(min(self.points[0].x(), self.points[1].x()))
                    right_x = int(max(self.points[0].x(), self.points[1].x()))
                    left_y = int(min(self.points[0].y(), self.points[1].y()))
                    right_y = int(max(self.points[0].y(), self.points[1].y()))

                    tmp = rectilinear_polygon.main(
                        self.cv2_image[left_y:right_y, left_x:right_x])
                    points = [QPointF(left_x + x, left_y + y) for x, y in tmp]
                    if (len(points) > 0):
                        text = self.labelDialog.pop_up()
                        self.add_obj(Polygon(points, text))
                    self.points = []

                if self.mode == self.POLYGON and len(self.points) >= 4 \
                        and self.close_enough(self.points[0], self.points[-1]):
                    text = self.labelDialog.pop_up()
                    self.add_obj(Polygon(self.points[:-1], text))
                    self.points = []
Example #15
0
    def __init__(self, parent, tour_function):
        super().__init__(parent)
        if MAC:
            flags = (self.windowFlags() | Qt.WindowStaysOnTopHint
                     & ~Qt.WindowContextHelpButtonHint)
        else:
            flags = self.windowFlags() & ~Qt.WindowContextHelpButtonHint
        self.setWindowFlags(flags)
        self.tour_function = tour_function

        # Image
        images_layout = QHBoxLayout()
        icon_filename = 'tour-spyder-logo'
        image_path = get_image_path(icon_filename)
        image = QPixmap(image_path)
        image_label = QLabel()
        image_height = image.height() * self.ICON_SCALE_FACTOR
        image_width = image.width() * self.ICON_SCALE_FACTOR
        image = image.scaled(image_width, image_height, Qt.KeepAspectRatio,
                             Qt.SmoothTransformation)
        image_label.setPixmap(image)

        images_layout.addStretch()
        images_layout.addWidget(image_label)
        images_layout.addStretch()
        if MAC:
            images_layout.setContentsMargins(0, -5, 20, 0)
        else:
            images_layout.setContentsMargins(0, -8, 35, 0)

        # Label
        tour_label_title = QLabel(_("Welcome to Spyder!"))
        tour_label_title.setStyleSheet(f"font-size: {self.TITLE_FONT_SIZE}")
        tour_label_title.setWordWrap(True)
        tour_label = QLabel(
            _("Check out our interactive tour to "
              "explore some of Spyder's panes and features."))
        tour_label.setStyleSheet(f"font-size: {self.CONTENT_FONT_SIZE}")
        tour_label.setWordWrap(True)
        tour_label.setFixedWidth(340)

        # Buttons
        buttons_layout = QHBoxLayout()
        dialog_tour_color = QStylePalette.COLOR_BACKGROUND_2
        start_tour_color = QStylePalette.COLOR_ACCENT_2
        start_tour_hover = QStylePalette.COLOR_ACCENT_3
        start_tour_pressed = QStylePalette.COLOR_ACCENT_4
        dismiss_tour_color = QStylePalette.COLOR_BACKGROUND_4
        dismiss_tour_hover = QStylePalette.COLOR_BACKGROUND_5
        dismiss_tour_pressed = QStylePalette.COLOR_BACKGROUND_6
        font_color = QStylePalette.COLOR_TEXT_1
        self.launch_tour_button = QPushButton(_('Start tour'))
        self.launch_tour_button.setStyleSheet(
            ("QPushButton {{ "
             "background-color: {background_color};"
             "border-color: {border_color};"
             "font-size: {font_size};"
             "color: {font_color};"
             "padding: {padding}}}"
             "QPushButton:hover:!pressed {{ "
             "background-color: {color_hover}}}"
             "QPushButton:pressed {{ "
             "background-color: {color_pressed}}}").format(
                 background_color=start_tour_color,
                 border_color=start_tour_color,
                 font_size=self.BUTTONS_FONT_SIZE,
                 font_color=font_color,
                 padding=self.BUTTONS_PADDING,
                 color_hover=start_tour_hover,
                 color_pressed=start_tour_pressed))
        self.launch_tour_button.setAutoDefault(False)
        self.dismiss_button = QPushButton(_('Dismiss'))
        self.dismiss_button.setStyleSheet(
            ("QPushButton {{ "
             "background-color: {background_color};"
             "border-color: {border_color};"
             "font-size: {font_size};"
             "color: {font_color};"
             "padding: {padding}}}"
             "QPushButton:hover:!pressed {{ "
             "background-color: {color_hover}}}"
             "QPushButton:pressed {{ "
             "background-color: {color_pressed}}}").format(
                 background_color=dismiss_tour_color,
                 border_color=dismiss_tour_color,
                 font_size=self.BUTTONS_FONT_SIZE,
                 font_color=font_color,
                 padding=self.BUTTONS_PADDING,
                 color_hover=dismiss_tour_hover,
                 color_pressed=dismiss_tour_pressed))
        self.dismiss_button.setAutoDefault(False)

        buttons_layout.addStretch()
        buttons_layout.addWidget(self.launch_tour_button)
        if not MAC:
            buttons_layout.addSpacing(10)
        buttons_layout.addWidget(self.dismiss_button)

        layout = QHBoxLayout()
        layout.addLayout(images_layout)

        label_layout = QVBoxLayout()
        label_layout.addWidget(tour_label_title)
        if not MAC:
            label_layout.addSpacing(3)
            label_layout.addWidget(tour_label)
        else:
            label_layout.addWidget(tour_label)
            label_layout.addSpacing(10)

        vertical_layout = QVBoxLayout()
        if not MAC:
            vertical_layout.addStretch()
            vertical_layout.addLayout(label_layout)
            vertical_layout.addSpacing(20)
            vertical_layout.addLayout(buttons_layout)
            vertical_layout.addStretch()
        else:
            vertical_layout.addLayout(label_layout)
            vertical_layout.addLayout(buttons_layout)

        general_layout = QHBoxLayout()
        if not MAC:
            general_layout.addStretch()
            general_layout.addLayout(layout)
            general_layout.addSpacing(1)
            general_layout.addLayout(vertical_layout)
            general_layout.addStretch()
        else:
            general_layout.addLayout(layout)
            general_layout.addLayout(vertical_layout)

        self.setLayout(general_layout)

        self.launch_tour_button.clicked.connect(self._start_tour)
        self.dismiss_button.clicked.connect(self.close)
        self.setStyleSheet(f"background-color:{dialog_tour_color}")
        self.setContentsMargins(18, 40, 18, 40)
        if not MAC:
            self.setFixedSize(640, 280)
Example #16
0
class AboutView(QDialog):
    def __init__(self, parent, presenter, version_text, date_text = None):
        super(AboutView, self).__init__(parent)
        self.background_pixmap = QPixmap(':/images/First_use_Background.png')
        self.mantid_pixmap = QPixmap(':/images/mantid_smaller.png')
        self.lbl_version = QLabel()
        self.clb_release_notes = QCommandLinkButton()
        self.clb_sample_datasets = QCommandLinkButton()
        self.clb_mantid_introduction = QCommandLinkButton()
        self.clb_python_introduction = QCommandLinkButton()
        self.clb_python_in_mantid = QCommandLinkButton()
        self.clb_extending_mantid = QCommandLinkButton()
        self.cb_facility = QComboBox()
        self.cb_instrument = QComboBox()
        self.pb_manage_user_directories = QPushButton()
        self.chk_allow_usage_data = QCheckBox()
        self.lbl_privacy_policy = QLabel()
        self.chk_do_not_show_until_next_release = QCheckBox()
        self.pb_close = QPushButton()
        self.setupUI()
        self.customize_layout(version_text, date_text)
        self.presenter = presenter

    def paintEvent(self, event):
        scaled_background = self.background_pixmap.scaled(self.rescale_w(self.background_pixmap.width()),
                                                          self.rescale_h(self.background_pixmap.height()),
                                                          Qt.KeepAspectRatio,
                                                          Qt.SmoothTransformation)

        scaled_mantid = self.mantid_pixmap.scaled(self.rescale_w(self.mantid_pixmap.width()),
                                                  self.rescale_h(self.mantid_pixmap.height()),
                                                  Qt.KeepAspectRatio,
                                                  Qt.SmoothTransformation)
        qp = QPainter()
        qp.begin(self)
        qp.drawPixmap(0, 0, scaled_background)
        qp.drawPixmap(self.width() - scaled_mantid.width(), self.height()-scaled_mantid.height(), scaled_mantid)
        qp.end()

    def determine_dialog_dimensions(self):
        width = REFERENCE_WIDTH
        height = REFERENCE_HEIGHT

        screen = None
        try:
            if hasattr(QGuiApplication,"screenAt"):
                screen = QGuiApplication.screenAt(self.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.size().width()
            screen_height = screen.size().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)

        return width, height

    def rescale_w(self, value):
        return int(value * (self.width() / REFERENCE_WIDTH))

    def rescale_h(self, value):
        return int(value * (self.height() / REFERENCE_HEIGHT))

    def setupUI(self):
        width, height  = self.determine_dialog_dimensions()

        self.setMinimumSize(width, height)
        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.setWindowTitle("About Mantid Workbench")
        self.setStyleSheet(f"""QDialog {{
    background-color: rgb(190, 230, 190);
}}
QLabel{{
    font: {self.rescale_w(14)}px;
}}
QPushButton{{
    font: {self.rescale_w(14)}px;
}}
QCommandLinkButton{{
    font: {self.rescale_w(22)}px;
    background-color: rgba(255, 255, 255, 0);
    border-radius: {self.rescale_w(15)}px;
}}
QCommandLinkButton:hover {{
    background-color: rgba(45, 105, 45, 40);
}}""")

        # version label section at th etop
        parent_layout = QVBoxLayout()
        parent_layout.addSpacerItem(QSpacerItem(self.rescale_w(20),self.rescale_h(70),vPolicy=QSizePolicy.Fixed))
        self.lbl_version.setText("version ")
        self.lbl_version.setIndent(self.rescale_w(115))
        self.lbl_version.setStyleSheet(f"""color: rgb(215, 215, 215);
font: {self.rescale_w(28)}pt;
font-weight: bold;
font-size: {self.rescale_w(28)}px""")
        parent_layout.addWidget(self.lbl_version)
        parent_layout.addSpacerItem(QSpacerItem(self.rescale_w(20),self.rescale_h(40),
                                                vPolicy=QSizePolicy.MinimumExpanding))

        # split into the two columns
        two_box_layout = QHBoxLayout()
        # left side Welcome and Tutorial
        left_layout = QVBoxLayout()
        left_layout.setContentsMargins(self.rescale_w(5), 0, self.rescale_w(10), 0)
        left_layout.setSpacing(0)
        # welcome label
        lbl_welcome = QLabel()
        lbl_welcome.setStyleSheet(f"color: rgb(45, 105, 45); font-size: {self.rescale_w(28)}px;")
        lbl_welcome.setText("Welcome")
        left_layout.addWidget(lbl_welcome)
        # release notes
        self.setup_command_link_button(self.clb_release_notes, "Release Notes",
                                       ':/images/Notepad-Bloc-notes-icon-48x48.png')
        left_layout.addWidget(self.clb_release_notes)
        # sample datasets
        self.setup_command_link_button(self.clb_sample_datasets, "Sample Datasets",
                                       ':/images/download-icon-48x48.png')
        left_layout.addWidget(self.clb_sample_datasets)
        # Tutorials Label
        lbl_tutorials = QLabel()
        lbl_tutorials.setStyleSheet(f"color: rgb(45, 105, 45); font-size: {self.rescale_w(28)}px;")
        lbl_tutorials.setText("Tutorials")
        left_layout.addWidget(lbl_tutorials)
        # Mantid Introduction
        self.setup_command_link_button(self.clb_mantid_introduction, "Mantid Introduction",
                                       ':/images/Misc-Tutorial-icon-48x48.png')
        left_layout.addWidget(self.clb_mantid_introduction)
        # Introduction to python
        self.setup_command_link_button(self.clb_python_introduction, "Introduction to Python",
                                       ':/images/Python-icon-48x48.png')
        left_layout.addWidget(self.clb_python_introduction)
        # Python in Mantid
        self.setup_command_link_button(self.clb_python_in_mantid, "Python In Mantid",
                                       ':/images/Circle_cog_48x48.png')
        left_layout.addWidget(self.clb_python_in_mantid)
        # Extending Mantid with python
        self.setup_command_link_button(self.clb_extending_mantid, "Extending Mantid with Python",
                                       ':/images/Plugin-Python-icon-48x48.png')
        left_layout.addWidget(self.clb_extending_mantid)

        # right hand side Setup and facility icons
        right_layout = QVBoxLayout()
        right_layout.setSpacing(0)
        # personal setup
        grp_personal_setup = QGroupBox()
        grp_personal_setup.setStyleSheet(f"""QGroupBox {{
     border: {self.rescale_w(3)}px solid  rgb(38, 128, 20);;
     border-radius: {self.rescale_w(10)}px;
     background-color: rgb(240, 240, 240);
}}
QGroupBox QLabel{{
    font: {self.rescale_w(12)}px;
    color: rgb(121, 121, 121);
}}
QGroupBox QComboBox{{
    font: {self.rescale_w(12)}px;
}}
font: {self.rescale_w(12)}px;
""")
        grp_personal_setup_layout = QVBoxLayout()
        grp_personal_setup_layout.setContentsMargins(self.rescale_w(9),
                                                     self.rescale_h(1),
                                                     self.rescale_w(9),
                                                     self.rescale_h(9))
        grp_personal_setup_layout.setSpacing(0)
        grp_personal_setup.setLayout(grp_personal_setup_layout)
        lbl_personal_setup = QLabel()
        lbl_personal_setup.setStyleSheet(f"color: rgb(38, 128, 20);\nfont-size: {self.rescale_w(18)}px;")
        lbl_personal_setup.setText("Personal Setup")
        lbl_personal_setup.setAlignment(Qt.AlignHCenter)
        grp_personal_setup_layout.addWidget(lbl_personal_setup)
        personal_setup_form_layout = QFormLayout()
        personal_setup_form_layout.setHorizontalSpacing(self.rescale_w(5))
        personal_setup_form_layout.setVerticalSpacing(self.rescale_h(5))
        personal_setup_form_layout.setLabelAlignment(Qt.AlignRight)
        # default Facility
        lbl_default_facilty = QLabel()
        lbl_default_facilty.setText("Default Facility")
        personal_setup_form_layout.addRow(lbl_default_facilty, self.cb_facility)
        # default instrument
        lbl_default_instrument = QLabel()
        lbl_default_instrument.setText("Default Instrument")
        personal_setup_form_layout.addRow(lbl_default_instrument, self.cb_instrument)
        # Set Data Directories
        lbl_mud = QLabel()
        lbl_mud.setText("Set data directories")
        self.pb_manage_user_directories.setText("Manage User Directories")
        personal_setup_form_layout.addRow(lbl_mud, self.pb_manage_user_directories)
        # Usage data
        lbl_allow_usage_data = QLabel()
        lbl_allow_usage_data.setText("Report Usage Data")
        usagelayout = QHBoxLayout()
        usagelayout.setContentsMargins(0, 0, 0, 0)
        self.chk_allow_usage_data.setChecked(True)
        self.chk_allow_usage_data.setStyleSheet(f"padding: {self.rescale_w(4)}px;")
        usagelayout.addWidget(self.chk_allow_usage_data)
        usagelayout.addSpacerItem(QSpacerItem(self.rescale_w(40), self.rescale_h(20), hPolicy=QSizePolicy.Expanding))
        self.lbl_privacy_policy.setText(r'<html><head/><body><p>'
                                        r'<a href="https://www.mantidproject.org/MantidProject:Privacy_policy'
                                        r'#Usage_Data_recorded_in_Mantid">'
                                        r'<span style=" text-decoration: underline; color:#0000ff;">'
                                        r'Privacy Policy</span></a></p></body></html>')
        self.lbl_privacy_policy.setOpenExternalLinks(False)
        usagelayout.addWidget(self.lbl_privacy_policy)
        personal_setup_form_layout.addRow(lbl_allow_usage_data,usagelayout)
        grp_personal_setup_layout.addLayout(personal_setup_form_layout)
        right_layout.addWidget(grp_personal_setup)
        right_layout.addSpacerItem(QSpacerItem(self.rescale_w(20), self.rescale_h(40), vPolicy=QSizePolicy.Expanding))

        # facility icons
        # Row one
        icon_layout_top = QHBoxLayout()
        icon_layout_top.setContentsMargins(0, self.rescale_h(10), 0, 0)
        icon_layout_top.setSpacing(0)
        icon_layout_top.addWidget(self.create_label_with_image(112, 50, ':/images/ISIS_Logo_Transparent.gif'))
        icon_layout_top.addSpacerItem(QSpacerItem(self.rescale_w(10), self.rescale_h(20), hPolicy=QSizePolicy.Fixed))
        icon_layout_top.addWidget(self.create_label_with_image(94, 50, ':/images/ess_logo_transparent_small.png'))
        icon_layout_top.addSpacerItem(QSpacerItem(self.rescale_w(40), 20,hPolicy=QSizePolicy.Expanding))
        right_layout.addLayout(icon_layout_top)
        # Row two
        icon_layout_middle = QHBoxLayout()
        icon_layout_middle.setContentsMargins(0, self.rescale_h(10), 0, 0)
        icon_layout_middle.setSpacing(0)
        icon_layout_middle.addWidget(self.create_label_with_image(200, 30, ':/images/Ornl_hfir_sns_logo_small.png'))
        icon_layout_middle.addSpacerItem(QSpacerItem(self.rescale_w(40), self.rescale_h(20),
                                                     hPolicy=QSizePolicy.Expanding))
        right_layout.addLayout(icon_layout_middle)
        # Row three
        icon_layout_bottom = QHBoxLayout()
        icon_layout_bottom.setContentsMargins(0, self.rescale_h(10), 0, 0)
        icon_layout_bottom.setSpacing(0)
        icon_layout_bottom.addWidget(self.create_label_with_image(110, 40, ':/images/Tessella_Logo_Transparent.gif'))
        icon_layout_bottom.addSpacerItem(QSpacerItem(self.rescale_w(10), self.rescale_h(20), hPolicy=QSizePolicy.Fixed))
        icon_layout_bottom.addWidget(self.create_label_with_image(50, 50, ':/images/ILL_logo.png'))
        icon_layout_bottom.addSpacerItem(QSpacerItem(self.rescale_w(10), self.rescale_h(20), hPolicy=QSizePolicy.Fixed))
        icon_layout_bottom.addWidget(self.create_label_with_image(92, 50, ':/images/CSNS_Logo_Short.png'))
        icon_layout_bottom.addSpacerItem(QSpacerItem(self.rescale_w(40), self.rescale_h(20),
                                                     hPolicy=QSizePolicy.Expanding))
        right_layout.addLayout(icon_layout_bottom)

        # end the two box layout
        two_box_layout.addLayout(left_layout)
        two_box_layout.addLayout(right_layout)
        parent_layout.addLayout(two_box_layout)

        # footer
        footer_layout = QHBoxLayout()
        # do not show again
        do_not_show_layout = QVBoxLayout()
        do_not_show_layout.setContentsMargins(self.rescale_w(15), 0, 0, 0)
        do_not_show_layout.setSpacing(self.rescale_w(2))
        do_not_show_layout.addSpacerItem(QSpacerItem(1,self.rescale_h(1), vPolicy=QSizePolicy.Expanding))
        lbl_update = QLabel()
        lbl_update.setMinimumSize(self.rescale_w(400),0)
        lbl_update.setStyleSheet("color: rgb(25,125,25);")
        lbl_update.setText('You can revisit this dialog by selecting "About" on the Help menu.')
        lbl_update.setAlignment(Qt.AlignBottom)
        do_not_show_layout.addWidget(lbl_update)

        do_not_show_checkbox_layout = QHBoxLayout()
        self.chk_do_not_show_until_next_release.setChecked(True)
        do_not_show_checkbox_layout.addWidget(self.chk_do_not_show_until_next_release)
        do_not_show_checkbox_layout.addSpacerItem(QSpacerItem(self.rescale_w(10), self.rescale_h(2),
                                                              hPolicy=QSizePolicy.Fixed))
        lbl_do_not_show = QLabel()
        lbl_do_not_show.setStyleSheet("color: rgb(25,125,25);")
        lbl_do_not_show.setText('Do not show again until next release')
        do_not_show_checkbox_layout.addWidget(lbl_do_not_show)
        do_not_show_checkbox_layout.addSpacerItem(QSpacerItem(self.rescale_w(40),10, hPolicy=QSizePolicy.Expanding))
        do_not_show_layout.addLayout(do_not_show_checkbox_layout)
        footer_layout.addLayout(do_not_show_layout)

        # Close button
        close_button_layout = QVBoxLayout()
        close_button_layout.addSpacerItem(QSpacerItem(20,self.rescale_h(15), vPolicy=QSizePolicy.Expanding))
        self.pb_close.setText("Close")
        self.pb_close.setDefault(True)
        close_button_layout.addWidget(self.pb_close)
        footer_layout.addLayout(close_button_layout)
        footer_layout.addSpacerItem(QSpacerItem(self.rescale_w(100), self.rescale_h(20), hPolicy=QSizePolicy.Fixed))
        parent_layout.addLayout(footer_layout)
        self.setLayout(parent_layout)

        self.setAttribute(Qt.WA_DeleteOnClose, True)

    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

    def create_label_with_image(self, width, height, image_location):
        label_with_image = QLabel()
        label_with_image.setMinimumSize(self.rescale_w(width), self.rescale_h(height))
        label_with_image.setMaximumSize(self.rescale_w(width), self.rescale_h(height))
        label_with_image.setPixmap(QPixmap(image_location))
        label_with_image.setScaledContents(True)
        return label_with_image

    def customize_layout(self, version_text, date_text):
        self.setWindowTitle(self.windowTitle() + " "
                            + version_text)
        version_label = version_text
        # add a date if it is an official release
        if date_text and len(version_text) < 10:
            # strip off the first few characters that will be "day, "
            version_label += " ({0})".format(date_text[5:])
        self.lbl_version.setText(self.lbl_version.text() + version_label)

    def closeEvent(self, event):
        self.presenter.save_on_closing()
        self.deleteLater()
        super(AboutView, self).closeEvent(event)
Example #17
0
class FigureCanvas(QFrame):
    """
    A basic widget on which can be painted a custom png, jpg, or svg image.
    """

    def __init__(self, parent=None):
        super(FigureCanvas, self).__init__(parent)
        self.setLineWidth(2)
        self.setMidLineWidth(1)
        self.setStyleSheet("background-color: white")

        self.fig = None
        self.fmt = None
        self.fwidth, self.fheight = 200, 200

    def clear_canvas(self):
        """Clear the figure that was painted on the widget."""
        self.fig = None
        self.fmt = None
        self._qpix_buffer = []
        self.repaint()

    def load_figure(self, fig, fmt):
        """
        Load the figure from a png, jpg, or svg image, convert it in
        a QPixmap, and force a repaint of the widget.
        """
        self.fig = fig
        self.fmt = fmt

        if fmt in ['image/png', 'image/jpeg']:
            self._qpix_orig = QPixmap()
            self._qpix_orig.loadFromData(fig, fmt.upper())
        elif fmt == 'image/svg+xml':
            self._qpix_orig = QPixmap(svg_to_image(fig))

        self._qpix_buffer = [self._qpix_orig]
        self.fwidth = self._qpix_orig.width()
        self.fheight = self._qpix_orig.height()

    def paintEvent(self, event):
        """Qt method override to paint a custom image on the Widget."""
        super(FigureCanvas, self).paintEvent(event)
        # Prepare the rect on which the image is going to be painted :
        fw = self.frameWidth()
        rect = QRect(0 + fw, 0 + fw,
                     self.size().width() - 2 * fw,
                     self.size().height() - 2 * fw)

        if self.fig is None:
            return

        # Check/update the qpixmap buffer :
        qpix2paint = None
        for qpix in self._qpix_buffer:
            if qpix.size().width() == rect.width():
                qpix2paint = qpix
                break
        else:
            if self.fmt in ['image/png', 'image/jpeg']:
                qpix2paint = self._qpix_orig.scaledToWidth(
                    rect.width(), mode=Qt.SmoothTransformation)
            elif self.fmt == 'image/svg+xml':
                qpix2paint = QPixmap(svg_to_image(self.fig, rect.size()))
            self._qpix_buffer.append(qpix2paint)

        if qpix2paint is not None:
            # Paint the image on the widget :
            qp = QPainter()
            qp.begin(self)
            qp.drawPixmap(rect, qpix2paint)
            qp.end()
Example #18
0
class FigureCanvas(QFrame):
    """
    A basic widget on which can be painted a custom png, jpg, or svg image.
    """

    def __init__(self, parent=None, background_color=None):
        super(FigureCanvas, self).__init__(parent)
        self.setLineWidth(2)
        self.setMidLineWidth(1)
        self.setObjectName("figcanvas")
        self.setStyleSheet(
            "#figcanvas {background-color:" + str(background_color) + "}")

        self.fig = None
        self.fmt = None
        self.fwidth, self.fheight = 200, 200
        self._blink_flag = False

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.context_menu_requested)

    def context_menu_requested(self, event):
        """Popup context menu."""
        if self.fig:
            pos = QPoint(event.x(), event.y())
            context_menu = QMenu(self)
            context_menu.addAction(ima.icon('editcopy'), "Copy Image",
                                   self.copy_figure,
                                   QKeySequence(
                                       get_shortcut('plots', 'copy')))
            context_menu.popup(self.mapToGlobal(pos))

    @Slot()
    def copy_figure(self):
        """Copy figure to clipboard."""
        if self.fmt in ['image/png', 'image/jpeg']:
            qpixmap = QPixmap()
            qpixmap.loadFromData(self.fig, self.fmt.upper())
            QApplication.clipboard().setImage(qpixmap.toImage())
        elif self.fmt == 'image/svg+xml':
            svg_to_clipboard(self.fig)
        else:
            return

        self.blink_figure()

    def blink_figure(self):
        """Blink figure once."""
        if self.fig:
            self._blink_flag = not self._blink_flag
            self.repaint()
            if self._blink_flag:
                timer = QTimer()
                timer.singleShot(40, self.blink_figure)

    def clear_canvas(self):
        """Clear the figure that was painted on the widget."""
        self.fig = None
        self.fmt = None
        self._qpix_buffer = []
        self.repaint()

    def load_figure(self, fig, fmt):
        """
        Load the figure from a png, jpg, or svg image, convert it in
        a QPixmap, and force a repaint of the widget.
        """
        self.fig = fig
        self.fmt = fmt

        if fmt in ['image/png', 'image/jpeg']:
            self._qpix_orig = QPixmap()
            self._qpix_orig.loadFromData(fig, fmt.upper())
        elif fmt == 'image/svg+xml':
            self._qpix_orig = QPixmap(svg_to_image(fig))

        self._qpix_buffer = [self._qpix_orig]
        self.fwidth = self._qpix_orig.width()
        self.fheight = self._qpix_orig.height()

    def paintEvent(self, event):
        """Qt method override to paint a custom image on the Widget."""
        super(FigureCanvas, self).paintEvent(event)
        # Prepare the rect on which the image is going to be painted :
        fw = self.frameWidth()
        rect = QRect(0 + fw, 0 + fw,
                     self.size().width() - 2 * fw,
                     self.size().height() - 2 * fw)

        if self.fig is None or self._blink_flag:
            return

        # Check/update the qpixmap buffer :
        qpix2paint = None
        for qpix in self._qpix_buffer:
            if qpix.size().width() == rect.width():
                qpix2paint = qpix
                break
        else:
            if self.fmt in ['image/png', 'image/jpeg']:
                qpix2paint = self._qpix_orig.scaledToWidth(
                    rect.width(), mode=Qt.SmoothTransformation)
            elif self.fmt == 'image/svg+xml':
                qpix2paint = QPixmap(svg_to_image(self.fig, rect.size()))
            self._qpix_buffer.append(qpix2paint)

        if qpix2paint is not None:
            # Paint the image on the widget :
            qp = QPainter()
            qp.begin(self)
            qp.drawPixmap(rect, qpix2paint)
            qp.end()
Example #19
0
class FigureCanvas(QFrame):
    """
    A basic widget on which can be painted a custom png, jpg, or svg image.
    """

    sig_context_menu_requested = Signal(QPoint)
    """
    This signal is emitted to request a context menu.

    Parameters
    ----------
    point: QPoint
        The QPoint in global coordinates where the menu was requested.
    """

    def __init__(self, parent=None, background_color=None):
        super().__init__(parent)
        self.setLineWidth(2)
        self.setMidLineWidth(1)
        self.setObjectName("figcanvas")
        self.setStyleSheet(
            "#figcanvas {background-color:" + str(background_color) + "}")

        self.fig = None
        self.fmt = None
        self.fwidth, self.fheight = 200, 200
        self._blink_flag = False

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(
            self.sig_context_menu_requested)

    @Slot()
    def copy_figure(self):
        """Copy figure to clipboard."""
        if self.fmt in ['image/png', 'image/jpeg']:
            qpixmap = QPixmap()
            qpixmap.loadFromData(self.fig, self.fmt.upper())
            QApplication.clipboard().setImage(qpixmap.toImage())
        elif self.fmt == 'image/svg+xml':
            svg_to_clipboard(self.fig)
        else:
            return

        self.blink_figure()

    def blink_figure(self):
        """Blink figure once."""
        if self.fig:
            self._blink_flag = not self._blink_flag
            self.repaint()
            if self._blink_flag:
                timer = QTimer()
                timer.singleShot(40, self.blink_figure)

    def clear_canvas(self):
        """Clear the figure that was painted on the widget."""
        self.fig = None
        self.fmt = None
        self._qpix_scaled = None
        self.repaint()

    def load_figure(self, fig, fmt):
        """
        Load the figure from a png, jpg, or svg image, convert it in
        a QPixmap, and force a repaint of the widget.
        """
        self.fig = fig
        self.fmt = fmt

        if fmt in ['image/png', 'image/jpeg']:
            self._qpix_orig = QPixmap()
            self._qpix_orig.loadFromData(fig, fmt.upper())
        elif fmt == 'image/svg+xml':
            self._qpix_orig = QPixmap(svg_to_image(fig))

        self._qpix_scaled = self._qpix_orig
        self.fwidth = self._qpix_orig.width()
        self.fheight = self._qpix_orig.height()

    def paintEvent(self, event):
        """Qt method override to paint a custom image on the Widget."""
        super().paintEvent(event)
        # Prepare the rect on which the image is going to be painted.
        fw = self.frameWidth()
        rect = QRect(0 + fw, 0 + fw,
                     self.size().width() - 2 * fw,
                     self.size().height() - 2 * fw)

        if self.fig is None or self._blink_flag:
            return

        # Prepare the scaled qpixmap to paint on the widget.
        if (self._qpix_scaled is None or
                self._qpix_scaled.size().width() != rect.width()):
            if self.fmt in ['image/png', 'image/jpeg']:
                self._qpix_scaled = self._qpix_orig.scaledToWidth(
                    rect.width(), mode=Qt.SmoothTransformation)
            elif self.fmt == 'image/svg+xml':
                self._qpix_scaled = QPixmap(svg_to_image(
                    self.fig, rect.size()))

        if self._qpix_scaled is not None:
            # Paint the image on the widget.
            qp = QPainter()
            qp.begin(self)
            qp.drawPixmap(rect, self._qpix_scaled)
            qp.end()
Example #20
0
class FigureCanvas(QFrame):
    """
    A basic widget on which can be painted a custom png, jpg, or svg image.
    """
    def __init__(self, parent=None, background_color=None):
        super(FigureCanvas, self).__init__(parent)
        self.setLineWidth(2)
        self.setMidLineWidth(1)
        self.setObjectName("figcanvas")
        self.setStyleSheet("#figcanvas {background-color:" +
                           str(background_color) + "}")

        self.fig = None
        self.fmt = None
        self.fwidth, self.fheight = 200, 200
        self._blink_flag = False

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.context_menu_requested)

    def context_menu_requested(self, event):
        """Popup context menu."""
        if self.fig:
            pos = QPoint(event.x(), event.y())
            context_menu = QMenu(self)
            context_menu.addAction(ima.icon('editcopy'), "Copy Image",
                                   self.copy_figure,
                                   QKeySequence(get_shortcut('plots', 'copy')))
            context_menu.popup(self.mapToGlobal(pos))

    @Slot()
    def copy_figure(self):
        """Copy figure to clipboard."""
        if self.fmt in ['image/png', 'image/jpeg']:
            qpixmap = QPixmap()
            qpixmap.loadFromData(self.fig, self.fmt.upper())
            QApplication.clipboard().setImage(qpixmap.toImage())
        elif self.fmt == 'image/svg+xml':
            svg_to_clipboard(self.fig)
        else:
            return

        self.blink_figure()

    def blink_figure(self):
        """Blink figure once."""
        if self.fig:
            self._blink_flag = not self._blink_flag
            self.repaint()
            if self._blink_flag:
                timer = QTimer()
                timer.singleShot(40, self.blink_figure)

    def clear_canvas(self):
        """Clear the figure that was painted on the widget."""
        self.fig = None
        self.fmt = None
        self._qpix_buffer = []
        self.repaint()

    def load_figure(self, fig, fmt):
        """
        Load the figure from a png, jpg, or svg image, convert it in
        a QPixmap, and force a repaint of the widget.
        """
        self.fig = fig
        self.fmt = fmt

        if fmt in ['image/png', 'image/jpeg']:
            self._qpix_orig = QPixmap()
            self._qpix_orig.loadFromData(fig, fmt.upper())
        elif fmt == 'image/svg+xml':
            self._qpix_orig = QPixmap(svg_to_image(fig))

        self._qpix_buffer = [self._qpix_orig]
        self.fwidth = self._qpix_orig.width()
        self.fheight = self._qpix_orig.height()

    def paintEvent(self, event):
        """Qt method override to paint a custom image on the Widget."""
        super(FigureCanvas, self).paintEvent(event)
        # Prepare the rect on which the image is going to be painted :
        fw = self.frameWidth()
        rect = QRect(0 + fw, 0 + fw,
                     self.size().width() - 2 * fw,
                     self.size().height() - 2 * fw)

        if self.fig is None or self._blink_flag:
            return

        # Check/update the qpixmap buffer :
        qpix2paint = None
        for qpix in self._qpix_buffer:
            if qpix.size().width() == rect.width():
                qpix2paint = qpix
                break
        else:
            if self.fmt in ['image/png', 'image/jpeg']:
                qpix2paint = self._qpix_orig.scaledToWidth(
                    rect.width(), mode=Qt.SmoothTransformation)
            elif self.fmt == 'image/svg+xml':
                qpix2paint = QPixmap(svg_to_image(self.fig, rect.size()))
            self._qpix_buffer.append(qpix2paint)

        if qpix2paint is not None:
            # Paint the image on the widget :
            qp = QPainter()
            qp.begin(self)
            qp.drawPixmap(rect, qpix2paint)
            qp.end()
Example #21
0
    def __init__(self, parent):
        super(KiteIntegrationInfo, self).__init__(parent)
        # Images
        images_layout = QHBoxLayout()
        icon_filename = 'kite_completions'
        image_path = get_image_path(icon_filename)
        image = QPixmap(image_path)
        image_label = QLabel()
        image_label = QLabel()
        image_height = int(image.height() * DialogStyle.IconScaleFactor)
        image_width = int(image.width() * DialogStyle.IconScaleFactor)
        image = image.scaled(image_width, image_height, Qt.KeepAspectRatio,
                             Qt.SmoothTransformation)
        image_label.setPixmap(image)

        images_layout.addStretch()
        images_layout.addWidget(image_label)
        images_layout.addStretch()

        ilayout = QHBoxLayout()
        ilayout.addLayout(images_layout)

        # Label
        integration_label_title = QLabel(
            "Get better code completions in Spyder")
        integration_label_title.setStyleSheet(
            f"font-size: {DialogStyle.TitleFontSize}")
        integration_label_title.setWordWrap(True)
        integration_label = QLabel(
            _("Now Spyder can use Kite to provide better code "
              "completions for key packages in the scientific Python "
              "Ecosystem. Install Kite for a better editor experience in "
              "Spyder. <br><br>Kite is free to use but is not open "
              "source. <a href=\"{kite_url}\">Learn more about Kite </a>").
            format(kite_url=KITE_SPYDER_URL))
        integration_label.setStyleSheet(
            f"font-size: {DialogStyle.ContentFontSize}")
        integration_label.setOpenExternalLinks(True)
        integration_label.setWordWrap(True)
        integration_label.setFixedWidth(360)
        label_layout = QVBoxLayout()
        label_layout.addWidget(integration_label_title)
        label_layout.addWidget(integration_label)

        # Buttons
        install_button_color = QStylePalette.COLOR_ACCENT_2
        install_button_hover = QStylePalette.COLOR_ACCENT_3
        install_button_pressed = QStylePalette.COLOR_ACCENT_4
        dismiss_button_color = QStylePalette.COLOR_BACKGROUND_4
        dismiss_button_hover = QStylePalette.COLOR_BACKGROUND_5
        dismiss_button_pressed = QStylePalette.COLOR_BACKGROUND_6
        font_color = QStylePalette.COLOR_TEXT_1
        buttons_layout = QHBoxLayout()
        install_button = QPushButton(_('Install Kite'))
        install_button.setAutoDefault(False)
        install_button.setStyleSheet(
            ("QPushButton {{ "
             "background-color: {background_color};"
             "border-color: {border_color};"
             "font-size: {font_size};"
             "color: {font_color};"
             "padding: {padding}}}"
             "QPushButton:hover:!pressed {{ "
             "background-color: {color_hover}}}"
             "QPushButton:pressed {{ "
             "background-color: {color_pressed}}}").format(
                 background_color=install_button_color,
                 border_color=install_button_color,
                 font_size=DialogStyle.ButtonsFontSize,
                 font_color=font_color,
                 padding=DialogStyle.ButtonsPadding,
                 color_hover=install_button_hover,
                 color_pressed=install_button_pressed))
        dismiss_button = QPushButton(_('Dismiss'))
        dismiss_button.setAutoDefault(False)
        dismiss_button.setStyleSheet(
            ("QPushButton {{ "
             "background-color: {background_color};"
             "border-color: {border_color};"
             "font-size: {font_size};"
             "color: {font_color};"
             "padding: {padding}}}"
             "QPushButton:hover:!pressed {{ "
             "background-color: {color_hover}}}"
             "QPushButton:pressed {{ "
             "background-color: {color_pressed}}}").format(
                 background_color=dismiss_button_color,
                 border_color=dismiss_button_color,
                 font_size=DialogStyle.ButtonsFontSize,
                 font_color=font_color,
                 padding=DialogStyle.ButtonsPadding,
                 color_hover=dismiss_button_hover,
                 color_pressed=dismiss_button_pressed))
        buttons_layout.addStretch()
        buttons_layout.addWidget(install_button)
        if not MAC:
            buttons_layout.addSpacing(10)
        buttons_layout.addWidget(dismiss_button)

        # Buttons with label
        vertical_layout = QVBoxLayout()
        if not MAC:
            vertical_layout.addStretch()
            vertical_layout.addLayout(label_layout)
            vertical_layout.addSpacing(20)
            vertical_layout.addLayout(buttons_layout)
            vertical_layout.addStretch()
        else:
            vertical_layout.addLayout(label_layout)
            vertical_layout.addLayout(buttons_layout)

        general_layout = QHBoxLayout()
        general_layout.addStretch()
        general_layout.addLayout(ilayout)
        general_layout.addSpacing(15)
        general_layout.addLayout(vertical_layout)
        general_layout.addStretch()

        self.setLayout(general_layout)

        # Signals
        install_button.clicked.connect(self.sig_install_button_clicked)
        dismiss_button.clicked.connect(self.sig_dismiss_button_clicked)

        self.setStyleSheet(
            f"background-color: {QStylePalette.COLOR_BACKGROUND_2}")
        self.setContentsMargins(18, 40, 18, 40)
        if not MAC:
            self.setFixedSize(800, 350)