def __init__(self, loader): self._loader = loader self._path = None self._exif = None self._ready = False self._magnify = False self._label = QStaticText() self._font = QFont("Verdana", 9) self._font.setBold(True) self._pen = QPen(QColor(0x00FF00)) super(Viewer, self).__init__()
def __init__(self, palette, scale): """ :param palette: palette used for showing continuous values :type palette: ContinuousPaletteGenerator :param scale: an instance of DiscretizedScale that defines the conversion of values into bins :type scale: DiscretizedScale """ super().__init__(None) self.palette = palette self.scale = scale cuts = ["{0:.{1}f}".format(scale.offset + i * scale.width, scale.decimals) for i in range(scale.bins + 1)] self.labels = [QStaticText("{} - {}".format(fr, to)) for fr, to in zip(cuts, cuts[1:])] for label in self.labels: label.prepare() self.text_width = max(label.size().width() for label in self.labels)
class Viewer(QWidget): def __init__(self, loader): self._loader = loader self._path = None self._exif = None self._ready = False self._magnify = False self._label = QStaticText() self._font = QFont("Verdana", 9) self._font.setBold(True) self._pen = QPen(QColor(0x00FF00)) super(Viewer, self).__init__() def paintEvent(self, unused_paint_event): # Signal handler. canvas = QPainter() canvas.begin(self) self._draw_widget(canvas) canvas.end() def _draw_widget(self, canvas): if not self._ready: return size = self.size() if self._magnify: image_size = self._image.size() x = self._lens_x - size.width() / 2 if x + size.width() > image_size.width(): x = image_size.width() - size.width() if x < 0: x = 0 y = self._lens_y - size.height() / 2 if y + size.height() > image_size.height(): y = image_size.height() - size.height() if y < 0: y = 0 x0 = 0 if image_size.width() > size.width() else (size.width() - image_size.width()) / 2 y0 = 0 if image_size.height() > size.height() else (size.height() - image_size.height()) / 2 canvas.drawPixmap(x0, y0, self._image, x, y, size.width(), size.height()) else: scaled_image_size = self._scaled_image.size() x = (size.width() - scaled_image_size.width()) / 2 y = (size.height() - scaled_image_size.height()) / 2 canvas.drawPixmap(x, y, self._scaled_image) canvas.setFont(self._font) canvas.setPen(self._pen) canvas.drawStaticText(2, 2, self._label) def resizeEvent(self, unused_resize_event): # Signal handler. self._create_scaled_image() self.repaint() def reset_path(self): self._path = None self._reload() def set_path(self, path): self._path = path self._reload() def _reload(self): self._image = self._loader.load_image(self._path) image_size = self._image.size() self._ready = image_size.width() or image_size.height() if self._ready: self._label.setText("%s [%dx%d]" % (self._path, image_size.width(), image_size.height())) self._create_scaled_image() self.repaint() def _create_scaled_image(self): self._scaled_image = None if not self._ready: return image_size = self._image.size() size = self.size() if (image_size.width() <= size.width()) and (image_size.height() <= size.height()): self._scaled_image = self._image else: self._scaled_image = self._image.scaled(size.width(), size.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation) def _update_lens(self, x, y): size = self.size() image_size = self._image.size() scaled_image_size = self._scaled_image.size() draw_x = (size.width() - scaled_image_size.width()) / 2 draw_y = (size.height() - scaled_image_size.height()) / 2 self._lens_x = ((x - draw_x) * image_size.width()) / scaled_image_size.width() self._lens_y = ((y - draw_y) * image_size.height()) / scaled_image_size.height() self.repaint() def mousePressEvent(self, mouse_event): # Signal handler. if not self._ready: return image_size = self._image.size() size = self.size() if (image_size.width() > size.width()) or (image_size.height() > size.height()): self._magnify = True self._update_lens(mouse_event.x(), mouse_event.y()) def mouseReleaseEvent(self, unused_mouse_event): # Signal handler. self._magnify = False self.repaint() def mouseMoveEvent(self, mouse_event): # Signal handler. if not self._ready: return if self._magnify: self._update_lens(mouse_event.x(), mouse_event.y())
def __set_sttext(self): mat = QTransform() self.montexte = QStaticText(self.texte) self.montexte.prepare(mat, self.police) self.set_size(self.montexte.size().width(), self.montexte.size().height()) return self.montexte
class Magnifier(QtGui.QGraphicsPixmapItem): def __init__(self, main, parent=None, img=None, graphic=None, scene=None, police=None, texte=None): super(Magnifier, self).__init__(parent, scene) self.main = main d = dict(shape="square", width=0, height=0, img=img, police=police, texte=texte, graphic=graphic, scene=scene, pix=None, cur_pos=None, old_X=None, old_Y=None) for key, value in d.items(): setattr(self, key, value) self.setFlags(QtGui.QGraphicsItem.ItemIsMovable | QtGui.QGraphicsItem.ItemIsFocusable) self.setAcceptHoverEvents(True) self._moved = Moved() # Create signals # Signals are class defined at the end of this script # http://docs.python.org/howto/descriptor.html def positionChanged(): def fget(self): return self._moved.positionChanged return locals() positionChanged = property(**positionChanged()) def set_size(self, width, height): self.width = self.montexte.size().width() self.height = self.montexte.size().height() def setup(self): """setup the magnifier. """ self.cur_pos = self.__get_center() self.setPos(self.cur_pos[2], self.cur_pos[3]) self.__create_magnifier() if not self.old_X: self.recenter_magnifying_glass() self.old_X, self.old_Y = self.pos().x(), self.pos().y() def __create_magnifier(self): """Call functions to build the magnifying glass. """ self.__set_sttext() self.orig = self.__get_orig_center() self.__set_square() def __set_sttext(self): mat = QTransform() self.montexte = QStaticText(self.texte) self.montexte.prepare(mat, self.police) self.set_size(self.montexte.size().width(), self.montexte.size().height()) return self.montexte def __set_square(self): self.txt = self.__set_sttext() rect = QtCore.QRect(0, 0, self.width, self.height) color = QtGui.QColor() color.setRgb(0, 0, 0, 0) self.pix = QtGui.QPixmap(QtCore.QSize(self.width + 2, self.height + 2)) self.pix.fill(color) painter = QtGui.QPainter() painter.begin(self.pix) painter.setFont(self.police) painter.drawStaticText(0, 0, self.montexte) painter.end() self.setPixmap(self.pix) return self.pix def __update(self, x, y): """Update the original coordinates when the magnifying glass is moved. """ self.orig[2] += x self.orig[3] += y def move_by(self, x, y): self.moveBy(x, y) self.__update(x, y) def __get_center(self): """Return the center of the scene. This assume both scene and image have the same geometry. Returns: list[center X, center Y, top left x, top left Y] """ cX, cY = int(self.scene.width() / 2), int(self.scene.height() / 2) posX, posY = cX - int(self.width / 2), cY - int(self.height / 2) return [cX, cY, posX, posY] def get_pos(self): """Return position of magnifying glass. Returns: QPointF(float, float) """ return self.pos() def set_pos(self, pos): """Move magnifying glass to pos. Keyword arguments: pos -- QPointF """ if isinstance(pos, QtCore.QPointF): X, Y = pos.x(), pos.y() else: X, Y = pos[0], pos[1] cur = self.pos() m_X, m_Y = X - self.pos().x(), Y - self.pos().y() self.moveBy(m_X, m_Y) self.__update(m_X, m_Y) self.positionChanged.emit([cur.x(), cur.y(), X, Y]) def __get_orig_center(self): """Return the original position at the creation of the magnifier. Returns : list -- center of pixmap magnified and corner top left. """ cX, cY = int(self.graphic.width() / 2), int(self.graphic.height() / 2) posX, posY = cX - int(self.width / 2), cY - int(self.height / 2) return [cX, cY, posX, posY] def recenter_magnifying_glass(self): """Move the magnifying glass from center image to center graphicsView. """ timer = QtCore.QTimeLine(1000); timer.setFrameRange(0, 50) self.animation = QtGui.QGraphicsItemAnimation() self.animation.setItem(self); self.animation.setTimeLine(timer) c = self.width / 2.0 dest = self.graphic.mapToScene(self.graphic.width() / 2 - c, self.graphic.height() / 2 - c) deltaX = dest.x() - self.pos().x() deltaY = dest.y() - self.pos().y() j, k, l, m = deltaX / 50, deltaY / 50, self.pos().x(), self.pos().y() for i in range (50): l, m = l + j, m + k self.animation.setPosAt(i / 50.0, QtCore.QPointF(l, m)) self.__update(j, k) timer.start() #-------------------------------- # Events #-------------------------------- def mousePressEvent(self, event, auto=0): # auto = 0 if event is caused by self # auto = 1 if event is given by other, i.e. event filter of main if auto: pos = self.graphic.mapToScene(event.pos()) else: pos = event.scenePos() if event.button() == 1: self.old_X, self.old_Y = pos.x(), pos.y() event.accept() else: event.ignore() def mouseMoveEvent(self, event, auto=0): # auto = 0 if event is caused by self # auto = 1 if event is given by other, i.e. event filter of main if auto: pos = self.graphic.mapToScene(event.pos()) else: pos = event.scenePos() if event.button() == 2: return cur = self.pos() X, Y = pos.x(), pos.y() m_X, m_Y = X - self.old_X, Y - self.old_Y self.old_X, self.old_Y = X, Y self.moveBy(m_X, m_Y) self.__update(m_X, m_Y) event.accept() def hoverEnterEvent(self, event): shape = QtGui.QPixmap("resources/cross_cursor_32.png") cursor = QtGui.QCursor(shape, -1, -1) self.setCursor(cursor) def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Escape: self.quit() elif event.key() == 16777234: # arrow LEFT self.move_by(-5, 0) self.positionChanged.emit([self.pos().x() + 5, self.pos().y(), self.pos().x(), self.pos().y()]) elif event.key() == 16777235: # arrow UP self.move_by(0, -5) self.positionChanged.emit([self.pos().x(), self.pos().y() + 5, self.pos().x(), self.pos().y()]) elif event.key() == 16777236: # arrow RIGHT self.move_by(5, 0) self.positionChanged.emit([self.pos().x() - 5, self.pos().y(), self.pos().x(), self.pos().y()]) elif event.key() == 16777237: # arrow DOWN self.move_by(0, 5) self.positionChanged.emit([self.pos().x(), self.pos().y() - 5, self.pos().x(), self.pos().y()]) elif event.key() == 83: # Key S used for enable / disable shadow effect try: self.main.shadow.setEnabled(not self.main.shadow.isEnabled()) except: pass