def on_item_changed(self, current, previous):
        if not current:
            return
        crc, goodname, path, fname = current.data(Qt.UserRole)

        title = QPixmap(os.path.join(
            self.user_data_path, "title", "%s.png") % crc)
        snapshot = QPixmap(os.path.join(
            self.user_data_path, "snapshot", "%s.png") % crc)

        if title.isNull():
            title = QPixmap(":/title/%s.jpg" % crc)
        if snapshot.isNull():
            snapshot = QPixmap(":/snapshot/%s.jpg" % crc)

        if title.isNull():
            title = QPixmap(":/images/default.png")
        if snapshot.isNull():
            snapshot = QPixmap(":/images/default.png")

        if previous is not None:
            self.titleView.scene().removeItem(self.title_item)
            self.snapshotView.scene().removeItem(self.snapshot_item)

        title_pixmap = title.scaled(
            self.titleView.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        snapshot_pixmap = snapshot.scaled(
            self.snapshotView.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)

        title_item = QGraphicsPixmapItem(title_pixmap)
        snapshot_item = QGraphicsPixmapItem(snapshot_pixmap)
        self.titleView.scene().addItem(title_item)
        self.snapshotView.scene().addItem(snapshot_item)
        self.title_item = title_item
        self.snapshot_item = snapshot_item
Beispiel #2
0
 def on_imagesTree_currentItemChanged(self, current, previous):
     """
     Private slot to show a preview of the selected image.
     
     @param current current image entry (QTreeWidgetItem)
     @param previous old current entry (QTreeWidgetItem)
     """
     if current is None:
         return
     
     imageUrl = QUrl(current.text(1))
     if not imageUrl.host():
         imageUrl.setHost(QUrl(self.siteAddressLabel.text()).host())
         imageUrl.setScheme(QUrl(self.siteAddressLabel.text()).scheme())
     
     import Helpviewer.HelpWindow
     cache = Helpviewer.HelpWindow.HelpWindow.networkAccessManager().cache()
     if cache:
         cacheData = cache.data(imageUrl)
     else:
         cacheData = None
     pixmap = QPixmap()
     invalidPixmap = False
     scene = QGraphicsScene(self.imagePreview)
     if not cacheData:
         invalidPixmap = True
     else:
         pixmap.loadFromData(cacheData.readAll())
         if pixmap.isNull():
             invalidPixmap = True
     if invalidPixmap:
         scene.addText(self.tr("Preview not available."))
     else:
         scene.addPixmap(pixmap)
     self.imagePreview.setScene(scene)
Beispiel #3
0
 def set_background(self, data):
     img = QImage()
     img.loadFromData(data)
     pixmap = QPixmap(img)
     if pixmap.isNull():
         return None
     return pixmap
Beispiel #4
0
	def loadImageDropped(self, urlin):
		pix = QPixmap(urlin.toLocalFile())
		if pix.isNull():
			QMessageBox.critical(self, 'Error', 'An error occured while loading image')
			return False
		self.setPixmap(pix)
		return pix
Beispiel #5
0
    def findIconHelper(self, size = int, themeName = str, iconName = str):
        pixmap = QPixmap()

        if iconName == '' or self.themeName == '':
            return pixmap

        if themeName == '':
            themeName = self.themeName

        if themeName == self.themeName:
            index = self.themeIndex
        else:
            index = self.readThemeIndex(themeName)

        
        subDirs = filter(lambda x:x[0] == str(size), index.dirList)
        
        for iconDir in self.iconDirs:
            if path.exists(path.join(iconDir, themeName)):
                for theme in subDirs:
                    fileName = path.join(iconDir, themeName, theme[1],
                            '%s.png' % str(iconName))
                    fileName_svg = path.join(iconDir, themeName, theme[1],
                            '%s.svg' % str(iconName))
                    logging.debug('Looking for : %s' % fileName)
                    if path.exists(fileName):
                        pixmap.load(fileName)
                        logging.debug('Icon: %s found in theme %s' % \
                                (iconName, themeName))
                        return pixmap
                    elif path.exists(fileName_svg):
                        pixmap.load(fileName_svg)
                        logging.debug('Icon: %s found in %s' % (iconName, iconDir))
                        return pixmap

        for iconDir in self.extraIcons:
            fileName = path.join(iconDir, '%s.png' % str(iconName))
            fileName_svg = path.join(iconDir, '{}.svg'.format(str(iconName)))
            if path.exists(fileName):
                pixmap.load(fileName)
                #print "pixmap ->{}".format(fileName)
                logging.debug('Icon: %s found in %s' % (iconName, iconDir))
                return pixmap
            elif path.exists(fileName_svg):
                    image=QImage(size, size, QImage.Format_RGB32)
                    reader=QImageReader(fileName)
                    reader.read(image)
                    pixmap.convertFromImage(image)
                    logging.debug('Icon: %s found in %s' % (iconName, iconDir))
                    #print "pixmap ->{}".format(fileName)
                    return pixmap

        if len(self._themes) > 0:
            self._themes.pop(0)
            if not len(self._themes) == 0 and pixmap.isNull():
                pixmap = self.findIconHelper(size, self._themes[0], iconName)
        return pixmap
Beispiel #6
0
 def set_img(self, future):
     content = future.result()
     img = QImage()
     img.loadFromData(content)
     pixmap = QPixmap(img)
     if pixmap.isNull():
         return None
     self.img_label.setPixmap(
         pixmap.scaledToWidth(self.img_label.width(),
                              mode=Qt.SmoothTransformation))
Beispiel #7
0
	def loadImage(self):
		filein, _ = QFileDialog.getOpenFileName(self, 'Open image', '', 'Images (*.png *.jpg *.gif *.bmp)')
		if not filein:
			return False
		pix = QPixmap(filein)
		if pix.isNull():
			QMessageBox.critical(self, 'Error', 'An error occured while loading image')
			return False
		self.setPixmap(pix)
		return pix
Beispiel #8
0
 def fillImage(self, pixmap, painter, roi, param, source):
     """Draw image in roi.
     """
     x, y, w, h = roi
     fillPixmap = QPixmap(param.fillPath)
     if not fillPixmap.isNull():
         fillPixmap = fillPixmap.scaled(w, h, QtCore.Qt.IgnoreAspectRatio)
         mask = self.getMask(pixmap, x, y, w, h, param.shape, None,
                             QtCore.Qt.white, QtCore.Qt.black)
         painter.setClipRegion(QtGui.QRegion(QtGui.QBitmap(mask)))
         painter.drawPixmap(x, y, fillPixmap)
         painter.setClipping(False)
 def __init__(self, parent, collection, item):
     QWidget.__init__(self, parent)
     self.setupUi(self)
     self.parent = parent
     self.item = item
     self.collection = collection
     self.header.setText(collection.title)
     self.description.setText(collection.description)
     icon = QPixmap(":/gui/pics/%s" % collection.icon)
     if icon.isNull():
         icon = QPixmap(":/gui/pics/systemsettings.png")
     self.icon.setPixmap(icon)
Beispiel #10
0
class RoundRectItem(QGraphicsObject):
    def __init__(self, bounds, color, parent=None):
        super(RoundRectItem, self).__init__(parent)

        self.fillRect = False
        self.bounds = QRectF(bounds)
        self.pix = QPixmap()

        self.gradient = QLinearGradient()
        self.gradient.setStart(self.bounds.topLeft())
        self.gradient.setFinalStop(self.bounds.bottomRight())
        self.gradient.setColorAt(0, color)
        self.gradient.setColorAt(1, color.darker(200))

        self.setCacheMode(QGraphicsItem.ItemCoordinateCache)

    def setFill(self, fill):
        self.fillRect = fill
        self.update()

    def fill(self):
        return self.fillRect

    fill = pyqtProperty(bool, fill, setFill)

    def paint(self, painter, option, widget):
        painter.setPen(Qt.NoPen)
        painter.setBrush(QColor(0, 0, 0, 64))
        painter.drawRoundedRect(self.bounds.translated(2, 2), 25.0, 25.0)

        if self.fillRect:
            painter.setBrush(QApplication.palette().brush(QPalette.Window))
        else:
            painter.setBrush(self.gradient)

        painter.setPen(QPen(Qt.black, 1))
        painter.drawRoundedRect(self.bounds, 25.0, 25.0)
        if not self.pix.isNull():
            painter.scale(1.95, 1.95)
            painter.drawPixmap(-self.pix.width() / 2, -self.pix.height() / 2, self.pix)

    def boundingRect(self):
        return self.bounds.adjusted(0, 0, 2, 2)

    def pixmap(self):
        return QPixmap(self.pix)

    def setPixmap(self, pixmap):
        self.pix = QPixmap(pixmap)
        self.update()
Beispiel #11
0
 def pixmap_from_url(self, url, callback=None):
     # FIXME: only neteasemusic img url accept the params
     data = {'param': '{0}y{0}'.format(self.width())}
     res = self.request.get(url, data)
     if res is None:
         return None
     img = QImage()
     img.loadFromData(res.content)
     pixmap = QPixmap(img)
     if pixmap.isNull():
         return None
     if callback is not None:
         callback(pixmap)
     return pixmap
Beispiel #12
0
def _init_icon():
    """Initialize the icon of qutebrowser."""
    icon = QIcon()
    fallback_icon = QIcon()
    for size in [16, 24, 32, 48, 64, 96, 128, 256, 512]:
        filename = ':/icons/qutebrowser-{}x{}.png'.format(size, size)
        pixmap = QPixmap(filename)
        if pixmap.isNull():
            log.init.warning("Failed to load {}".format(filename))
        else:
            fallback_icon.addPixmap(pixmap)
    icon = QIcon.fromTheme('qutebrowser', fallback_icon)
    if icon.isNull():
        log.init.warning("Failed to load icon")
    else:
        qApp.setWindowIcon(icon)
Beispiel #13
0
 def drawBackground(self, pixmap):
     """Draw background in pixmap.
     """
     w, h = pixmap.width(), pixmap.height()
     mode = self.__bgModes[self.bgCBox.currentIndex()]
     source = QPixmap(pixmap)
     painter = QtGui.QPainter(pixmap)
     if mode == self.BG_COLOR:
         painter.fillRect(0, 0, w, h, self.bgColor)
     if mode == self.BG_TRANSPARENT or mode == self.BG_IMAGE or mode == self.BG_INPUT:
         painter.drawPixmap(0, 0, common.checkerboard(pixmap.size()))
     if mode == self.BG_IMAGE and self.bgPath:
         bgPixmap = QPixmap(self.bgPath)
         if not bgPixmap.isNull():
             bgPixmap = bgPixmap.scaled(w, h, QtCore.Qt.IgnoreAspectRatio)
             painter.drawPixmap(0, 0, bgPixmap)
     if mode == self.BG_INPUT:
         painter.drawPixmap(0, 0, source)
Beispiel #14
0
    def findIconHelper(self, size = int, themeName = str, iconName = str):
        pixmap = QPixmap()

        if iconName == '' or self.themeName == '':
            return pixmap

        if themeName == '':
            themeName = self.themeName

        if themeName == self.themeName:
            index = self.themeIndex
        else:
            index = self.readThemeIndex(themeName)

        
        subDirs = filter(lambda x:x[0] == str(size), index.dirList)
        
        for iconDir in self.iconDirs:
            if path.exists(path.join(iconDir, themeName)):
                for theme in subDirs:
                    fileName = path.join(iconDir, themeName, theme[1],
                            '%s.png' % str(iconName))
        
                    logging.debug('Looking for : %s' % fileName)
                    if path.exists(fileName):
                        pixmap.load(fileName)
                        logging.debug('Icon: %s found in theme %s' % \
                                (iconName, themeName))
                        return pixmap

        for iconDir in self.extraIcons:
            fileName = path.join(iconDir, '%s.png' % str(iconName))
        
            if path.exists(fileName):
                pixmap.load(fileName)
                logging.debug('Icon: %s found in %s' % (iconName, iconDir))
                return pixmap

        if len(self._themes) > 0:
            self._themes.pop(0)
            if not len(self._themes) == 0 and pixmap.isNull():
                pixmap = self.findIconHelper(size, self._themes[0], iconName)
        return pixmap
Beispiel #15
0
    def set_paragraph(self, h2='', h3='', text='', img=None):
        if h2 != '':
            lbl_h2 = QLabel(h2, self.inner)
            fnt = lbl_h2.font()
            fnt.setPointSize(self.H2_FONT_SIZE)
            lbl_h2.setFont(fnt)
            lbl_h2.setFixedHeight(self.H2_HEIGHT)
            lbl_h2.setAlignment(Qt.AlignBottom)
            lbl_h2.setMargin(self.SIDE_MARGIN)
            self.vbox.addWidget(lbl_h2)

            frm = QFrame(self.inner)
            frm.setFrameShape(QFrame.HLine)
            frm.setContentsMargins(self.SIDE_MARGIN, 0, self.SIDE_MARGIN, 0)
            plt = frm.palette()
            plt.setColor(QPalette.WindowText, Qt.darkGray)
            frm.setPalette(plt)
            self.vbox.addWidget(frm)

        if text != '':
            lbl_txt = QLabel(text, self.inner)
            lbl_txt.setWordWrap(True)
            fnt = lbl_txt.font()
            fnt.setPointSize(self.TEXT_FONT_SIZE)
            lbl_txt.setFont(fnt)
            lbl_txt.setMargin(self.SIDE_MARGIN)
            self.vbox.addWidget(lbl_txt)

        if img is not None:
            if self.params.lang == 'en':
                img += '_en.png'
            else:
                img += '_jp.png'
            pixmap = QPixmap(img)
            if not pixmap.isNull():
                lbl_img = QLabel(self.inner)
                lbl_img.setPixmap(pixmap)
                self.lbl_img_list.append(lbl_img)
                self.pixmap_list.append(pixmap.scaledToWidth(pixmap.width()))
                self.vbox.addWidget(lbl_img)

        self.inner.setLayout(self.vbox)
Beispiel #16
0
class RobotHead(RobotPart):
    def __init__(self, parent=None):
        super(RobotHead, self).__init__(parent)

        self.pixmap = QPixmap()

    def boundingRect(self):
        return QRectF(-15, -50, 30, 50)

    def paint(self, painter, option, widget=None):
        if self.pixmap.isNull():
            painter.setBrush(self.color.lighter(130) if self.dragOver else self.color)
            painter.drawRoundedRect(-10, -30, 20, 30, 25, 25, Qt.RelativeSize)
            painter.setBrush(Qt.white)
            painter.drawEllipse(-7, -3 - 20, 7, 7)
            painter.drawEllipse(0, -3 - 20, 7, 7)
            painter.setBrush(Qt.black)
            painter.drawEllipse(-5, -1 - 20, 2, 2)
            painter.drawEllipse(2, -1 - 20, 2, 2)
            painter.setPen(QPen(Qt.black, 2))
            painter.setBrush(Qt.NoBrush)
            painter.drawArc(-6, -2 - 20, 12, 15, 190 * 16, 160 * 16)
        else:
            painter.scale(0.2272, 0.2824)
            painter.drawPixmap(QPointF(-15 * 4.4, -50 * 3.54), self.pixmap)

    def dragEnterEvent(self, event):
        if event.mimeData().hasImage():
            event.setAccepted(True)
            self.dragOver = True
            self.update()
        else:
            super(RobotHead, self).dragEnterEvent(event)

    def dropEvent(self, event):
        if event.mimeData().hasImage():
            self.dragOver = False
            self.pixmap = QPixmap(event.mimeData().imageData())
            self.update()
        else:
            super(RobotHead, self).dropEvent(event)
Beispiel #17
0
    def getPixmap(self, key):
        """
        Public method to retrieve a pixmap.

        @param key name of the wanted pixmap (string)
        @return the requested pixmap (QPixmap)
        """
        if key:
            try:
                return self.pixmapCache[key]
            except KeyError:
                if not os.path.isabs(key):
                    for path in self.searchPath:
                        pm = QPixmap(path + "/" + key)
                        if not pm.isNull():
                            break
                    else:
                        pm = QPixmap()
                else:
                    pm = QPixmap(key)
                self.pixmapCache[key] = pm
                return self.pixmapCache[key]
        return QPixmap()
Beispiel #18
0
class Dialog(QDialog):
    """A Dialog with basic layout features:

    a main widget,
    an icon or pixmap,
    a separator,
    buttons (provided by a QDialogButtonBox)

    """
    def __init__(self,
                 parent = None,
                 message = "",
                 title = "",
                 icon = None,
                 iconSize = QSize(64, 64),
                 pixmap = None,
                 separator = True,
                 buttonOrientation = Qt.Horizontal,
                 buttons = ('ok', 'cancel'),
                 help = None,
                 **kwargs):
        """Initializes the dialog.

        parent = a parent widget or None.

        The following keyword arguments are recognized:
        - message: the text to display in the message label
        - title: the window title
        - icon or pixmap: shown in the left area
        - iconSize: size of the icon in the left (QSize, default: 64x64)
        - separator: draw a separator line or not (default: True)
        - buttonOrientation: Qt.Horizontal (default) or Qt.Vertical
        - buttons: which buttons to use (default: Ok, Cancel)
        - help: function to call when a help button is clicked.

        Other keyword arguments are passed to QDialog.

        """
        super(Dialog, self).__init__(parent, **kwargs)
        self._icon = QIcon()
        self._separatorWidget = Separator()
        self._mainWidget = QWidget()
        self._pixmap = QPixmap()
        self._pixmapLabel = QLabel(self)
        self._messageLabel = QLabel(self)
        self._buttonBox = b = QDialogButtonBox(self)
        b.accepted.connect(self.accept)
        b.rejected.connect(self.reject)
        layout = QGridLayout()
        layout.setSpacing(10)
        self.setLayout(layout)

        # handle keyword args
        self._buttonOrientation = buttonOrientation
        self._iconSize = iconSize
        self._separator = separator
        if title:
            self.setWindowTitle(title)
        self.setMessage(message)
        if icon:
            self.setIcon(icon)
        elif pixmap:
            self.setPixmap(pixmap)
        b.helpRequested.connect(help or self.helpRequest)
        self.setStandardButtons(buttons)
        self.reLayout()

    def helpRequest(self):
        """Called when a help button is clicked."""
        pass

    def setButtonOrientation(self, orientation):
        """Sets the button orientation.

        Qt.Horizontal (default) puts the buttons at the bottom of the dialog
        in a horizontal row, Qt.Vertical puts the buttons at the right in a
        vertical column.

        """
        if orientation != self._buttonOrientation:
            self._buttonOrientation = orientation
            self._buttonBox.setOrientation(orientation)
            self.reLayout()

    def buttonOrientation(self):
        """Returns the button orientation."""
        return self._buttonOrientation

    def setIcon(self, icon):
        """Sets the icon to display in the left area.

        May be:
        - None or QIcon()
        - one of 'info', 'warning', 'critical', 'question'
        - a QStyle.StandardPixmap
        - a QIcon.

        """
        if icon in standardicons:
            icon = standardicons[icon]
        if isinstance(icon, QStyle.StandardPixmap):
            icon = self.style().standardIcon(icon)
        if icon is None:
            icon = QIcon()
        self._icon = icon
        self.setPixmap(icon.pixmap(self._iconSize))

    def icon(self):
        """Returns the currently set icon as a QIcon."""
        return self._icon

    def setIconSize(self, size):
        """Sets the icon size (QSize or int)."""
        if isinstance(size, int):
            size = QSize(size, size)
        changed = size != self._iconSize
        self._iconSize = size
        if changed and not self._icon.isNull():
            self.setPixmap(self._icon.pixmap(size))

    def iconSize(self):
        """Returns the icon size (QSize)."""
        return self._iconSize

    def setPixmap(self, pixmap):
        """Sets the pixmap to display in the left area."""
        changed = self._pixmap.isNull() != pixmap.isNull()
        self._pixmap = pixmap
        self._pixmapLabel.setPixmap(pixmap)
        if not pixmap.isNull():
            self._pixmapLabel.setFixedSize(pixmap.size())
        if changed:
            self.reLayout()

    def pixmap(self):
        """Returns the currently set pixmap."""
        return self._pixmap

    def setMessage(self, text):
        """Sets the main text in the dialog."""
        self._messageLabel.setText(text)

    def message(self):
        """Returns the main text."""
        return self._messageLabel.text()

    def messageLabel(self):
        """Returns the QLabel displaying the message text."""
        return self._messageLabel

    def buttonBox(self):
        """Returns our QDialogButtonBox instance."""
        return self._buttonBox

    def setStandardButtons(self, buttons):
        """Convenience method to set standard buttons in the button box.

        Accepts a sequence of string names from the standardbuttons constant,
        or a QDialogButtonBox.StandardButtons value.

        """
        if isinstance(buttons, (set, tuple, list)):
            buttons = functools.reduce(operator.or_,
                map(standardbuttons.get, buttons),
                QDialogButtonBox.StandardButtons())
        self._buttonBox.setStandardButtons(buttons)

    def button(self, button):
        """Returns the given button.

        May be a QDialogButtonBox.StandardButton or a key from standardbuttons.

        """
        if button in standardbuttons:
            button = standardbuttons[button]
        return self._buttonBox.button(button)

    def setSeparator(self, enabled):
        """Sets whether to show a line between contents and buttons."""
        changed = self._separator != enabled
        self._separator = enabled
        if changed:
            self.reLayout()

    def hasSeparator(self):
        """Returns whether a separator line is shown."""
        return self._separator

    def setMainWidget(self, widget):
        """Sets the specified widget as our main widget."""
        old = self._mainWidget
        if old:
            old.setParent(None)
        self._mainWidget = widget
        self.reLayout()

    def mainWidget(self):
        """Returns the current main widget (an empty QWidget by default)."""
        return self._mainWidget

    def reLayout(self):
        """(Internal) Lays out all items in this dialog."""
        layout = self.layout()
        while layout.takeAt(0):
            pass

        if not self._pixmap.isNull():
            col = 1
            layout.addWidget(self._pixmapLabel, 0, 0, 2, 1)
        else:
            layout.setColumnStretch(1, 0)
            col = 0
        layout.setColumnStretch(col, 1)
        self._pixmapLabel.setVisible(not self._pixmap.isNull())
        layout.addWidget(self._messageLabel, 0, col)
        layout.addWidget(self._mainWidget, 1, col)
        if self._buttonOrientation == Qt.Horizontal:
            if self._separator:
                layout.addWidget(self._separatorWidget, 2, 0, 1, col+1)
            layout.addWidget(self._buttonBox, 3, 0, 1, col+1)
        else:
            if self._separator:
                layout.addWidget(self._separatorWidget, 0, col+1, 2, 1)
            layout.addWidget(self._buttonBox, 0, col+2, 2, 1)
        self._separatorWidget.setVisible(self._separator)
Beispiel #19
0
class Canvas(QWidget):
    def __init__(self, **kwargs):
        super(Canvas, self).__init__(**kwargs)

        self.pixmap = QPixmap()
        self.filenamePrefix = ""

        self.scale = DEFAULT_SCALE
        self.scaleMax = MAX_SCALE
        self.scaleMin = MIN_SCALE
        self.scaleIncrement = ZOOM_INCREMENT

        self.painter = QPainter()
        self.setMouseTracking(True)
        self.color = QColor(CANVAS_DEFAULT_COLOR)

        self.parentCenterX = 0
        self.parentCenterY = 0
        self.canvasCenterX = self.pixmap.width() // 2
        self.canvasCenterY = self.pixmap.height() // 2

        self.canvasWidth = int(self.pixmap.width() * self.scale)
        self.canvasHeight = int(self.pixmap.height() * self.scale)

        self.canvasGlobalLeft = 0
        self.canvasGlobalRight = 0
        self.canvasGlobalTop = 0
        self.canvasGlobalBottom = 0

        self.controlOpacity = CONTROL_OPACITY
        self.polygons = []

        self.mouseHeld = False
        self.middleClickHeld = False
        self.mouseDownPos = QPoint()
        self.mousePos = QPoint()
        self.previousMousePos = QPoint()

        self.highlightedControl = None
        self.clickedControl = None
        self.selectedPolygon = None
        self.freeDrawPolygon = None
        self.closestLine = None
        self.controlOffset = QPoint()
        self.copyOfSelectedPolygon = None
        self.hideControls = False

        self.vBarPos = 0
        self.hBarPos = 0
        self.hBar = None
        self.vBar = None

        self.state = MOVE_CONTROLS

        self.update()
        self.updateCanvasGlobalParameters()

    def showEvent(self, event):
        '''
        Used for making sure the correct width/height of the screen is used

        Inside __init__(), parent.size = (1280, 720) 
            (doesn't take into account margins, 
            incorrect mouse positions)

        When running, parent.size = (1278, 667)
            (Does take into account margins, 
            correct mouse positions)
        '''

        parent = self.parent().window()

        self.hBar = parent.scrollArea.horizontalScrollBar()
        self.vBar = parent.scrollArea.verticalScrollBar()
        self.updateCanvasGlobalParameters()

    def paintEvent(self, event):
        if (not self.pixmap.isNull()):
            self.painter.begin(self)

            self.setPainterQuality()

            self.painter.scale(self.scale, self.scale)
            self.painter.translate(self.offsetToCenter())

            self.drawImage()
            self.drawPolygons()

            if (self.closestLine is not None
                    and self.selectedPolygon is not None
                    and type(self.highlightedControl) is not Control):
                self.drawClosestLineControls()

            if (self.state == DRAW_POLYGON):
                self.drawMouseTargets()

            self.painter.end()

    def sizeHint(self):
        return self.minimumSizeHint()

    def minimumSizeHint(self):
        if self.pixmap:
            return self.scale * self.pixmap.size()
        return super(Canvas, self).minimumSizeHint()

    def drawImage(self):
        self.painter.setOpacity(1)
        self.painter.drawPixmap(0, 0, self.pixmap)

    def drawPolygons(self):
        for poly in self.polygons:
            self.painter.setOpacity(CONTROL_OPACITY)

            if (not self.hideControls):
                self.drawControls(poly.controls)
            elif (poly == self.selectedPolygon):
                self.drawControls(poly.controls)
            elif (poly == self.freeDrawPolygon):
                self.drawControls(poly.controls)

            self.painter.setBrush(poly.color)

            if (poly == self.selectedPolygon
                    and poly == self.highlightedControl):
                self.painter.setOpacity(HIGHLIGHTED_OPACITY)
                self.painter.setPen(QColor(CONTROL_HIGHLIGHT_COLOR))
            elif (poly == self.selectedPolygon):
                self.painter.setPen(QColor(CONTROL_HIGHLIGHT_COLOR))
                self.painter.setOpacity(SELECTED_OPACITY)

            elif (poly == self.highlightedControl):
                self.painter.setOpacity(HIGHLIGHTED_OPACITY)

            else:
                self.painter.setPen(Qt.NoPen)

            self.painter.drawPolygon(poly.toQPointList())

    def drawControls(self, controls):
        for control in controls:
            self.painter.setBrush(control.color)

            if (control == self.highlightedControl):
                self.painter.setOpacity(HIGHLIGHTED_OPACITY)
            else:
                self.painter.setPen(Qt.NoPen)
                self.painter.setOpacity(CONTROL_OPACITY)

            self.painter.drawEllipse(control.position, control.radius,
                                     control.radius)

    def drawClosestLineControls(self):
        scaledPos = self.scaleMousePos()
        self.painter.setPen(QColor(CLOSEST_LINE_COLOR))
        line = self.closestLine
        start = self.selectedPolygon.controls[line[0]].position
        end = self.selectedPolygon.controls[line[1]].position

        self.painter.drawLine(start.x(), start.y(), end.x(), end.y())

        self.painter.setBrush(self.selectedPolygon.color)
        self.painter.drawEllipse(self.getClosestLineIntersection(),
                                 CONTROL_RADIUS / self.scale,
                                 CONTROL_RADIUS / self.scale)

    def drawMouseTargets(self):
        scaledPos = self.scaleMousePos()
        self.painter.setPen(Qt.black)
        self.painter.pen().setWidth(MOUSE_TARGET_THICKNESS)
        self.painter.drawLine(0, scaledPos.y(), self.pixmap.width(),
                              scaledPos.y())
        self.painter.drawLine(scaledPos.x(), 0, scaledPos.x(),
                              self.pixmap.height())

    def mousePressEvent(self, event):
        if (not self.pixmap.isNull()):
            self.mouseHeld = True
            self.mouseDownPos = self.scaleMousePos()
            self.previousMousePos = self.mouseDownPos

            if (event.button() == Qt.LeftButton):
                self.handleLeftClick(event)
            elif (event.button() == Qt.MiddleButton):
                self.handleMiddleClick(event)
            elif (event.button() == Qt.RightButton):
                self.handleRightClick(event)

    def mouseMoveEvent(self, event):
        if (not self.pixmap.isNull()):
            self.mousePos = event.pos()
            scaledPos = self.scaleMousePos()
            self.closestLine = None

            if (self.middleClickHeld):
                self.scrollWindow(scaledPos)
            else:
                self.moveControls(scaledPos)

            self.parent().window().labelCoordinates.setText(
                f"X: {scaledPos.x()}; Y: {scaledPos.y()}")

            self.update()

    def scrollWindow(self, scaledPos):
        move = (scaledPos - self.previousMousePos) * SCROLL_SCALE
        self.hBar.setValue(self.hBar.value() - move.x())
        self.vBar.setValue(self.vBar.value() - move.y())

        self.previousMousePos = scaledPos

    def moveControls(self, scaledPos):
        if (self.clickedControl is not None):
            newPos = scaledPos
            validPos = True

            if (type(self.clickedControl) is Polygon):
                prevPos = self.clickedControl.center
                newPos += self.controlOffset
                self.clickedControl.move(newPos)

                for control in self.clickedControl.controls:
                    if (control.position.x() < 0):
                        validPos = False
                        newPos.setX(prevPos.x())
                    elif (control.position.x() > self.pixmap.width()):
                        validPos = False
                        newPos.setX(prevPos.x())

                    if (control.position.y() < 0):
                        validPos = False
                        newPos.setY(prevPos.y())
                    elif (control.position.y() >= self.pixmap.height()):
                        validPos = False
                        newPos.setY(prevPos.y())

                if (not validPos):
                    self.clickedControl.move(newPos)
            else:
                self.clickedControl.move(newPos)

            self.parent().window().saved = False

        elif (self.state is not DRAW_POLYGON):
            self.highlightedControl = self.checkIfHoveringOverControl(
                scaledPos)

        if (self.selectedPolygon is not None
                and type(self.selectedPolygon)) is Polygon and type(
                    self.highlightedControl) is not Control:
            distance, indexes = getClosestLine(self.scaleMousePos(),
                                               self.selectedPolygon)
            if (distance < CONTROL_MIN_LINE_DISTANCE):
                self.closestLine = indexes

                self.state = ADD_CONTROL
            elif (self.state is not DRAW_POLYGON):
                self.state = MOVE_CONTROLS
        else:
            self.closestLine = None
            if (self.state is not DRAW_POLYGON):
                self.state = MOVE_CONTROLS

    def mouseReleaseEvent(self, event):
        self.clickedControl = None
        self.mouseHeld = False
        self.middleClickHeld = False

    def wheelEvent(self, event):
        if (event.angleDelta().y() >= 0):
            self.scale += self.scaleIncrement
        else:
            self.scale -= self.scaleIncrement

        self.scale = clamp(self.scale, self.scaleMin, self.scaleMax)

        self.hBar.setValue(self.hBar.value())
        self.vBar.setValue(self.vBar.value())

        self.updateControlRadius()
        self.updateCanvasGlobalParameters()

        self.update()
        self.adjustSize()

    def handleLeftClick(self, event):
        self.mouseDownPos = event.pos()
        scaledPos = self.scaleMousePos()

        if (self.state == MOVE_CONTROLS):
            if (self.highlightedControl is not None):
                self.clickedControl = self.highlightedControl
                if (type(self.clickedControl) is Polygon):
                    self.controlOffset = self.clickedControl.center - scaledPos
            self.updateSelectedPolygon()
        elif (self.state == ADD_CONTROL):
            index = self.closestLine[1]
            self.selectedPolygon.addControlAtIndex(index, scaledPos)
            self.selectedPolygon.updateParameters()
            self.updateControlRadius()
            self.state = MOVE_CONTROLS
        elif (self.state == DRAW_POLYGON):
            if (self.freeDrawPolygon is None):
                poly = Polygon(color=self.color)
                poly.controls = []
                poly.addControlAtPosition(self.scaleMousePos())
                poly.computeBoundingBox()
                self.polygons.append(poly)
                self.freeDrawPolygon = poly

                self.updateControlRadius()
                self.update()
            else:
                self.freeDrawPolygon.addControlAtPosition(self.scaleMousePos())
                self.freeDrawPolygon.updateParameters()
                self.updateControlRadius()

        self.update()

    def handleMiddleClick(self, event):
        self.middleClickHeld = True

    def deleteControl(self):
        control = self.highlightedControl
        control.parent.deleteControl(control)
        control.parent.updateParameters()

    def handleRightClick(self, event):
        pos = event.pos()
        scaledPos = self.scaleMousePos()

        menu = QMenu(self)
        menu.setStyleSheet(STYLE_SHEET)
        changeColorAciton = menu.addAction("Change Color")

        menu.addSeparator()
        copyAction = menu.addAction(COPY_TEXT)
        pasteAction = menu.addAction(PASTE_TEXT)

        menu.addSeparator()
        deleteControlAction = menu.addAction(DELETE_CONTROL_TEXT)
        deletePolygonAction = menu.addAction(DELETE_POLYGON_TEXT)

        if (self.highlightedControl is None):
            changeColorAciton.setDisabled(True)
            copyAction.setDisabled(True)
            deletePolygonAction.setDisabled(True)
            deleteControlAction.setDisabled(True)
        elif (self.selectedPolygon is None):
            changeColorAciton.setDisabled(True)

        if (type(self.highlightedControl) is Polygon):
            deleteControlAction.setDisabled(True)
        elif (type(self.highlightedControl) is Control):
            deletePolygonAction.setDisabled(True)
            copyAction.setDisabled(True)

        selectedAction = menu.exec_(self.mapToGlobal(event.pos()))

        if (selectedAction == changeColorAciton):
            self.askForColorChange()
        elif (selectedAction == copyAction):
            self.copyPolygon()
        elif (selectedAction == pasteAction):
            self.pastePolygon()
        elif (selectedAction == deleteControlAction):
            self.deleteControl()
        elif (selectedAction == deletePolygonAction):
            self.deletePolygon()
        elif (selectedAction == None):
            self.highlightedControl = None

        self.update()

    def updateSelectedPolygon(self):
        if (type(self.clickedControl) == Control):
            self.selectedPolygon = self.clickedControl.parent
        elif (type(self.clickedControl) == Polygon):
            self.selectedPolygon = self.clickedControl
        else:
            self.selectedPolygon = None

    def updateControlRadius(self):
        for control in Control.instances:
            control.radius = control._radius / self.scale

    def checkIfClickedOnControl(self):
        scaledMousePos = self.scaleMousePos()

        for control in Control.instances:
            if (control.checkClicked(scaledMousePos)):
                return control
        return None

    def checkIfHoveringOverControl(self, scaledPos):

        if (self.hideControls):
            if (self.selectedPolygon is not None):
                for control in self.selectedPolygon.controls:
                    if (control.checkClicked(scaledPos)):
                        return control
        else:
            for control in Control.instances:
                if (control.checkClicked(scaledPos)):
                    return control

        for poly in self.polygons:
            if (pointInsidePolygon(scaledPos, poly.toList())):
                return poly

        return None

    def setPainterQuality(self):
        self.painter.setRenderHint(QPainter.Antialiasing, True)
        self.painter.setRenderHint(QPainter.HighQualityAntialiasing)
        self.painter.setRenderHint(QPainter.SmoothPixmapTransform)
        self.painter.setPen(Qt.NoPen)

    def sizeHint(self):
        if (self.pixmap):
            return self.scale * self.pixmap.size()

    def offsetToCenter(self):
        #https://github.com/tzutalin/labelImg/blob/master/libs/canvas.py
        self.scale
        area = super(Canvas, self).size()
        w = self.pixmap.width() * self.scale
        h = self.pixmap.height() * self.scale

        aw = area.width()
        ah = area.height()

        x = (aw - w) / (2 * self.scale)
        y = (ah - h) / (2 * self.scale)

        return QPointF(x, y)

    def resizedParent(self):
        self.updateCanvasGlobalParameters()

    def scaleMousePos(self):
        offset = self.getCanvasStartPosition()

        mouseX = self.mousePos.x()
        mouseY = self.mousePos.y()

        scaledX = scale(mouseX, self.canvasGlobalLeft, self.canvasGlobalRight,
                        0, self.pixmap.width())
        scaledY = scale(mouseY, self.canvasGlobalTop, self.canvasGlobalBottom,
                        0, self.pixmap.height())

        scaledX = clamp(scaledX, 0, self.pixmap.width())
        scaledY = clamp(scaledY, 0, self.pixmap.height())

        return QPoint(scaledX, scaledY)

    def getCanvasStartPosition(self):
        parentCenterX = self.parent().size().width() // 2
        parentCenterY = self.parent().size().height() // 2

        startX = (parentCenterX - (self.canvasWidth // 2)) - self.hBar.value()
        startY = (parentCenterY - (self.canvasHeight // 2)) - self.vBar.value()

        return QPoint(startX, startY)

    def updateCanvasGlobalParameters(self):

        self.parentCenterX = self.parent().size().width() // 2
        self.parentCenterY = self.parent().size().height() // 2

        self.canvasCenterX = self.pixmap.width() // 2
        self.canvasCenterY = self.pixmap.height() // 2

        self.canvasWidth = int(self.pixmap.width() * self.scale)
        self.canvasHeight = int(self.pixmap.height() * self.scale)

        self.canvasGlobalLeft = self.parentCenterX - (self.canvasWidth // 2)
        self.canvasGlobalTop = self.parentCenterY - (self.canvasHeight // 2)

        if (self.canvasGlobalLeft < 0):
            self.canvasGlobalLeft = 0

        if (self.canvasGlobalTop < 0):
            self.canvasGlobalTop = 0

        self.canvasGlobalRight = self.canvasGlobalLeft + self.canvasWidth
        self.canvasGlobalBottom = self.canvasGlobalTop + self.canvasHeight

    def addPolygon(self, color):
        if (not self.pixmap.isNull()):

            polyColor = None

            if (type(color) is str):
                polyColor = QColor(int(color, 0))
            elif (type(color) is QColor):
                polyColor = color

            poly = Polygon(color=polyColor,
                           center=QPoint(self.canvasCenterX,
                                         self.canvasCenterY))
            poly.computeBoundingBox()
            self.polygons.append(poly)

            self.updateControlRadius()
            self.update()
        else:
            QMessageBox.information(self, NO_IMAGE_TITLE, NO_IMAGE_TEXT)

    def deletePolygon(self):
        if (self.selectedPolygon is not None):
            try:
                index = self.polygons.index(self.selectedPolygon)
                self.polygons.pop(index)
                self.selectedPolygon = None
                self.update()
            except ValueError:
                pass

    def addControlToSelectedPolygon(self):
        if (self.selectedPolygon is not None):
            self.selectedPolygon.addControl()
            self.update()
            self.updateControlRadius()

    def deleteControlFromSelectedPolygon(self):
        if (self.selectedPolygon is not None):
            self.selectedPolygon.deleteLastControl()
            if (len(self.selectedPolygon.controls) <= 0):
                index = self.polygons.index(self.selectedPolygon)
                self.polygons.pop(index)
                self.selectedPolygon = None

            self.update()

    def resetCanvas(self):
        Control.deleteAllControls()
        self.highlightedControl = None
        self.selectedPolygon = None
        self.clickedControl = None
        self.polygons = []

    def loadImage(self, filename, copyPolygons=False):
        self.pixmap.load(filename)
        self.filenamePrefix = filename[:-4]

        pickleFilename = f"{self.filenamePrefix}{POLYGON_SUFFIX}"

        if (os.path.exists(pickleFilename)):
            self.resetCanvas()
            with open(pickleFilename, 'rb') as polyPickle:
                polygons = pickle.load(polyPickle)
                for polygon in polygons:
                    color = polygon['color']
                    newPolygon = Polygon(
                        color=QColor(color[0], color[1], color[2]))
                    newPolygon.setFromListOfCotnrolPositions(
                        polygon['controls'])

                    newPolygon.updateParameters()
                    newPolygon.updateOffsets()
                    self.polygons.append(newPolygon)
        elif (copyPolygons is False):
            self.resetCanvas()

        self.updateControlRadius()
        self.updateCanvasGlobalParameters()
        self.update()

    def saveImage(self):
        if (not self.pixmap.isNull()):
            image = np.zeros((self.pixmap.height(), self.pixmap.width(), 3),
                             dtype=np.uint8)
            polygons = []
            for polygon in self.polygons:
                polyToDraw = np.array(polygon.toList())
                color = polygon.colorToCV()

                image = cv2.fillPoly(image, [polyToDraw], color)

                polyObj = {'color': color, 'controls': polyToDraw}
                polygons.append(polyObj)

            #Deals with openCV using BGR instead of RGB
            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
            cv2.imwrite(f"{self.filenamePrefix}{SEGMENTATION_SUFFIX}", image)

            with open(f"{self.filenamePrefix}{POLYGON_SUFFIX}",
                      'wb+') as polyPickle:
                pickle.dump(polygons, polyPickle)

    def setState(self, state):
        self.state = state

        if (state == DRAW_POLYGON):
            self.freeDrawPolygon = None
            self.highlightedControl = None
            self.closestLine = None
            self.selectedPolygon = None
        else:
            self.freeDrawPolygon = None

        if (not self.pixmap.isNull()):
            self.update()

    def setColor(self, color):
        if (type(color) == str):
            self.color = QColor(color)
        elif (type(color) == QColor):
            self.color = color

    def getClosestLineIntersection(self):
        pos1 = self.selectedPolygon.controls[self.closestLine[0]].position
        pos2 = self.selectedPolygon.controls[self.closestLine[1]].position
        line = [pos1.x(), pos1.y(), pos2.x(), pos2.y()]

        mPos = self.scaleMousePos()

        vLine = [
            mPos.x(),
            mPos.y() + MOUSE_SEARCH_AREA,
            mPos.x(),
            mPos.y() - MOUSE_SEARCH_AREA
        ]
        hLine = [
            mPos.x() - MOUSE_SEARCH_AREA,
            mPos.y(),
            mPos.x() + MOUSE_SEARCH_AREA,
            mPos.y()
        ]

        intersectionV = linesIntersect(line, vLine)
        intersectionH = linesIntersect(line, hLine)

        intersection = intersectionV

        if (intersectionV is not None and intersectionH is not None):
            vDistance = distance([intersectionV['x'], intersectionV['y']],
                                 [mPos.x(), mPos.y()])
            hDistance = distance([intersectionH['x'], intersectionH['y']],
                                 [mPos.x(), mPos.y()])

            if (vDistance < hDistance):
                intersection = intersectionV
            else:
                intersection = intersectionH
        elif (intersectionV is None):
            intersection = intersectionH

        if (intersection is not None):
            return QPoint(intersection['x'], intersection['y'])
        else:
            return QPoint(OFFSCREEN, OFFSCREEN)

    def copyPolygon(self):
        if (self.selectedPolygon is not None):
            self.copyOfSelectedPolygon = self.selectedPolygon

    def pastePolygon(self):
        if (self.copyOfSelectedPolygon is not None):
            import time
            startTime = time.time()
            c = self.copyOfSelectedPolygon

            newPolygon = Polygon(color=QColor(c.color))
            newPolygon.copyControls(c.controls, offset=COPY_OFFSET)
            newPolygon.updateParameters()
            self.polygons.append(newPolygon)

            self.updateControlRadius()
            self.update()

    def askForColorChange(self):
        if (self.selectedPolygon is not None):
            color = QColorDialog.getColor()

            if (QColor.isValid(color)):
                self.setColor(color)
                self.selectedPolygon.setColor(color)

    def changeHideControlsState(self, state):
        if (state > 0):
            self.hideControls = True
        else:
            self.hideControls = False

        self.update()
Beispiel #20
0
class FLCodBar(object):

    barcode = {}
    p = None
    pError = None


    def __init__(self, value=None, type_=BARCODE_128, margin=10, scale=1.0, cut=1.0, rotation=0, text_flag=False, fg=QtCore.Qt.black, bg=QtCore.Qt.white, res=72):
        dict_ = {"barcode": "python-barcode"}
        from pineboolib.utils import checkDependencies
        checkDependencies(dict_)
        self.pError = "Not Implemented"

        self.barcode["value"] = ""

        if value in [None, 0]:
            self.p = None
            self.pError = QPixmap()
            self.readingStdout = False
            self.writingStdout = False
            self.fillDefault(self.barcode)
        else:
            if isinstance(value, str):
                self.p = None
                self.pError = QPixmap()
                self.readingStdout = False
                self.writingStdout = False
                self.barcode["value"] = value
                self.barcode["type"] = type_
                self.barcode["margin"] = margin 
                self.barcode["scale"] = scale
                self.barcode["cut"] = cut
                self.barcode["rotation"] = rotation
                self.barcode["text"] = text_flag
                self.barcode["fg"] = fg
                self.barcode["bg"] = bg
                self.barcode["valid"] = False
                self.barcode["res"] = res

            else:
                self._copyBarCode(value, self.barcode)


    def pixmap(self):
        self._createBarcode()

        if not self.p:
            self.barcode["valid"] = False

        return self.p

    def pixmapError(self):
        return self.pError

    def value(self):
        return self.barcode["value"]

    def type_(self):
        return self.barcode["type"]

    def margin(self):
        return self.barcode["margin"]

    def scale(self):
        return self.barcode["scale"]

    def cut(self):
        return self.barcode["cut"]

    def text(self):
        return self.barcode["text"]

    def rotation(self):
        return self.barcode["rotation"]

    def fg(self):
        return self.barcode["fg"]

    def bg(self):
        return self.barcode["bg"]

    def setData(self, d):
        self.barcode = d

    def validBarcode(self):
        return self.barcode["valid"]

    def setCaption(self, caption):
        self.barcode["caption"] = caption

    def caption(self):
        return self.barcode["caption"]

    def setValue(self, value):
        self.barcode["value"] = value

    def setType(self, type_):
        self.barcode["type"] = type_

    def setMargin(self, margin):
        self.barcode["margin"] = margin

    def setScale(self, scale):
        self.barcode["scale"] = scale

    def setCut(self, cut):
        self.barcode["cut"] = cut

    def setText(self, text):
        self.barcode["text"] = text

    def setRotation(self, rotation):
        self.barcode["rotation"] = rotation

    def setFg(self, fg):
        self.barcode["fg"] = fg

    def setBg(self, bg):
        self.barcode["bg"] = bg

    def setRes(self, res):
        self.barcode["res"] = res

    def data(self):
        return self.barcode

    def fillDefault(self, data):
        data["bg"] = "white"
        data["fg"] = "black"
        data["margin"] = 10
        data["text"] = True
        data["value"] = "1234567890"
        data["type"] = BARCODE_39
        data["scale"] = 1.0
        data["cut"] = 1.0
        data["rotation"] = 0
        data["caption"] = "Static"
        data["valid"] = False
        data["res"] = 72

    def cleanUp(self):
        self.p.resize(0, 0)
        self.pError.resize(0, 0)

    def nameToType(self, name):
        n = name.lower()
        if n == "any":
            return BARCODE_ANY
        elif n == "ean":
            return BARCODE_EAN
        elif n == "ean-8":
            return BARCODE_EAN_8
        elif n == "ean-13":
            return BARCODE_EAN_13
        elif n == "ean-14":
            return BARCODE_EAN_14
        elif n == "upc":
            return BARCODE_UPC
        elif n == "upc-a":
            return BARCODE_UPC_A
        elif n == "jan":
            return BARCODE_JAN
        elif n == "isbn":
            return BARCODE_ISBN
        elif n == "isbn-10":
            return BARCODE_ISBN_10
        elif n == "isbn-13":
            return BARCODE_ISBN_13
        elif n == "issn":
            return BARCODE_ISSN
        elif n == "code39":
            return BARCODE_39
        elif n == "code128":
            return BARCODE_128
        elif n == "pzn":
            return BARCODE_PZN
        elif n == "itf":
            return BARCODE_ITF
        elif n == "gs1":
            return BARCODE_GS1
        elif n == "gtin":
            return BARCODE_GTIN
        else:
            logger.warning("Formato no soportado (%s)\nSoportados: %s." % (n, barcode.PROVIDED_BARCODES))
            return BARCODE_ANY

    def typeToName(self, type_):
        if type_ == BARCODE_ANY:
            return "ANY"
        elif type_ == BARCODE_EAN:
            return "EAN"
        elif type_ == BARCODE_EAN_8:
            return "EAN-8"
        elif type_ == BARCODE_EAN_13:
            return "EAN-13"
        elif type_ == BARCODE_EAN_14:
            return "EAN-14"
        elif type_ == BARCODE_UPC:
            return "UPC"
        elif type_ == BARCODE_UPC_A:
            return "UPC-A"
        elif type_ == BARCODE_JAN:
            return "JAN"
        elif type_ == BARCODE_ISBN:
            return "ISBN"
        elif type_ == BARCODE_ISBN_10:
            return "ISBN-10"
        elif type_ == BARCODE_ISBN_13:
            return "ISBN-13"
        elif type_ == BARCODE_ISSN:
            return "ISSN"
        elif type_ == BARCODE_39:
            return "Code39"
        elif type_ == BARCODE_128:
            return "Code128"
        elif type_ == BARCODE_PZN:
            return "PZN"
        elif type_ == BARCODE_ITF:
            return "ITF"
        elif type_ == BARCODE_GS1:
            return "GS1"
        elif type_ == BARCODE_GTIN:
            return "GTIN"
        else:
            return "ANY"


    def _createBarcode(self):
        if self.barcode["value"] == "":
            return
        if self.barcode["type"] == BARCODE_ANY:
            logger.warning("Usando %s por defecto" % self.typeToName(BARCODE_128))
            self.barcode["type"] = BARCODE_128

        type_ = self.typeToName(self.barcode["type"])
        value_ = self.barcode["value"]
        bg_ = self.barcode["bg"]
        fg_ = self.barcode["fg"]
        if not isinstance(self.barcode["bg"], str):
            bg_ = QColor(self.barcode["bg"]).name()

        if not isinstance(self.barcode["fg"], str):
            fg_ = QColor(self.barcode["fg"]).name()

        margin_ = self.barcode["margin"] / 10
        
        render_options = {}
        render_options['module_width'] = 0.6
        render_options['module_height'] = 10
        render_options['background'] = bg_.lower()
        render_options['foreground'] = fg_.lower()
        render_options['font_size'] = 8
        render_options['write_text'] = self.barcode["text"]
        render_options['text_distance'] = 35
        render_options['quiet_zone'] = margin_ 
        if self.barcode["text"]:
            render_options['text'] = value_  
        else:
            render_options['text'] = " "
            
        
        
        
        
        
        import barcode
        from barcode.writer import ImageWriter
        from PyQt5.QtSvg import QSvgRenderer

        barC = barcode.get_barcode_class(type_.lower())
        try:
            bar_ = barC(u'%s' % value_)
        except Exception:
            bar_ = barC('000000000000')
            
        svg = bar_.render(render_options)
        xml_svg = load2xml(svg.decode("utf-8"))
        svg_w = (3.779 * float(xml_svg.get("width")[0:6])) 
        svg_h = (3.779 * float(xml_svg.get("height")[0:6]))
        self.p = QPixmap(svg_w, svg_h)
        render = QSvgRenderer(svg)
        self.p.fill(QtCore.Qt.transparent)
        painter = Qt.QPainter(self.p)
        render.render(painter, QRectF(0,0,svg_w * 3.4 , svg_h * 3.4))

        if self.p.isNull():
            self.barcode["valid"] = False
        else:
            
            if self.barcode["scale"] != 1.0:
                wS_ = self.barcode["x"] * self.barcode["scale"]
                hS_ = self.barcode["y"] * self.barcode["scale"]
                self.p = self.p.scaled(wS_, hS_)

            self.barcode["x"] = self.p.width()
            self.barcode["y"] = self.p.height()

            self.barcode["valid"] = True
            

    def _copyBarCode(self, source, dest):
        dest["value"] = source["value"]
        dest["type"] = source["type"]
        dest["margin"] = source["margin"]
        dest["scale"] = source["scale"]
        dest["cut"] = source["cut"]
        dest["rotation"] = source["rotation"]
        dest["text"] = source["text"]
        dest["caption"] = source["caption"]
        dest["valid"] = source["valid"]
        dest["fg"] = source["fg"]
        dest["bg"] = source["bg"]
        dest["x"] = source["x"]
        dest["y"] = source["y"]
        dest["res"] = source["res"]
Beispiel #21
0
    def getWidget(self, media, scale):
        """  _________________________________________
            | Icon | Title                            |
            |______|__________________________________|
        """
        title_layout = QHBoxLayout()
        title_layout.setAlignment(Qt.AlignLeft)

        # space between the three grids
        title_layout.setSpacing(10)

        # margin around the widget
        title_layout.setContentsMargins(0, 0, 0, 0)

        widget = QWidget()
        widget.setLayout(title_layout)

        #
        # existing           showing
        # ____________________________________________________________________________
        #
        # icon.png           icon.png
        #
        # card.ini:
        #    iconkey +
        #    media +
        #    categpry        media-{collector/storage}-{media}-{categry}-{iconkey}.png
        #
        # card.ini:
        #    iconkey         media-{collector/storage}-{iconkey}.png
        #
        # card.ini:
        #    media +
        #    categpry        media-{collector/storage}-{media}-{categry}.png
        #

        #
        # Icon
        #
        pixmap = None
        pathToFile = media.getPathOfIcon()
        if pathToFile:
            pixmap = QPixmap(pathToFile)

        if not pixmap:

            #media-(collector/storage)
            iconFileName = TITLE_ICON_PREFIX + "-" + media.getFolderType()

            # media-(collector/storage)-{iconKey}
            if media.control.getIconKey():
                iconFileName += "-" + media.control.getIconKey()
            # media-(collector/storage)-{media}
            elif media.control.getMedia() and not media.control.getCategory():
                iconFileName += "-" + media.control.getMedia()
            # media-(collector/storage)-{media}-{category}
            elif media.control.getMedia() and media.control.getCategory():
                iconFileName += ("-" + media.control.getMedia()
                                 if media.control.getMedia() else
                                 "") + ("-" + media.control.getCategory()
                                        if media.control.getCategory() else "")

            iconFileName += "." + TITLE_ICON_EXTENSION
            pathToFile = resource_filename(
                __name__, os.path.join(TITLE_ICON_FOLDER, iconFileName))
            pixmap = QPixmap(pathToFile)

        if pixmap.isNull():
            smaller_pixmap = QPixmap(TITLE_ICON_HEIGHT * scale,
                                     TITLE_ICON_HEIGHT * scale)
            smaller_pixmap.fill(QColor(media.getBackgroundColor()))
        else:

            if pixmap.width() >= pixmap.height():
                smaller_pixmap = pixmap.scaledToWidth(TITLE_ICON_HEIGHT *
                                                      scale)
            else:
                smaller_pixmap = pixmap.scaledToHeight(TITLE_ICON_HEIGHT *
                                                       scale)

        iconWidget = QLabel()
        iconWidget.setPixmap(smaller_pixmap)

        title_layout.addWidget(iconWidget)

        #
        # Title
        #
        titleWidget = QLabel(self.getFormattedTitle(media))
        titleWidget.setFont(
            QFont(PANEL_FONT_TYPE,
                  PANEL_FONT_SIZE * scale * 1.8,
                  weight=QFont.Bold))

        title_layout.addWidget(titleWidget)
        return widget
class ImageViewer(QMainWindow):
    def __init__(self):
        super().__init__()

        self.formats = ('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.pbm',
                        '.pgm', '.ppm', '.xbm', '.xpm')
        self.rotval = 0  # 旋转方向
        self.rotvals = (0, -90, -180, -270)
        self.file_path = QDir.currentPath()  # 获取当前文件路径

        self.resize(1000, 800)
        self.setWindowTitle("Magic Viewer")

        self.btn = QPushButton("打开图片", self)
        self.btn.resize(200, 80)
        self.btn.move((self.width() - self.btn.width()) / 2,
                      (self.height() - self.btn.height()) / 2)
        self.btn.setFont(QFont("", 20, QFont.Bold))
        self.btn.clicked.connect(self.btnClicked)

        self.show()

    def btnClicked(self):

        self.open()

    def open(self, file=None):
        if file is None:
            self.chooseFile()
        else:
            self.key = file.replace("\\", "/")

        # 获取图像列表
        if self.key:
            self.btn.setEnabled(False)  # 选择了文件按钮消失
            self.imgfiles = []  # 如果选择了文件则则重新获取图像列表
            self.file_path = os.path.dirname(self.key)  # 获取文件路径
            try:
                for file in os.listdir(self.file_path):
                    if os.path.splitext(file)[1].lower() in self.formats:
                        self.imgfiles.append(self.file_path + "/" + file)
                self.count = len(self.imgfiles)  # 图像列表总数量
                self.index = self.imgfiles.index(self.key)  # 当前图像在图像列表中位置
            except FileNotFoundError:
                print("文件目录不存在!")

        self.showImage()

    def chooseFile(self):
        # 选择图片文件
        self.key, _ = QFileDialog.getOpenFileName(
            self, "选择文件", self.file_path,
            "图片文件 (*.bmp *.jpg *.jpeg *.png *.gif)")

    def showImage(self):

        if self.key:
            self.img = QPixmap(self.key)
            if self.img.isNull():
                QMessageBox.information(self, "Magic Viewer",
                                        "不能打开文件:%s!" % self.key)
                return

            self.scene = QGraphicsScene()
            self.view = QGraphicsView(self.scene)
            self.view.setDragMode(QGraphicsView.ScrollHandDrag)
            # self.view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
            # self.view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)

            self.scene.clear()
            self.view.resetTransform()
            self.scene.addPixmap(self.img)

            self.zoom = 1  # 缩放系数
            self.rotate = 0  # 旋转系数

            # 如果图片尺寸>窗口尺寸,计算缩放系数进行缩放
            if self.img.width() > self.width() or self.img.height(
            ) > self.height():
                self.zoom = min(self.width() / self.img.width(),
                                self.height() / self.img.height()) * 0.995

            width = self.img.width()
            height = self.img.height()

            # self.scene.setSceneRect(0, 0, width - 2, height - 2)
            self.view.resize(width, height)
            self.setCentralWidget(self.view)
            self.updateView()
            self.show()

    # 获取文件大小
    def fileSize(self, file):
        size = QFileInfo(file).size()

        if size < 1024:
            return str(size), "B"
        elif 1024 <= size < 1024 * 1024:
            return str(round(size / 1024, 2)), "KB"
        else:
            return str(round(size / 1024 / 1024, 2)), "MB"

    # 全屏
    def toggleFullscreen(self):

        if self.isFullScreen():
            self.showNormal()
        else:
            self.showFullScreen()

    def keyPressEvent(self, event):

        if event.key() == Qt.Key_F11:
            self.toggleFullscreen()
        elif event.key() == Qt.Key_Up or event.key() == Qt.Key_W:
            self.zoomIn()
        elif event.key() == Qt.Key_Down or event.key() == Qt.Key_S:
            self.zoomOut()
        elif event.key() == Qt.Key_1:
            self.zoomReset()
        elif event.key() == Qt.Key_E:
            self.rotateImg(-1)
        elif event.key() == Qt.Key_R:
            self.rotateImg(1)
        elif event.key() == Qt.Key_F:
            self.fitView()
        elif event.key() == Qt.Key_Right or event.key() == Qt.Key_Space:
            self.dirBrowse(1)
        elif event.key() == Qt.Key_Left or event.key() == Qt.Key_B:
            self.dirBrowse(-1)
        elif event.key() == Qt.Key_Q or event.key() == Qt.Key_Escape:
            self.close()
        elif event.key() == Qt.Key_O:
            self.btnClicked()

    def mouseDoubleClickEvent(self, event):

        self.toggleFullscreen()

    def zoomIn(self):

        self.zoom *= 1.05
        self.updateView()

    def zoomOut(self):

        self.zoom /= 1.05
        self.updateView()

    def zoomReset(self):

        self.zoom = 1
        self.updateView()

    def rotateImg(self, clock):

        self.rotval += clock
        if self.rotval == 4:
            self.rotval = 0
        elif self.rotval < 0:
            self.rotval = 3
        self.rotate = self.rotvals[self.rotval]
        self.updateView()

    def fitView(self):

        self.view.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
        if self.rotate == 0:
            self.zoom = self.view.transform().m11()
        elif self.rotate == -90:
            self.zoom = (self.view.transform().m12()) * -1
        elif self.rotate == -180:
            self.zoom = (self.view.transform().m11()) * -1
        else:
            self.zoom = self.view.transform().m12()

    def updateView(self):

        self.view.setTransform(QTransform().scale(self.zoom, self.zoom).rotate(
            self.rotate))
        # 更新标题信息
        self.title = os.path.basename(self.key)
        size = self.fileSize(self.key)
        self.setWindowTitle(
            "%s(%sx%s,%s %s) - Magic Viewer - 第%s/%s张 %.2f%%" %
            (self.title, self.img.width(), self.img.height(), size[0], size[1],
             self.index + 1, self.count, self.zoom * 100))

    def dirBrowse(self, direc):

        if self.count > 1:
            self.index += direc
            # 最后一张后跳到第一张,第一张前跳到最后一张
            if self.index > self.count - 1:
                self.index = 0
            elif self.index < 0:
                self.index = self.count - 1

            self.key = self.imgfiles[self.index]

            self.showImage()

    def wheelEvent(self, event):
        # 鼠标滚动
        moose = event.angleDelta().y() / 120
        if moose > 0:
            self.zoomIn()
        elif moose < 0:
            self.zoomOut()

    def contextMenuEvent(self, event):
        # 右键菜单
        menu = QMenu()
        menu.addAction(QIcon('image\\zoom_in.png'), '放大          Scorll Up, W',
                       self.zoomIn)
        menu.addAction(QIcon('image\\zoom_out.png'),
                       '缩小          Scroll Down, S', self.zoomOut)
        menu.addAction(QIcon('image\\full.png'), '全屏          F11',
                       self.toggleFullscreen)
        menu.addAction(QIcon('image\\rotate_right.png'), '右转90°     R',
                       partial(self.rotateImg, 1))
        menu.addAction(QIcon('image\\rotate_left.png'), '左转90°     E',
                       partial(self.rotateImg, -1))
        menu.addAction(QIcon('image\\next.png'), '下一张       Right, SPACE',
                       partial(self.dirBrowse, 1))
        menu.addAction(QIcon('image\\previous.png'), '上一张       Left, B',
                       partial(self.dirBrowse, -1))
        menu.addAction('适合屏幕    F', self.fitView)
        menu.addAction('实际尺寸    1', self.zoomReset)
        menu.addSeparator()
        menu.addAction('打开          O', self.open)
        menu.addAction('退出          Q, ESC', self.close)
        menu.addSeparator()
        menu.addAction('关于Magic Viewer', self.about)

        menu.exec_(event.globalPos())

    def about(self):
        QMessageBox.about(
            self, "关于Magic Viewer", "<b>Magic Viewer</b>是一个基于PyQt5的开源图片浏览器<br>"
            "作者 : Youth Lee<br>"
            "版本 : Ver 0.3<br>"
            "网址 : <a href='https://github.com/createnewli/Magic-Viewer'>https://github.com/createnewli/Magic-Viewer</a>"
        )
Beispiel #23
0
class MyWinMap(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.initWidget()  # 初始化组件
        self.initLayout()  # 初始化布局
        self.initWindow(800, 700)  # 初始化窗口
        self.initMap()  # 初始化地图
        self.initSerial(STR_COM)  # 初始化串口
        self.show()

    '''----------------------------------------------'''

    def initWidget(self):
        '''地图显示控件'''
        self.gscene_map = QGraphicsScene()
        self.gview_map = QGraphicsView(self.gscene_map)
        '''设定节点及阈值区'''
        self.chb_mark = QCheckBox('进入标记模式')
        self.chb_mark.toggle()
        self.sp_thre = QSpinBox()
        self.sp_thre.setRange(0, 10)  # 设置上界和下界
        '''数据显示区'''

    def initLayout(self):
        '''箱组声明'''
        self.gpbx_map = QGroupBox('地图', self)
        self.gpbx_mark_and_thre = QGroupBox('设定节点及阈值', self)
        self.gpbx_data = QGroupBox('数据', self)
        '''箱组布局类型'''
        self.lot_v_map = QVBoxLayout()
        self.lot_g_mark_and_thre = QGridLayout()
        self.lot_g_data = QGridLayout()
        self.lot_v_all = QVBoxLayout()
        '''箱组map布局设置'''
        self.lot_v_map.addWidget(self.gview_map, alignment=Qt.AlignHCenter)
        self.gpbx_map.setLayout(self.lot_v_map)
        '''箱组mark and thre布局设置'''
        #  _ __ __ _ _
        # |_|__|__|_|_|
        self.lot_g_mark_and_thre.addWidget(self.chb_mark, 0, 1, 1, 1,
                                           Qt.AlignCenter)
        self.lot_g_mark_and_thre.addWidget(self.sp_thre, 0, 3, 1, 1,
                                           Qt.AlignCenter)
        self.lot_g_mark_and_thre.setColumnStretch(0, 1)
        self.lot_g_mark_and_thre.setColumnStretch(1, 2)
        self.lot_g_mark_and_thre.setColumnStretch(2, 2)
        self.lot_g_mark_and_thre.setColumnStretch(3, 1)
        self.lot_g_mark_and_thre.setColumnStretch(4, 1)
        self.gpbx_mark_and_thre.setLayout(self.lot_g_mark_and_thre)
        '''箱组data布局设置'''
        for i in range(NODE_NUM):
            # 数据框
            le_temp = QLineEdit('*')
            le_temp.setReadOnly(True)
            le_temp.setAlignment(Qt.AlignHCenter)
            self.lot_g_data.addWidget(le_temp, 0, i)
        for i in range(NODE_NUM):
            # 节点号框
            lb_temp = QLabel('<div style="color:#d648ac;"><b>' + str(i + 1) +
                             '</b></div>')
            lb_temp.setAlignment(Qt.AlignCenter)
            self.lot_g_data.addWidget(lb_temp, 1, i)
        self.gpbx_data.setLayout(self.lot_g_data)
        '''总布局设置'''
        self.lot_v_all.addWidget(self.gpbx_map)
        self.lot_v_all.addWidget(self.gpbx_mark_and_thre)
        self.lot_v_all.addWidget(self.gpbx_data)
        self.setLayout(self.lot_v_all)

    def initWindow(self, w, h):
        '''获取屏幕居中点信息'''
        center_point = QDesktopWidget().availableGeometry().center()
        self.center_point_x = center_point.x()
        self.center_point_y = center_point.y()
        '''窗口初始化'''
        self.setGeometry(0, 0, w, h)
        self.max_w = (self.center_point_x - 10) * 2  # 窗口允许的最大宽
        self.max_h = (self.center_point_y - 20) * 2  # 窗口允许的最大高
        self.setMaximumSize(self.max_w, self.max_h)  # 防止窗口尺寸过大
        self.moveToCenter(w, h)
        self.win_name = GUI_NAME  # 窗口标题
        self.setWindowTitle(self.win_name)

    def moveToCenter(self, w, h):
        '''窗口过大则先进行调整'''
        if (w > self.max_w) or (h > self.max_h):
            self.adjustSize()
        '''窗口居中'''
        topleft_point_x = (int)(self.center_point_x - w / 2)
        topleft_point_y = (int)(self.center_point_y - h / 2)
        self.move(topleft_point_x, topleft_point_y)

    def initMap(self):
        try:
            # 地图加载部分
            self.pixmap_map = QPixmap('平面图_走廊_房间.png')
            if self.pixmap_map.isNull():  # 空图处理
                self.initMapErrorHandle()
                return
            self.pixmap_map = self.pixmap_map.scaled(700, 600,
                                                     Qt.KeepAspectRatio,
                                                     Qt.SmoothTransformation)
            self.gscene_map.addPixmap(self.pixmap_map)
            # 固定边界以禁用滑动条
            self.f_pixmap_map_x = float(self.pixmap_map.rect().x())
            self.f_pixmap_map_y = float(self.pixmap_map.rect().y())
            self.f_pixmap_map_w = float(self.pixmap_map.rect().width())
            self.f_pixmap_map_h = float(self.pixmap_map.rect().height())
            self.gview_map.setSceneRect(self.f_pixmap_map_x,
                                        self.f_pixmap_map_y,
                                        self.f_pixmap_map_w,
                                        self.f_pixmap_map_h)
            # 地图加载成功的标志位
            self.b_map_loaded = True
            # 复选框信号连接
            self.chb_mark.stateChanged.connect(self.updateMap)
            # view视图鼠标响应
            self.gview_map.mousePressEvent = self.markMap
            w = self.width()
            h = self.height()
            self.moveToCenter(w, h)
            # 节点相关部分
            self.node_list = []  # 存储节点的坐标及邻域信息
        except Exception as e:
            print(e)
            self.initMapErrorHandle()

    def initMapErrorHandle(self):
        self.b_map_loaded = False
        self.text_warning = '<div style="font:20px;\
                            color:red;\
                            text-align:center;">\
                            <b>⚠ WARNING ⚠</b><br /><br />\
                            地图加载出错啦<br /><br />\
                            ::>﹏<::\
                            </div>'

        self.gtext_warning = QGraphicsTextItem()
        self.gtext_warning.setHtml(self.text_warning)
        self.gscene_map.addItem(self.gtext_warning)

    def markMap(self, event):
        if self.b_map_loaded:
            if self.chb_mark.isChecked():
                self.node_pos = self.gview_map.mapToScene(event.pos())
                # 左键创建标记
                if event.button() == Qt.LeftButton:
                    if len(self.node_list) < NODE_NUM:
                        _is_near_init = False  # 标记模式下,初始化无近邻rssi
                        _append_iter = [self.node_pos,
                                        _is_near_init]  # 用list存储复合信息
                        self.node_list.append(_append_iter)
                        # 绘图部分
                        self.drawNode(len(self.node_list), _append_iter[0],
                                      _append_iter[1])
                # 右键回退标记
                if event.button() == Qt.RightButton:
                    if len(self.node_list) > 0:
                        self.node_list.pop()
                        self.gscene_map.clear()  # 清空scene
                        self.gscene_map.addPixmap(self.pixmap_map)  # 重新加载地图
                        for i in range(len(self.node_list)):
                            self.drawNode(i + 1, self.node_list[i][0],
                                          self.node_list[i][1])

    def updateMap(self):
        if self.b_map_loaded:
            if not self.chb_mark.isChecked():
                self.timer_map_refresh = QTimer(self)  # 设定地图刷新定时器
                self.timer_map_refresh.timeout.connect(self.redrawMap)
                self.timer_map_refresh.start(REFRESH_TIME_MS)  # 设置刷新时间为100毫秒

    def redrawMap(self):
        self.gscene_map.clear()  # 清空scene
        self.gscene_map.addPixmap(self.pixmap_map)  # 重新加载地图
        for i in range(len(self.node_list)):
            self.drawNode(i + 1, self.node_list[i][0], self.node_list[i][1])

    '''----------------------------------------------'''

    def drawNode(self, index, node_pos, is_near):
        # 样式设置
        node_draw_r = 15
        node_draw_x = node_pos.x() - node_draw_r
        node_draw_y = node_pos.y() - node_draw_r
        # node_draw_pos = QPointF(node_draw_x, node_draw_y)
        node_draw_pen = QPen(QColor(204, 47, 105), 3, Qt.SolidLine)
        node_draw_brush = QBrush(QColor(255, 110, 151), Qt.SolidPattern)
        # 正式画圆
        self.gellipse_node = self.gscene_map.addEllipse(
            node_draw_x, node_draw_y, 2 * node_draw_r, 2 * node_draw_r,
            node_draw_pen, node_draw_brush)
        # 索引号
        self.text_index = '<div style=\"font:26px;color:black;font-weight:900;\">' + \
            str(index) + '</div>'
        self.gtext_index = QGraphicsTextItem()
        self.gtext_index.setHtml(self.text_index)
        self.gtext_index.setParentItem(self.gellipse_node)
        self.gtext_index.setPos(node_draw_x + 4, node_draw_y - 2)
        if is_near:  # 若附近rssi判断有效
            node_draw_r = 20
            node_draw_x = node_pos.x() - node_draw_r
            node_draw_y = node_pos.y() - node_draw_r
            node_draw_pen = QPen(QColor(245, 229, 143), 10, Qt.DashLine)
            self.gscene_map.addEllipse(node_draw_x, node_draw_y,
                                       2 * node_draw_r, 2 * node_draw_r,
                                       node_draw_pen)

    '''----------------------------------------------'''

    def initSerial(self, str_com):
        self.data_zigbee_list = []
        # 初始化串口
        self.ser_data = QSerialPort(STR_COM,
                                    baudRate=QSerialPort.Baud115200,
                                    readyRead=self.receive)
        self.ser_data.open(QIODevice.ReadWrite)
        if self.ser_data.isOpen():
            print('串口开启成功!')
        else:
            print('串口打开失败……')

    @pyqtSlot()
    def receive(self):
        _data = self.ser_data.readLine().data()  # 读取数据
        if _data != b'':
            self.data_zigbee_list = []  # 清空数据
            self.data = _data[0:2 * NODE_NUM].decode("gbk")
            # 存储数据
            for i in range(len(self.data) // 2):
                # 每两位存储,用tuple存储,只读
                data_iter = (self.data[2 * i:2 * i + 1],
                             self.data[2 * i + 1:2 * i + 2])
                self.data_zigbee_list.append(data_iter)
            # print('data_zigbee_list:', self.data_zigbee_list)
            self.updateSerial()
        else:
            print('串口接收内容为空!')

    def updateSerial(self):
        if not self.chb_mark.isChecked():
            for i in range(NODE_NUM):
                if i < len(self.node_list):
                    value_update = self.data_zigbee_list[i][1]
                    # 更新节点列表
                    self.node_list[i][1] = (True
                                            if value_update == '1' else False)
                else:
                    value_update = '*'
                self.lot_g_data.itemAt(i).widget().setText(value_update)
Beispiel #24
0
class CAvatar(QWidget):
    Circle = 0  # 圆圈
    Rectangle = 1  # 圆角矩形
    SizeLarge = QSize(128, 128)
    SizeMedium = QSize(64, 64)
    SizeSmall = QSize(32, 32)
    StartAngle = 0  # 起始旋转角度
    EndAngle = 360  # 结束旋转角度
    clicked = pyqtSignal(bool)

    def __init__(self,
                 *args,
                 shape=0,
                 url='',
                 cacheDir=False,
                 size=QSize(64, 64),
                 animation=False,
                 **kwargs):
        super(CAvatar, self).__init__(*args, **kwargs)
        self.url = ''
        self._angle = 0  # 角度
        self.pradius = 0  # 加载进度条半径
        self.animation = animation  # 是否使用动画
        self._movie = None  # 动态图
        self._pixmap = QPixmap()  # 图片对象
        self.pixmap = QPixmap()  # 被绘制的对象
        self.isGif = url.endswith('.gif')
        # 进度动画定时器
        self.loadingTimer = QTimer(self, timeout=self.onLoading)
        # 旋转动画
        self.rotateAnimation = QPropertyAnimation(self,
                                                  b'angle',
                                                  self,
                                                  loopCount=1)
        self.setShape(shape)
        self.setCacheDir(cacheDir)
        self.setSize(size)
        self.setUrl(url)

    def paintEvent(self, event):
        super(CAvatar, self).paintEvent(event)
        # 画笔
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing, True)
        painter.setRenderHint(QPainter.HighQualityAntialiasing, True)
        painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
        # 绘制
        path = QPainterPath()
        diameter = min(self.width(), self.height())
        if self.shape == self.Circle:
            radius = int(diameter / 2)
        elif self.shape == self.Rectangle:
            radius = 4
        halfW = self.width() / 2
        halfH = self.height() / 2
        painter.translate(halfW, halfH)
        path.addRoundedRect(QRectF(-halfW, -halfH, diameter, diameter), radius,
                            radius)
        painter.setClipPath(path)
        # 如果是动画效果
        if self.rotateAnimation.state() == QPropertyAnimation.Running:
            painter.rotate(self._angle)  # 旋转
            painter.drawPixmap(
                QPointF(-self.pixmap.width() / 2, -self.pixmap.height() / 2),
                self.pixmap)
        else:
            painter.drawPixmap(-int(halfW), -int(halfH), self.pixmap)
        # 如果在加载
        if self.loadingTimer.isActive():
            diameter = 2 * self.pradius
            painter.setBrush(
                QColor(45, 140, 240, (1 - self.pradius / 10) * 255))
            painter.setPen(Qt.NoPen)
            painter.drawRoundedRect(
                QRectF(-self.pradius, -self.pradius, diameter, diameter),
                self.pradius, self.pradius)

    def enterEvent(self, event):
        """鼠标进入动画
        :param event:
        """
        if not (self.animation and not self.isGif):
            return
        self.rotateAnimation.stop()
        cv = self.rotateAnimation.currentValue() or self.StartAngle
        self.rotateAnimation.setDuration(540 if cv ==
                                         0 else int(cv / self.EndAngle * 540))
        self.rotateAnimation.setStartValue(cv)
        self.rotateAnimation.setEndValue(self.EndAngle)
        self.rotateAnimation.start()

    def leaveEvent(self, event):
        """鼠标离开动画
        :param event:
        """
        if not (self.animation and not self.isGif):
            return
        self.rotateAnimation.stop()
        cv = self.rotateAnimation.currentValue() or self.EndAngle
        self.rotateAnimation.setDuration(int(cv / self.EndAngle * 540))
        self.rotateAnimation.setStartValue(cv)
        self.rotateAnimation.setEndValue(self.StartAngle)
        self.rotateAnimation.start()

    def mousePressEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.clicked.emit(True)

    def onLoading(self):
        """更新进度动画
        """
        if self.loadingTimer.isActive():
            if self.pradius > 9:
                self.pradius = 0
            self.pradius += 1
        else:
            self.pradius = 0
        self.update()

    def onFinished(self):
        """图片下载完成
        """
        self.loadingTimer.stop()
        self.pradius = 0
        reply = self.sender()
        if self.isGif:
            self._movie = QMovie(reply, b'gif', self)
            if self._movie.isValid():
                self._movie.frameChanged.connect(self._resizeGifPixmap)
                self._movie.start()
        else:
            data = reply.readAll().data()
            reply.deleteLater()
            del reply
            self._pixmap.loadFromData(data)
            if self._pixmap.isNull():
                self._pixmap = QPixmap(self.size())
                self._pixmap.fill(QColor(204, 204, 204))
            self._resizePixmap()

    def onError(self, code):
        """下载出错了
        :param code:
        """
        self._pixmap = QPixmap(self.size())
        self._pixmap.fill(QColor(204, 204, 204))
        self._resizePixmap()

    def refresh(self):
        """强制刷新
        """
        self._get(self.url)

    def isLoading(self):
        """判断是否正在加载
        """
        return self.loadingTimer.isActive()

    def setShape(self, shape):
        """设置形状
        :param shape:        0=圆形, 1=圆角矩形
        """
        self.shape = shape

    def setUrl(self, url):
        """设置url,可以是本地路径,也可以是网络地址
        :param url:
        """
        self.url = url
        # print('设置头像', url)
        self._get(url)

    def setCacheDir(self, cacheDir=''):
        """设置本地缓存路径
        :param cacheDir:
        """
        self.cacheDir = cacheDir
        self._initNetWork()

    def setSize(self, size):
        """设置固定尺寸
        :param size:
        """
        if not isinstance(size, QSize):
            size = self.SizeMedium
        self.setMinimumSize(size)
        self.setMaximumSize(size)
        self._resizePixmap()

    @pyqtProperty(int)
    def angle(self):
        return self._angle

    @angle.setter
    def angle(self, value):
        self._angle = value
        self.update()

    def _resizePixmap(self):
        """缩放图片
        """
        if not self._pixmap.isNull():
            self.pixmap = self._pixmap.scaled(self.width(), self.height(),
                                              Qt.IgnoreAspectRatio,
                                              Qt.SmoothTransformation)
        self.update()

    def _resizeGifPixmap(self, _):
        """缩放动画图片
        """
        if self._movie:
            self.pixmap = self._movie.currentPixmap().scaled(
                self.width(), self.height(), Qt.IgnoreAspectRatio,
                Qt.SmoothTransformation)
        self.update()

    def _initNetWork(self):
        """初始化异步网络库
        """
        if not hasattr(qApp, '_network'):
            network = QNetworkAccessManager(self.window())
            setattr(qApp, '_network', network)
        # 是否需要设置缓存
        if self.cacheDir and not qApp._network.cache():
            cache = QNetworkDiskCache(self.window())
            cache.setCacheDirectory(self.cacheDir)
            qApp._network.setCache(cache)

    def _get(self, url):
        """设置图片或者请求网络图片
        :param url:
        """
        if not url:
            self.onError('')
            return
        if url.startswith('http') and not self.loadingTimer.isActive():
            url = QUrl(url)
            request = QNetworkRequest(url)
            # request.setHeader(QNetworkRequest.UserAgentHeader, b'CAvatar')
            # request.setRawHeader(b'Author', b'Irony')
            request.setAttribute(QNetworkRequest.FollowRedirectsAttribute,
                                 True)
            if qApp._network.cache():
                request.setAttribute(QNetworkRequest.CacheLoadControlAttribute,
                                     QNetworkRequest.PreferNetwork)
                request.setAttribute(QNetworkRequest.CacheSaveControlAttribute,
                                     True)
            reply = qApp._network.get(request)
            self.pradius = 0
            self.loadingTimer.start(50)  # 显示进度动画
            reply.finished.connect(self.onFinished)
            reply.error.connect(self.onError)
            return
        self.pradius = 0
        if os.path.exists(url) and os.path.isfile(url):
            if self.isGif:
                self._movie = QMovie(url, parent=self)
                if self._movie.isValid():
                    self._movie.frameChanged.connect(self._resizeGifPixmap)
                    self._movie.start()
            else:
                self._pixmap = QPixmap(url)
                self._resizePixmap()
        else:
            self.onError('')
Beispiel #25
0
class Viewer(QtMainWindow):
    jobAdded = Signal()
    jobFinished = Signal()

    def __init__(self, weboob, parent=None):
        super(Viewer, self).__init__(parent)

        self.ui = Ui_Viewer()
        self.ui.setupUi(self)
        self.ui.prevButton.clicked.connect(self.prev)
        self.ui.nextButton.clicked.connect(self.next)
        self.ui.firstButton.clicked.connect(self.first)
        self.ui.lastButton.clicked.connect(self.last)
        self.ui.actionZoomIn.triggered.connect(self.zoomIn)
        self.ui.actionZoomOut.triggered.connect(self.zoomOut)
        self.ui.actionFullSize.triggered.connect(self.zoomFullSize)
        self.ui.actionFitWindow.triggered.connect(self.zoomFit)

        self.ui.actionSaveImage.setShortcut(QKeySequence.Save)
        self.ui.actionSaveImage.triggered.connect(self.saveImage)
        self.ui.actionClose.setShortcut(QKeySequence.Close)
        self.ui.actionClose.triggered.connect(self.close)

        self.model = None
        self.current = None
        self.total = 0
        self.zoomFactor = 1
        self.zoomMode = ZOOM_FACTOR
        self.weboob = weboob

    def setData(self, model, qidx):
        self.model = model
        self.current = QPersistentModelIndex(qidx)

        self.model.rowsInserted.connect(self.updatePos)
        self.model.rowsRemoved.connect(self.updatePos)
        self.model.rowsInserted.connect(self.updateNavButtons)
        self.model.rowsRemoved.connect(self.updateNavButtons)
        self.model.dataChanged.connect(self._dataChanged)
        self.model.modelReset.connect(self.disable)

        self.updateImage()

    @Slot()
    def disable(self):
        self.setEnabled(False)

    def updateNavButtons(self):
        prev = self.current.row() > 0
        self.ui.prevButton.setEnabled(prev)
        self.ui.firstButton.setEnabled(prev)
        next = self.current.row() < self.total - 1
        self.ui.nextButton.setEnabled(next)
        self.ui.lastButton.setEnabled(next)

    def updatePos(self):
        self.total = self.model.rowCount(self.current.parent())
        self.ui.posLabel.setText('%d / %d' % (self.current.row() + 1, self.total))

    def updateImage(self):
        self.updatePos()
        self.updateNavButtons()

        obj = self.current.data(ResultModel.RoleObject)

        if obj.data is NotLoaded:
            self.model.fillObj(obj, ['data'], QModelIndex(self.current))
            self.pixmap = None
        elif obj.data:
            self.pixmap = QPixmap(QImage.fromData(obj.data))
        else:
            self.pixmap = QPixmap()

        self._rebuildImage()

    @Slot(QModelIndex)
    def _dataChanged(self, qidx):
        if qidx == self.current:
            obj = qidx.data(ResultModel.RoleObject)

            if obj.data:
                self.pixmap = QPixmap(QImage.fromData(obj.data))
            else:
                self.pixmap = QPixmap()
            self._rebuildImage()

    @Slot()
    def next(self):
        new = self.current.sibling(self.current.row() + 1, 0)
        if not new.isValid():
            return
        self.current = QPersistentModelIndex(new)
        self.updateImage()

    @Slot()
    def prev(self):
        if self.current.row() == 0:
            return
        self.current = QPersistentModelIndex(self.current.sibling(self.current.row() - 1, 0))
        self.updateImage()

    @Slot()
    def first(self):
        self.current = QPersistentModelIndex(self.current.sibling(0, 0))
        self.updateImage()

    @Slot()
    def last(self):
        self.current = QPersistentModelIndex(self.current.sibling(self.total - 1, 0))
        self.updateImage()

    @Slot()
    def zoomIn(self):
        self.zoomFactor *= 1.25
        self.zoomMode = ZOOM_FACTOR
        self._rebuildImage()

    @Slot()
    def zoomOut(self):
        self.zoomFactor *= 0.75
        self.zoomMode = ZOOM_FACTOR
        self._rebuildImage()

    @Slot()
    def zoomFullSize(self):
        self.zoomFactor = 1
        self.zoomMode = ZOOM_FACTOR
        self._rebuildImage()

    @Slot()
    def zoomFit(self):
        self.zoomMode = ZOOM_FIT
        self._rebuildImage()

    def resizeEvent(self, ev):
        super(Viewer, self).resizeEvent(ev)
        if self.zoomMode == ZOOM_FIT:
            self._rebuildImage()

    def _rebuildZoom(self):
        if self.zoomMode == ZOOM_FACTOR:
            new_width = int(self.pixmap.width() * self.zoomFactor)
            pixmap = self.pixmap.scaledToWidth(new_width, Qt.SmoothTransformation)
        else:
            new_size = self.ui.scrollArea.viewport().size()
            pixmap = self.pixmap.scaled(new_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
            self.zoomFactor = pixmap.width() / float(self.pixmap.width())
        return pixmap

    def _rebuildImage(self):
        if self.pixmap is None:
            self.ui.view.setText('Loading...')
            return
        elif self.pixmap.isNull():
            self.ui.view.setText('Image could not be loaded')
            return

        pixmap = self._rebuildZoom()
        self.ui.view.setPixmap(pixmap)

    @Slot()
    def saveImage(self):
        def ext_for_filter(s):
            return re.match(r'(?:[A-Z]+) \(\*\.([a-z]+)\)$', s).group(1)

        if not self.pixmap:
            return

        filters = ['PNG (*.png)', 'JPEG (*.jpg)', 'GIF (*.gif)']

        obj = self.current.data(ResultModel.RoleObject)
        name = '%s.%s' % (obj.title or obj.id or u'', obj.ext or 'png')
        default = filters[0]
        for f in filters:
            if name.endswith(ext_for_filter(f)):
                default = f
        filters = ';;'.join(filters)

        target = os.path.join(self.parent().lastSaveDir, name)
        out, filter = QFileDialog.getSaveFileName(self, 'Save image', target, filters, default)
        if not out:
            return

        ext = ext_for_filter(filter)

        self.parent().lastSaveDir = os.path.dirname(out)
        if not os.path.splitext(out)[1]:
            out = '%s.%s' % (out, ext)

            if os.path.exists(out):
                q = self.tr('%s already exists, are you sure you want to replace it?') % out
                reply = QMessageBox.question(self, self.tr('Overwrite?'), q)
                if reply == QMessageBox.No:
                    return self.saveImage()

        self.pixmap.save(out, ext.upper())
Beispiel #26
0
class ImageWidget(QLabel):
    def __init__(self, parent):
        super(QLabel, self).__init__(parent)

        self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.setMouseTracking(True)
        self.setCursor(Qt.CrossCursor)

        self.thread = RenderThread()
        self.pixmap = QPixmap()
        self.thread.renderedImage.connect(self.updatePixmap)

        self.thread.render()
        # https://stackoverflow.com/questions/7829829/pyqt4-mousemove-event-without-mousepress

        self.state = make_default_state()

        self.thread.load_image(
            "/Users/jonathan/Desktop/scanned on 20180605/Scan.jpeg")

    def mouseMoveEvent(self, event):
        mouse_x = event.pos().x()
        mouse_y = event.pos().y()

        # boxes = self.state.bounding_boxes
        # for box in boxes:
        #     box.selected = self.is_point_in_box(mouse_x, mouse_y, box)
        #     self.thread.render(self.state)

        self.state = self.state._replace(
            mouse_pos=[event.pos().x(), event.pos().y()])
        self.thread.render(self.state)

    def mousePressEvent(self, event):
        mouse_x = event.pos().x()
        mouse_y = event.pos().y()

        # event.buttons() => bitmask of ALL buttons - i.e we can perform multi click etc.
        if event.buttons() & Qt.LeftButton:
            boxes = self.state.bounding_boxes

            for box in boxes:
                box.selected = box.xy_in_bounds(mouse_x, mouse_y)
                self.thread.render(self.state)

            self.state = self.state._replace(bounding_boxes=boxes)

            self.state = self.state._replace(
                drag_start_pos=[mouse_x, mouse_y],
                dragging=True,
            )

    def mouseReleaseEvent(self, event):
        # event.button() (lack of 's') => button that caused the event.
        if event.button() == Qt.LeftButton:
            if self.state.dragging:
                self.state = self.state._replace(
                    drag_end_pos=[event.pos().x(),
                                  event.pos().y()],
                    dragging=False)

                bounding_boxes = self.state.bounding_boxes

                x1 = self.state.drag_start_pos[0]
                x2 = self.state.drag_end_pos[0]
                y1 = self.state.drag_start_pos[1]
                y2 = self.state.drag_end_pos[1]

                # Normalize coordinates (remove difference between start corner and end corner):
                # top left, bottom right => x,y,w,h

                min_x = min(x1, x2)
                min_y = min(y1, y2)
                max_x = max(x1, x2)
                max_y = max(y1, y2)

                x = min_x
                y = min_y
                w = max_x - min_x
                h = max_y - min_y

                box = BoundingBox(x=x, y=y, w=w, h=h, selected=True)

                if box.get_area() > 20:
                    bounding_boxes.append(box)

                self.state = self.state._replace(bounding_boxes=bounding_boxes)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(self.rect(), Qt.black)

        if self.pixmap.isNull():
            painter.setPen(Qt.white)
            painter.drawText(self.rect(), Qt.AlignCenter, "No image loaded...")
            return

        painter.drawPixmap(QPoint(), self.pixmap)

    def updatePixmap(self, image):
        self.pixmap = QPixmap.fromImage(image)
        self.update()
Beispiel #27
0
class Dialog(QDialog):
    """A Dialog with basic layout features:
    
    a main widget,
    an icon or pixmap,
    a separator,
    buttons (provided by a QDialogButtonBox)
    
    """
    def __init__(self,
                 parent=None,
                 message="",
                 title="",
                 icon=None,
                 iconSize=QSize(64, 64),
                 pixmap=None,
                 separator=True,
                 buttonOrientation=Qt.Horizontal,
                 buttons=('ok', 'cancel'),
                 help=None,
                 **kwargs):
        """Initializes the dialog.
        
        parent = a parent widget or None.
        
        The following keyword arguments are recognized:
        - message: the text to display in the message label
        - title: the window title
        - icon or pixmap: shown in the left area
        - iconSize: size of the icon in the left (QSize, default: 64x64)
        - separator: draw a separator line or not (default: True)
        - buttonOrientation: Qt.Horizontal (default) or Qt.Vertical
        - buttons: which buttons to use (default: Ok, Cancel)
        - help: function to call when a help button is clicked.
        
        Other keyword arguments are passed to QDialog.
        
        """
        super(Dialog, self).__init__(parent, **kwargs)
        self._icon = QIcon()
        self._separatorWidget = Separator()
        self._mainWidget = QWidget()
        self._pixmap = QPixmap()
        self._pixmapLabel = QLabel(self)
        self._messageLabel = QLabel(self)
        self._buttonBox = b = QDialogButtonBox(self)
        b.accepted.connect(self.accept)
        b.rejected.connect(self.reject)
        layout = QGridLayout()
        layout.setSpacing(10)
        self.setLayout(layout)

        # handle keyword args
        self._buttonOrientation = buttonOrientation
        self._iconSize = iconSize
        self._separator = separator
        if title:
            self.setWindowTitle(title)
        self.setMessage(message)
        if icon:
            self.setIcon(icon)
        elif pixmap:
            self.setPixmap(pixmap)
        b.helpRequested.connect(help or self.helpRequest)
        self.setStandardButtons(buttons)
        self.reLayout()

    def helpRequest(self):
        """Called when a help button is clicked."""
        pass

    def setButtonOrientation(self, orientation):
        """Sets the button orientation.
        
        Qt.Horizontal (default) puts the buttons at the bottom of the dialog
        in a horizontal row, Qt.Vertical puts the buttons at the right in a
        vertical column.
        
        """
        if orientation != self._buttonOrientation:
            self._buttonOrientation = orientation
            self._buttonBox.setOrientation(orientation)
            self.reLayout()

    def buttonOrientation(self):
        """Returns the button orientation."""
        return self._buttonOrientation

    def setIcon(self, icon):
        """Sets the icon to display in the left area.
        
        May be:
        - None or QIcon()
        - one of 'info', 'warning', 'critical', 'question'
        - a QStyle.StandardPixmap
        - a QIcon.
        
        """
        if icon in standardicons:
            icon = standardicons[icon]
        if isinstance(icon, QStyle.StandardPixmap):
            icon = self.style().standardIcon(icon)
        if icon is None:
            icon = QIcon()
        self._icon = icon
        self.setPixmap(icon.pixmap(self._iconSize))

    def icon(self):
        """Returns the currently set icon as a QIcon."""
        return self._icon

    def setIconSize(self, size):
        """Sets the icon size (QSize or int)."""
        if isinstance(size, int):
            size = QSize(size, size)
        changed = size != self._iconSize
        self._iconSize = size
        if changed and not self._icon.isNull():
            self.setPixmap(self._icon.pixmap(size))

    def iconSize(self):
        """Returns the icon size (QSize)."""
        return self._iconSize

    def setPixmap(self, pixmap):
        """Sets the pixmap to display in the left area."""
        changed = self._pixmap.isNull() != pixmap.isNull()
        self._pixmap = pixmap
        self._pixmapLabel.setPixmap(pixmap)
        if not pixmap.isNull():
            self._pixmapLabel.setFixedSize(pixmap.size())
        if changed:
            self.reLayout()

    def pixmap(self):
        """Returns the currently set pixmap."""
        return self._pixmap

    def setMessage(self, text):
        """Sets the main text in the dialog."""
        self._messageLabel.setText(text)

    def message(self):
        """Returns the main text."""
        return self._messageLabel.text()

    def messageLabel(self):
        """Returns the QLabel displaying the message text."""
        return self._messageLabel

    def buttonBox(self):
        """Returns our QDialogButtonBox instance."""
        return self._buttonBox

    def setStandardButtons(self, buttons):
        """Convenience method to set standard buttons in the button box.
        
        Accepts a sequence of string names from the standardbuttons constant,
        or a QDialogButtonBox.StandardButtons value.
        
        """
        if isinstance(buttons, (set, tuple, list)):
            buttons = functools.reduce(operator.or_,
                                       map(standardbuttons.get, buttons),
                                       QDialogButtonBox.StandardButtons())
        self._buttonBox.setStandardButtons(buttons)

    def button(self, button):
        """Returns the given button.
        
        May be a QDialogButtonBox.StandardButton or a key from standardbuttons.
        
        """
        if button in standardbuttons:
            button = standardbuttons[button]
        return self._buttonBox.button(button)

    def setSeparator(self, enabled):
        """Sets whether to show a line between contents and buttons."""
        changed = self._separator != enabled
        self._separator = enabled
        if changed:
            self.reLayout()

    def hasSeparator(self):
        """Returns whether a separator line is shown."""
        return self._separator

    def setMainWidget(self, widget):
        """Sets the specified widget as our main widget."""
        old = self._mainWidget
        if old:
            old.setParent(None)
        self._mainWidget = widget
        self.reLayout()

    def mainWidget(self):
        """Returns the current main widget (an empty QWidget by default)."""
        return self._mainWidget

    def reLayout(self):
        """(Internal) Lays out all items in this dialog."""
        layout = self.layout()
        while layout.takeAt(0):
            pass

        if not self._pixmap.isNull():
            col = 1
            layout.addWidget(self._pixmapLabel, 0, 0, 2, 1)
        else:
            layout.setColumnStretch(1, 0)
            col = 0
        layout.setColumnStretch(col, 1)
        self._pixmapLabel.setVisible(not self._pixmap.isNull())
        layout.addWidget(self._messageLabel, 0, col)
        layout.addWidget(self._mainWidget, 1, col)
        if self._buttonOrientation == Qt.Horizontal:
            if self._separator:
                layout.addWidget(self._separatorWidget, 2, 0, 1, col + 1)
            layout.addWidget(self._buttonBox, 3, 0, 1, col + 1)
        else:
            if self._separator:
                layout.addWidget(self._separatorWidget, 0, col + 1, 2, 1)
            layout.addWidget(self._buttonBox, 0, col + 2, 2, 1)
        self._separatorWidget.setVisible(self._separator)
Beispiel #28
0
class SnapWidget(QWidget, Ui_SnapWidget):
    """
    Class implementing the snapshot widget.
    """
    ModeFullscreen = 0
    ModeScreen = 1
    ModeRectangle = 2
    ModeFreehand = 3
    ModeEllipse = 4
    
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        """
        super(SnapWidget, self).__init__(parent)
        self.setupUi(self)
        
        self.saveButton.setIcon(UI.PixmapCache.getIcon("fileSaveAs.png"))
        self.takeButton.setIcon(UI.PixmapCache.getIcon("cameraPhoto.png"))
        self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy.png"))
        self.copyPreviewButton.setIcon(UI.PixmapCache.getIcon("editCopy.png"))
        self.setWindowIcon(UI.PixmapCache.getIcon("ericSnap.png"))
        
        self.modeCombo.addItem(self.tr("Fullscreen"),
                               SnapWidget.ModeFullscreen)
        self.modeCombo.addItem(self.tr("Rectangular Selection"),
                               SnapWidget.ModeRectangle)
        self.modeCombo.addItem(self.tr("Ellipical Selection"),
                               SnapWidget.ModeEllipse)
        self.modeCombo.addItem(self.tr("Freehand Selection"),
                               SnapWidget.ModeFreehand)
        if QApplication.desktop().screenCount() > 1:
            self.modeCombo.addItem(self.tr("Current Screen"),
                                   SnapWidget.ModeScreen)
        self.__mode = int(Preferences.Prefs.settings.value("Snapshot/Mode", 0))
        index = self.modeCombo.findData(self.__mode)
        if index == -1:
            index = 0
        self.modeCombo.setCurrentIndex(index)
        
        self.__delay = int(
            Preferences.Prefs.settings.value("Snapshot/Delay", 0))
        self.delaySpin.setValue(self.__delay)
        
        if PYQT_VERSION_STR >= "5.0.0":
            from PyQt5.QtCore import QStandardPaths
            picturesLocation = QStandardPaths.writableLocation(
                QStandardPaths.PicturesLocation)
        else:
            from PyQt5.QtGui import QDesktopServices
            picturesLocation = QDesktopServices.storageLocation(
                QDesktopServices.PicturesLocation)
        self.__filename = Preferences.Prefs.settings.value(
            "Snapshot/Filename",
            os.path.join(picturesLocation,
                         self.tr("snapshot") + "1.png"))
        
        self.__grabber = None
        self.__snapshot = QPixmap()
        self.__savedPosition = QPoint()
        self.__modified = False
        self.__locale = QLocale()
        
        self.__grabberWidget = QWidget(None, Qt.X11BypassWindowManagerHint)
        self.__grabberWidget.move(-10000, -10000)
        self.__grabberWidget.installEventFilter(self)
        
        self.__initFileFilters()
        
        self.__initShortcuts()
        
        self.preview.startDrag.connect(self.__dragSnapshot)
        
        from .SnapshotTimer import SnapshotTimer
        self.__grabTimer = SnapshotTimer()
        self.__grabTimer.timeout.connect(self.__grabTimerTimeout)
        self.__updateTimer = QTimer()
        self.__updateTimer.setSingleShot(True)
        self.__updateTimer.timeout.connect(self.__updatePreview)
        
        self.__updateCaption()
        self.takeButton.setFocus()
    
    def __initFileFilters(self):
        """
        Private method to define the supported image file filters.
        """
        filters = {
            'bmp': self.tr("Windows Bitmap File (*.bmp)"),
            'gif': self.tr("Graphic Interchange Format File (*.gif)"),
            'ico': self.tr("Windows Icon File (*.ico)"),
            'jpg': self.tr("JPEG File (*.jpg)"),
            'mng': self.tr("Multiple-Image Network Graphics File (*.mng)"),
            'pbm': self.tr("Portable Bitmap File (*.pbm)"),
            'pcx': self.tr("Paintbrush Bitmap File (*.pcx)"),
            'pgm': self.tr("Portable Graymap File (*.pgm)"),
            'png': self.tr("Portable Network Graphics File (*.png)"),
            'ppm': self.tr("Portable Pixmap File (*.ppm)"),
            'sgi': self.tr("Silicon Graphics Image File (*.sgi)"),
            'svg': self.tr("Scalable Vector Graphics File (*.svg)"),
            'tga': self.tr("Targa Graphic File (*.tga)"),
            'tif': self.tr("TIFF File (*.tif)"),
            'xbm': self.tr("X11 Bitmap File (*.xbm)"),
            'xpm': self.tr("X11 Pixmap File (*.xpm)"),
        }
        
        outputFormats = []
        writeFormats = QImageWriter.supportedImageFormats()
        for writeFormat in writeFormats:
            try:
                outputFormats.append(filters[bytes(writeFormat).decode()])
            except KeyError:
                pass
        outputFormats.sort()
        self.__outputFilter = ';;'.join(outputFormats)
        
        self.__defaultFilter = filters['png']
    
    def __initShortcuts(self):
        """
        Private method to initialize the keyboard shortcuts.
        """
        self.__quitShortcut = QShortcut(
            QKeySequence(QKeySequence.Quit), self, self.close)
        
        self.__copyShortcut = QShortcut(
            QKeySequence(QKeySequence.Copy), self,
            self.copyButton.animateClick)
        
        self.__quickSaveShortcut = QShortcut(
            QKeySequence(Qt.Key_Q), self, self.__quickSave)
        
        self.__save1Shortcut = QShortcut(
            QKeySequence(QKeySequence.Save), self,
            self.saveButton.animateClick)
        self.__save2Shortcut = QShortcut(
            QKeySequence(Qt.Key_S), self, self.saveButton.animateClick)
        
        self.__grab1Shortcut = QShortcut(
            QKeySequence(QKeySequence.New), self, self.takeButton.animateClick)
        self.__grab2Shortcut = QShortcut(
            QKeySequence(Qt.Key_N), self, self.takeButton.animateClick)
        self.__grab3Shortcut = QShortcut(
            QKeySequence(Qt.Key_Space), self, self.takeButton.animateClick)
    
    def __quickSave(self):
        """
        Private slot to save the snapshot bypassing the file selection dialog.
        """
        if not self.__snapshot.isNull():
            while os.path.exists(self.__filename):
                self.__autoIncFilename()
            
            if self.__saveImage(self.__filename):
                self.__modified = False
                self.__autoIncFilename()
                self.__updateCaption()
    
    @pyqtSlot()
    def on_saveButton_clicked(self):
        """
        Private slot to save the snapshot.
        """
        if not self.__snapshot.isNull():
            while os.path.exists(self.__filename):
                self.__autoIncFilename()
            
            fileName, selectedFilter = E5FileDialog.getSaveFileNameAndFilter(
                self,
                self.tr("Save Snapshot"),
                self.__filename,
                self.__outputFilter,
                self.__defaultFilter,
                E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite))
            if not fileName:
                return
            
            ext = QFileInfo(fileName).suffix()
            if not ext:
                ex = selectedFilter.split("(*")[1].split(")")[0]
                if ex:
                    fileName += ex
            
            if self.__saveImage(fileName):
                self.__modified = False
                self.__filename = fileName
                self.__autoIncFilename()
                self.__updateCaption()
    
    def __saveImage(self, fileName):
        """
        Private method to save the snapshot.
        
        @param fileName name of the file to save to (string)
        @return flag indicating success (boolean)
        """
        if QFileInfo(fileName).exists():
            res = E5MessageBox.yesNo(
                self,
                self.tr("Save Snapshot"),
                self.tr("<p>The file <b>{0}</b> already exists."
                        " Overwrite it?</p>").format(fileName),
                icon=E5MessageBox.Warning)
            if not res:
                return False
        
        file = QFile(fileName)
        if not file.open(QFile.WriteOnly):
            E5MessageBox.warning(
                self, self.tr("Save Snapshot"),
                self.tr("Cannot write file '{0}:\n{1}.")
                .format(fileName, file.errorString()))
            return False
        
        ok = self.__snapshot.save(file)
        file.close()
        
        if not ok:
            E5MessageBox.warning(
                self, self.tr("Save Snapshot"),
                self.tr("Cannot write file '{0}:\n{1}.")
                .format(fileName, file.errorString()))
        
        return ok
    
    def __autoIncFilename(self):
        """
        Private method to auto-increment the file name.
        """
        # Extract the file name
        name = os.path.basename(self.__filename)
        
        # If the name contains a number, then increment it.
        numSearch = QRegExp("(^|[^\\d])(\\d+)")
        # We want to match as far left as possible, and when the number is
        # at the start of the name.
        
        # Does it have a number?
        start = numSearch.lastIndexIn(name)
        if start != -1:
            # It has a number, increment it.
            start = numSearch.pos(2)    # Only the second group is of interest.
            numAsStr = numSearch.capturedTexts()[2]
            number = "{0:0{width}d}".format(
                int(numAsStr) + 1, width=len(numAsStr))
            name = name[:start] + number + name[start + len(numAsStr):]
        else:
            # no number
            start = name.rfind('.')
            if start != -1:
                # has a '.' somewhere, e.g. it has an extension
                name = name[:start] + '1' + name[start:]
            else:
                # no extension, just tack it on to the end
                name += '1'
        
        self.__filename = os.path.join(os.path.dirname(self.__filename), name)
        self.__updateCaption()
    
    @pyqtSlot()
    def on_takeButton_clicked(self):
        """
        Private slot to take a snapshot.
        """
        self.__mode = self.modeCombo.itemData(self.modeCombo.currentIndex())
        self.__delay = self.delaySpin.value()
        
        self.__savedPosition = self.pos()
        self.hide()
        
        if self.__delay:
            self.__grabTimer.start(self.__delay)
        else:
            QTimer.singleShot(200, self.__startUndelayedGrab)
    
    def __grabTimerTimeout(self):
        """
        Private slot to perform a delayed grab operation.
        """
        if self.__mode == SnapWidget.ModeRectangle:
            self.__grabRectangle()
        elif self.__mode == SnapWidget.ModeEllipse:
            self.__grabEllipse()
        elif self.__mode == SnapWidget.ModeFreehand:
            self.__grabFreehand()
        else:
            self.__performGrab()
    
    def __startUndelayedGrab(self):
        """
        Private slot to perform an undelayed grab operation.
        """
        if self.__mode == SnapWidget.ModeRectangle:
            self.__grabRectangle()
        elif self.__mode == SnapWidget.ModeEllipse:
            self.__grabEllipse()
        elif self.__mode == SnapWidget.ModeFreehand:
            self.__grabFreehand()
        else:
            if Globals.isMacPlatform():
                self.__performGrab()
            else:
                self.__grabberWidget.show()
                self.__grabberWidget.grabMouse(Qt.CrossCursor)
    
    def __grabRectangle(self):
        """
        Private method to grab a rectangular screen region.
        """
        from .SnapshotRegionGrabber import SnapshotRegionGrabber
        self.__grabber = SnapshotRegionGrabber(
            mode=SnapshotRegionGrabber.Rectangle)
        self.__grabber.grabbed.connect(self.__captured)
    
    def __grabEllipse(self):
        """
        Private method to grab an elliptical screen region.
        """
        from .SnapshotRegionGrabber import SnapshotRegionGrabber
        self.__grabber = SnapshotRegionGrabber(
            mode=SnapshotRegionGrabber.Ellipse)
        self.__grabber.grabbed.connect(self.__captured)
    
    def __grabFreehand(self):
        """
        Private method to grab a non-rectangular screen region.
        """
        from .SnapshotFreehandGrabber import SnapshotFreehandGrabber
        self.__grabber = SnapshotFreehandGrabber()
        self.__grabber.grabbed.connect(self.__captured)
    
    def __performGrab(self):
        """
        Private method to perform a screen grab other than a selected region.
        """
        self.__grabberWidget.releaseMouse()
        self.__grabberWidget.hide()
        self.__grabTimer.stop()
        
        if self.__mode == SnapWidget.ModeFullscreen:
            desktop = QApplication.desktop()
            if qVersion() >= "5.0.0":
                self.__snapshot = QApplication.screens()[0].grabWindow(
                    desktop.winId(), desktop.x(), desktop.y(),
                    desktop.width(), desktop.height())
            else:
                self.__snapshot = QPixmap.grabWindow(
                    desktop.winId(), desktop.x(), desktop.y(),
                    desktop.width(), desktop.height())
        elif self.__mode == SnapWidget.ModeScreen:
            desktop = QApplication.desktop()
            screenId = desktop.screenNumber(QCursor.pos())
            geom = desktop.screenGeometry(screenId)
            x = geom.x()
            y = geom.y()
            if qVersion() >= "5.0.0":
                self.__snapshot = QApplication.screens()[0].grabWindow(
                    desktop.winId(), x, y, geom.width(), geom.height())
            else:
                self.__snapshot = QPixmap.grabWindow(
                    desktop.winId(), x, y, geom.width(), geom.height())
        else:
            self.__snapshot = QPixmap()
        
        self.__redisplay()
        self.__modified = True
        self.__updateCaption()
    
    def __redisplay(self):
        """
        Private method to redisplay the window.
        """
        self.__updatePreview()
        QApplication.restoreOverrideCursor()
        if not self.__savedPosition.isNull():
            self.move(self.__savedPosition)
        self.show()
        self.raise_()
        
        self.saveButton.setEnabled(not self.__snapshot.isNull())
        self.copyButton.setEnabled(not self.__snapshot.isNull())
        self.copyPreviewButton.setEnabled(not self.__snapshot.isNull())
    
    @pyqtSlot()
    def on_copyButton_clicked(self):
        """
        Private slot to copy the snapshot to the clipboard.
        """
        if not self.__snapshot.isNull():
            QApplication.clipboard().setPixmap(QPixmap(self.__snapshot))
    
    @pyqtSlot()
    def on_copyPreviewButton_clicked(self):
        """
        Private slot to copy the snapshot preview to the clipboard.
        """
        QApplication.clipboard().setPixmap(self.preview.pixmap())
    
    def __captured(self, pixmap):
        """
        Private slot to show a preview of the snapshot.
        
        @param pixmap pixmap of the snapshot (QPixmap)
        """
        self.__grabber.close()
        self.__snapshot = QPixmap(pixmap)
        
        self.__grabber.grabbed.disconnect(self.__captured)
        self.__grabber = None
        
        self.__redisplay()
        self.__modified = True
        self.__updateCaption()
    
    def __updatePreview(self):
        """
        Private slot to update the preview picture.
        """
        self.preview.setToolTip(self.tr(
            "Preview of the snapshot image ({0} x {1})").format(
            self.__locale.toString(self.__snapshot.width()),
            self.__locale.toString(self.__snapshot.height()))
        )
        self.preview.setPreview(self.__snapshot)
        self.preview.adjustSize()
    
    def resizeEvent(self, evt):
        """
        Protected method handling a resizing of the window.
        
        @param evt resize event (QResizeEvent)
        """
        self.__updateTimer.start(200)
    
    def __dragSnapshot(self):
        """
        Private slot handling the dragging of the preview picture.
        """
        drag = QDrag(self)
        mimeData = QMimeData()
        mimeData.setImageData(self.__snapshot)
        drag.setMimeData(mimeData)
        drag.setPixmap(self.preview.pixmap())
        drag.exec_(Qt.CopyAction)
    
    def eventFilter(self, obj, evt):
        """
        Public method to handle event for other objects.
        
        @param obj reference to the object (QObject)
        @param evt reference to the event (QEvent)
        @return flag indicating that the event should be filtered out (boolean)
        """
        if obj == self.__grabberWidget and \
                evt.type() == QEvent.MouseButtonPress:
            if QWidget.mouseGrabber() != self.__grabberWidget:
                return False
            if evt.button() == Qt.LeftButton:
                self.__performGrab()
        
        return False
    
    def closeEvent(self, evt):
        """
        Protected method handling the close event.
        
        @param evt close event (QCloseEvent)
        """
        if self.__modified:
            res = E5MessageBox.question(
                self,
                self.tr("eric6 Snapshot"),
                self.tr(
                    """The application contains an unsaved snapshot."""),
                E5MessageBox.StandardButtons(
                    E5MessageBox.Abort |
                    E5MessageBox.Discard |
                    E5MessageBox.Save))
            if res == E5MessageBox.Abort:
                evt.ignore()
                return
            elif res == E5MessageBox.Save:
                self.on_saveButton_clicked()
        
        Preferences.Prefs.settings.setValue(
            "Snapshot/Delay", self.delaySpin.value())
        Preferences.Prefs.settings.setValue(
            "Snapshot/Mode",
            self.modeCombo.itemData(self.modeCombo.currentIndex()))
        Preferences.Prefs.settings.setValue(
            "Snapshot/Filename", self.__filename)
        Preferences.Prefs.settings.sync()
    
    def __updateCaption(self):
        """
        Private method to update the window caption.
        """
        self.setWindowTitle("{0}[*] - {1}".format(
            os.path.basename(self.__filename),
            self.tr("eric6 Snapshot")))
        self.setWindowModified(self.__modified)
        self.pathNameEdit.setText(os.path.dirname(self.__filename))
Beispiel #29
0
class ImgWatch(QWidget):
    def __init__(self, loader, history):
        super().__init__()

        self.screen_mode = ScreenMode(self)
        self.image_loader = loader

        self.mpos = QPoint()
        self.pixmap = QPixmap()

        self.setWindowTitle('QImgWatch')
        self.resize(1280, 720)
        self.setStyleSheet("background-color: black;")

        if history:
            self.pixmap_history = collections.deque(maxlen=history)
        else:
            self.pixmap_history = None
        self.pixmap_idx = None

        self.setMouseTracking(True)

    def update_pixmap(self, data):
        if not self.pixmap.isNull() and self.pixmap_history is not None:
            self.pixmap_history.append(self.pixmap)

        self.pixmap = QPixmap()
        image = QImage.fromData(data)
        self.pixmap = QPixmap.fromImage(image)

    def keyPressEvent(self, ev):
        if ev.key() == Qt.Key_F11 or ev.key() == Qt.Key_F:
            self.screen_mode.fullscreen_toggle()
        elif ev.key() == Qt.Key_Escape:
            if self.screen_mode.is_fullscreen():
                self.window()
        elif ev.key() == Qt.Key_Q:
            self.close()

    def mouseDoubleClickEvent(self, ev):
        self.screen_mode.fullscreen_toggle()

    def mousePressEvent(self, ev):
        self.mpos = ev.pos()

    def mouseMoveEvent(self, ev):
        if ev.buttons() & Qt.LeftButton:
            diff = ev.pos() - self.mpos
            newpos = self.pos() + diff
            self.move(newpos)

        if self.pixmap_history is not None:
            if ev.pos().y() > self.height() - 200:
                w = self.width() // self.pixmap_history.maxlen
                idx = ev.pos().x() // w
                idx = max(0, min(idx, self.pixmap_history.maxlen))
                if self.pixmap_idx != idx:
                    self.pixmap_idx = idx
                    self.repaint()
            else:
                self.pixmap_idx = None

    def paintEvent(self, ev):
        if self.pixmap.isNull():
            return

        painter = QPainter(self)
        painter.setRenderHints(QPainter.Antialiasing
                               | QPainter.SmoothPixmapTransform)

        if self.pixmap_idx is None or self.pixmap_history is None:
            pixmap = self.pixmap
        else:
            if 0 <= self.pixmap_idx < len(self.pixmap_history):
                pixmap = self.pixmap_history[self.pixmap_idx]
            else:
                pixmap = self.pixmap

        sap = pixmap.width() / pixmap.height()
        tap = self.width() / self.height()
        if sap > tap:
            th = self.width() / sap
            painter.drawPixmap(0,
                               self.height() // 2 - th // 2, self.width(), th,
                               pixmap, 0, 0, pixmap.width(), pixmap.height())
        else:
            tw = sap * self.height()
            painter.drawPixmap(self.width() // 2 - tw // 2, 0, tw,
                               self.height(), pixmap, 0, 0, pixmap.width(),
                               pixmap.height())

        if self.pixmap_history is not None:
            for x, pixmap in enumerate(self.pixmap_history):
                thumb_w = self.width() // self.pixmap_history.maxlen
                thumb_h = 150  # pixmap.height() * thumb_w // self.pixmap.width() * 3
                painter.drawPixmap(x * thumb_w,
                                   self.height() - thumb_h, thumb_w,
                                   thumb_h, pixmap, 0, 0, pixmap.width(),
                                   pixmap.height())
Beispiel #30
0
class RoundRectItem(QGraphicsObject):
    """Base class for most graphic objects in our scene"""
    def __init__(self, bounds, color=None, parent=None):
        """
        Args:
            bounds - QRectF, geometry of object
            color - QColor or None
            parent - widget to contain this graphic item or None
        """
        super(RoundRectItem, self).__init__(parent)

        self._fillRect = False
        self._bounds = QRectF(bounds)
        self._pix = QPixmap()
        self._color = color

        self.setCacheMode(QGraphicsItem.ItemCoordinateCache)

    def setFill(self, fill: bool):
        """
        Changes the property of how the cell is filled.

        Args:
          fill: bool
        """
        self._fillRect = fill
        self.update()

    @property
    def _gradient(self):
        gradient = QLinearGradient()
        gradient.setStart(
            (self._bounds.topLeft() + self._bounds.topRight()) / 2)
        gradient.setFinalStop(
            (self._bounds.bottomLeft() + self._bounds.bottomRight()) / 2)
        gradient.setColorAt(0, self._color)
        gradient.setColorAt(1, self._color.darker(200))
        return gradient

    def paint(self, painter, option, widget):
        """Standard Qt paint event."""
        if self._color:
            painter.setPen(Qt.NoPen)
            painter.setBrush(QColor(0, 0, 0, 64))
            painter.drawRoundedRect(self._bounds.translated(2, 2), 25.0, 25.0)

            if self._fillRect:
                painter.setBrush(QApplication.palette().brush(QPalette.Window))
            else:
                painter.setBrush(self._gradient)

            painter.setPen(QPen(Qt.black, 1))
            painter.drawRoundedRect(self._bounds, 25.0, 25.0)

        if not self._pix.isNull():
            if self._rounded_pixmap:
                painter.setRenderHint(QPainter.Antialiasing, True)
                brush = QBrush(
                    self._pix.scaled(self._bounds.width(),
                                     self._bounds.height()))
                painter.setBrush(brush)
                painter.drawRoundedRect(self._bounds, 25.0, 25.0)
            else:
                painter.scale(self._bounds.width() / self._pix.width(),
                              self._bounds.height() / self._pix.height())
                painter.drawPixmap(-self._pix.width() / 2,
                                   -self._pix.height() / 2, self._pix)

    def boundingRect(self):
        """returns bounding rectangle"""
        return self._bounds.adjusted(0, 0, 2, 2)

    def setPixmap(self, pixmap_path: str, rounded_pixmap=False):
        """
        Sets new pixmap for this graphic object.

        Args:
          pixmap_path: path to image for pixmap
          rounded_pixmap: make the picture rounded (used, e.g., for lava in the cells)
        """
        self._rounded_pixmap = rounded_pixmap
        self._pix = QPixmap(pixmap_path)
        self.update()
Beispiel #31
0
class TrafficUi(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        naming = "no file selected"
        self.setMinimumSize(QSize(1015, 1000))
        self.setWindowTitle("Traffic Management")
        centralWidget = QWidget(self)
        self.setCentralWidget(centralWidget)

        oImage = QImage("b.png")
        sImage = oImage.scaled(QSize(1015, 1000))
        palette = QPalette()
        palette.setBrush(10, QBrush(sImage))
        newfont = QFont('Roboto', 12, QFont.Bold)
        self.setPalette(palette)

        self.run_btn = QPushButton('Start', self)
        self.run_btn.resize(100, 40)
        self.run_btn.move(10, 10)
        self.run_btn.clicked.connect(self.runMethod)

        self.east_label = QLabel("east", self)
        self.east_label.resize(200, 40)
        self.east_label.move(780, 380)
        self.east_label.setFont(newfont)

        self.south_label = QLabel("south", self)
        self.south_label.resize(200, 40)
        self.south_label.move(400, 825)
        self.south_label.setFont(newfont)

        self.west_label = QLabel("west", self)
        self.west_label.resize(200, 40)
        self.west_label.move(160, 380)
        self.west_label.setFont(newfont)

        self.north_label = QLabel("north", self)
        self.north_label.resize(200, 40)
        self.north_label.move(400, 175)
        self.north_label.setFont(newfont)

        self.east_density = QLabel("low", self)
        self.east_density.resize(200, 40)
        self.east_density.move(780, 600)
        self.east_density.setFont(newfont)
        self.east_density.setStyleSheet('color : white;')

        self.south_density = QLabel("low", self)
        self.south_density.resize(200, 40)
        self.south_density.move(600, 825)
        self.south_density.setFont(newfont)
        self.south_density.setStyleSheet('color : white;')

        self.west_density = QLabel("low", self)
        self.west_density.resize(200, 40)
        self.west_density.move(160, 600)
        self.west_density.setFont(newfont)
        self.west_density.setStyleSheet('color : white;')

        self.north_density = QLabel("low", self)
        self.north_density.resize(200, 40)
        self.north_density.move(600, 175)
        self.north_density.setFont(newfont)
        self.north_density.setStyleSheet('color : white;')

        self.traffic_h = QLabel(self)
        self.traffic_h_pixmap = QPixmap('traffic_lamp2.png')
        self.traffic_h_pixmap = self.traffic_h_pixmap.scaled(150, 60)
        self.traffic_h.setPixmap(self.traffic_h_pixmap)
        self.traffic_h.resize(150, 60)
        self.traffic_h.move(425, 780)
        self.traffic_h.hide()
        self.traffic_h.setStyleSheet(
            'border-style: solid; border-width: 0px 3px 0px 3px; border-color: white;'
        )

        self.traffic_h2 = QLabel(self)
        self.traffic_h2_pixmap = QPixmap('traffic_lamp2.png')
        self.traffic_h2_pixmap = self.traffic_h2_pixmap.scaled(150, 60)
        self.traffic_h2.setPixmap(self.traffic_h2_pixmap)
        self.traffic_h2.resize(150, 60)
        self.traffic_h2.move(425, 160)
        self.traffic_h2.hide()
        self.traffic_h2.setStyleSheet(
            'border-style: solid; border-width: 0px 3px 0px 3px; border-color: white;'
        )

        self.traffic_v = QLabel(self)
        self.traffic_v_pixmap = QPixmap('traffic_lamp.png')
        self.traffic_v_pixmap = self.traffic_v_pixmap.scaled(60, 150)
        self.traffic_v.setPixmap(self.traffic_v_pixmap)
        self.traffic_v.resize(60, 150)
        self.traffic_v.move(780, 425)
        self.traffic_v.hide()
        self.traffic_v.setStyleSheet(
            'border-style: solid; border-width: 3px 0px 3px 0px; border-color: white;'
        )

        self.traffic_v2 = QLabel(self)
        self.traffic_v2_pixmap = QPixmap('traffic_lamp.png')
        self.traffic_v2_pixmap = self.traffic_v2_pixmap.scaled(60, 150)
        self.traffic_v2.setPixmap(self.traffic_v2_pixmap)
        self.traffic_v2.resize(60, 150)
        self.traffic_v2.move(160, 425)
        self.traffic_v2.hide()
        self.traffic_v2.setStyleSheet(
            'border-style: solid; border-width: 3px 0px 3px 0px; border-color: white;'
        )

        self.red_label = QLabel(self)
        self.red_pixmap = QPixmap('red.png')
        self.red_pixmap = self.red_pixmap.scaled(50, 50)
        self.red_label.setPixmap(self.red_pixmap)
        self.red_label.resize(50, 50)
        self.red_label.move(785, 428)

        self.red_label2 = QLabel(self)
        self.red_pixmap2 = QPixmap('red.png')
        self.red_pixmap2 = self.red_pixmap2.scaled(50, 50)
        self.red_label2.setPixmap(self.red_pixmap2)
        self.red_label2.resize(50, 50)
        self.red_label2.move(431, 785)

        self.red_label3 = QLabel(self)
        self.red_pixmap3 = QPixmap('red.png')
        self.red_pixmap3 = self.red_pixmap3.scaled(50, 50)
        self.red_label3.setPixmap(self.red_pixmap3)
        self.red_label3.resize(50, 50)
        self.red_label3.move(166, 428)

        self.red_label4 = QLabel(self)
        self.red_pixmap4 = QPixmap('red.png')
        self.red_pixmap4 = self.red_pixmap4.scaled(50, 50)
        self.red_label4.setPixmap(self.red_pixmap4)
        self.red_label4.resize(50, 50)
        self.red_label4.move(431, 166)

        self.yellow_label = QLabel(self)
        self.yellow_pixmap = QPixmap('yellow.png')
        self.yellow_pixmap = self.yellow_pixmap.scaled(50, 50)
        self.yellow_label.setPixmap(self.yellow_pixmap)
        self.yellow_label.resize(50, 50)
        self.yellow_label.move(785, 475)

        self.yellow_label2 = QLabel(self)
        self.yellow_pixmap2 = QPixmap('yellow.png')
        self.yellow_pixmap2 = self.yellow_pixmap2.scaled(50, 50)
        self.yellow_label2.setPixmap(self.yellow_pixmap2)
        self.yellow_label2.resize(50, 50)
        self.yellow_label2.move(478, 785)

        self.yellow_label3 = QLabel(self)
        self.yellow_pixmap3 = QPixmap('yellow.png')
        self.yellow_pixmap3 = self.yellow_pixmap3.scaled(50, 50)
        self.yellow_label3.setPixmap(self.yellow_pixmap3)
        self.yellow_label3.resize(50, 50)
        self.yellow_label3.move(166, 475)

        self.yellow_label4 = QLabel(self)
        self.yellow_pixmap4 = QPixmap('yellow.png')
        self.yellow_pixmap4 = self.yellow_pixmap4.scaled(50, 50)
        self.yellow_label4.setPixmap(self.yellow_pixmap4)
        self.yellow_label4.resize(50, 50)
        self.yellow_label4.move(478, 166)

        self.green_label = QLabel(self)
        self.green_pixmap = QPixmap('green.png')
        self.green_pixmap = self.green_pixmap.scaled(50, 50)
        self.green_label.setPixmap(self.green_pixmap)
        self.green_label.resize(50, 50)
        self.green_label.move(785, 522)

        self.green_label2 = QLabel(self)
        self.green_pixmap2 = QPixmap('green.png')
        self.green_pixmap2 = self.green_pixmap2.scaled(50, 50)
        self.green_label2.setPixmap(self.green_pixmap2)
        self.green_label2.resize(50, 50)
        self.green_label2.move(525, 785)

        self.green_label3 = QLabel(self)
        self.green_pixmap3 = QPixmap('green.png')
        self.green_pixmap3 = self.green_pixmap3.scaled(50, 50)
        self.green_label3.setPixmap(self.green_pixmap3)
        self.green_label3.resize(50, 50)
        self.green_label3.move(166, 522)

        self.green_label4 = QLabel(self)
        self.green_pixmap4 = QPixmap('green.png')
        self.green_pixmap4 = self.green_pixmap4.scaled(50, 50)
        self.green_label4.setPixmap(self.green_pixmap4)
        self.green_label4.resize(50, 50)
        self.green_label4.move(525, 166)

        self.east_road = QLabel(self)
        self.east_road_pixmap = QPixmap('./Test/images/east.png')
        self.east_road_pixmap = self.east_road_pixmap.scaled(150, 150)
        self.east_road.setPixmap(self.east_road_pixmap)
        self.east_road.resize(150, 150)
        self.east_road.move(10, -250)
        self.east_road.setStyleSheet(
            'border-style: solid; border-width: 3px; border-color: white;')

        self.east_road_bbox = QLabel(self)
        self.east_road_bbox_pixmap = QPixmap('./Test/images/east_bbox.png')
        self.east_road_bbox_pixmap = self.east_road_bbox_pixmap.scaled(
            150, 150)
        self.east_road_bbox.setPixmap(self.east_road_bbox_pixmap)
        self.east_road_bbox.resize(150, 150)
        self.east_road_bbox.move(10, -250)
        self.east_road_bbox.setStyleSheet(
            'border-style: solid; border-width: 3px; border-color: white;')

        self.south_road = QLabel(self)
        self.south_road_pixmap = QPixmap('./Test/images/south.png')
        self.south_road_pixmap = self.south_road_pixmap.scaled(150, 150)
        self.south_road.setPixmap(self.south_road_pixmap)
        self.south_road.resize(150, 150)
        self.south_road.move(10, -250)
        self.south_road.setStyleSheet(
            'border-style: solid; border-width: 3px; border-color: white;')

        self.south_road_bbox = QLabel(self)
        self.south_road_bbox_pixmap = QPixmap('./Test/images/south_bbox.png')
        self.south_road_bbox_pixmap = self.south_road_bbox_pixmap.scaled(
            150, 150)
        self.south_road_bbox.setPixmap(self.south_road_bbox_pixmap)
        self.south_road_bbox.resize(150, 150)
        self.south_road_bbox.move(10, -250)
        self.south_road_bbox.setStyleSheet(
            'border-style: solid; border-width: 3px; border-color: white;')

        self.west_road = QLabel(self)
        self.west_road_pixmap = QPixmap('./Test/images/west.png')
        self.west_road_pixmap = self.west_road_pixmap.scaled(150, 150)
        self.west_road.setPixmap(self.west_road_pixmap)
        self.west_road.resize(150, 150)
        self.west_road.move(10, -250)
        self.west_road.setStyleSheet(
            'border-style: solid; border-width: 3px; border-color: white;')

        self.west_road_bbox = QLabel(self)
        self.west_road_bbox_pixmap = QPixmap('./Test/images/west_bbox.png')
        self.west_road_bbox_pixmap = self.west_road_bbox_pixmap.scaled(
            150, 150)
        self.west_road_bbox.setPixmap(self.west_road_bbox_pixmap)
        self.west_road_bbox.resize(150, 150)
        self.west_road_bbox.move(10, -250)
        self.west_road_bbox.setStyleSheet(
            'border-style: solid; border-width: 3px; border-color: white;')

        self.north_road = QLabel(self)
        self.north_road_pixmap = QPixmap('./Test/images/north.png')
        self.north_road_pixmap = self.north_road_pixmap.scaled(150, 150)
        self.north_road.setPixmap(self.north_road_pixmap)
        self.north_road.resize(150, 150)
        self.north_road.move(10, -250)
        self.north_road.setStyleSheet(
            'border-style: solid; border-width: 3px; border-color: white;')

        self.north_road_bbox = QLabel(self)
        self.north_road_bbox_pixmap = QPixmap('./Test/images/north_bbox.png')
        self.north_road_bbox_pixmap = self.north_road_bbox_pixmap.scaled(
            150, 150)
        self.north_road_bbox.setPixmap(self.north_road_bbox_pixmap)
        self.north_road_bbox.resize(150, 150)
        self.north_road_bbox.move(10, -250)
        self.north_road_bbox.setStyleSheet(
            'border-style: solid; border-width: 3px; border-color: white;')

    def runMethod(self):

        t2 = threading.Thread(target=self.print_images)
        t2.start()
        self.runMethod_()

    def runMethod_(self):

        self.run_btn.hide()
        QApplication.processEvents()

        self.east = 30
        self.south = 60
        self.west = 90
        self.north = 120
        self.cur = "east"

        self.east_status = "low"
        self.south_status = "low"
        self.west_status = "low"
        self.north_status = "low"

        self.traffic_v2.show()
        self.traffic_v.show()
        self.traffic_h.show()
        self.traffic_h2.show()

        while (True):
            if self.cur == "east":
                self.east_label.setText(str(self.east))
                self.south_label.setText(str(self.south - 30))
                self.west_label.setText(str(self.west - 30))
                self.north_label.setText(str(self.north - 30))
            if self.cur == "south":
                self.east_label.setText(str(self.east - 30))
                self.south_label.setText(str(self.south))
                self.west_label.setText(str(self.west - 30))
                self.north_label.setText(str(self.north - 30))
            if self.cur == "west":
                self.east_label.setText(str(self.east - 30))
                self.south_label.setText(str(self.south - 30))
                self.west_label.setText(str(self.west))
                self.north_label.setText(str(self.north - 30))
            if self.cur == "north":
                self.east_label.setText(str(self.east - 30))
                self.south_label.setText(str(self.south - 30))
                self.west_label.setText(str(self.west - 30))
                self.north_label.setText(str(self.north))
            QApplication.processEvents()
            self.file = open('val.txt', 'r+')
            self.cont = self.file.read()
            self.cont = self.cont[1:-2]
            self.cont = self.cont.replace(',', '')
            self.east_st, self.south_st, self.west_st, self.north_st = self.cont.split(
                ' ')

            print(self.east_st, self.south_st, self.west_st, self.north_st)

            if float(self.east_st) > 40:
                self.east_status = "High"
            elif float(self.east_st) > 30:
                self.east_status = "Mod"
            else:
                self.east_status = "low"

            if float(self.south_st) > 40:
                self.south_status = "High"
            elif float(self.south_st) > 30:
                self.south_status = "Mod"
            else:
                self.south_status = "low"

            if float(self.west_st) > 40:
                self.west_status = "High"
            elif float(self.west_st) > 30:
                self.west_status = "Mod"
            else:
                self.west_status = "low"

            if float(self.north_st) > 40:
                self.north_status = "High"
            elif float(self.north_st) > 30:
                self.north_status = "Mod"
            else:
                self.north_status = "low"

            print(self.east_status, self.south_status, self.west_status,
                  self.north_status)

            time.sleep(0.9)

            self.east -= 1
            self.south -= 1
            self.west -= 1
            self.north -= 1
            if self.east == 0:
                self.east = 120
                self.south = 30
                self.west = 60
                self.north = 90
                self.cur = "south"
            if self.south == 0:
                self.east = 90
                self.south = 120
                self.west = 30
                self.north = 60
                self.cur = "west"
            if self.west == 0:
                self.east = 60
                self.south = 90
                self.west = 120
                self.north = 30
                self.cur = "north"
            if self.north == 0:
                self.east = 30
                self.south = 60
                self.west = 90
                self.north = 120
                self.cur = "east"

            if self.east > 35:
                self.east_label.setStyleSheet('color: red')
                self.red_label.show()
                self.yellow_label.hide()
                self.green_label.hide()
            elif self.east > 30:
                self.east_label.setStyleSheet('color: yellow')
                self.red_label.hide()
                self.yellow_label.show()
                self.green_label.hide()
            else:
                self.east_label.setStyleSheet('color: green')
                self.red_label.hide()
                self.yellow_label.hide()
                self.green_label.show()

            if self.south > 35:
                self.south_label.setStyleSheet('color: red')
                self.red_label2.show()
                self.yellow_label2.hide()
                self.green_label2.hide()
            elif self.south > 30:
                self.south_label.setStyleSheet('color: yellow')
                self.red_label2.hide()
                self.yellow_label2.show()
                self.green_label2.hide()
            else:
                self.south_label.setStyleSheet('color: green')
                self.red_label2.hide()
                self.yellow_label2.hide()
                self.green_label2.show()

            if self.west > 35:
                self.west_label.setStyleSheet('color: red')
                self.red_label3.show()
                self.yellow_label3.hide()
                self.green_label3.hide()
            elif self.west > 30:
                self.west_label.setStyleSheet('color: yellow')
                self.red_label3.hide()
                self.yellow_label3.show()
                self.green_label3.hide()
            else:
                self.west_label.setStyleSheet('color: green')
                self.red_label3.hide()
                self.yellow_label3.hide()
                self.green_label3.show()

            if self.north > 35:
                self.north_label.setStyleSheet('color: red')
                self.red_label4.show()
                self.yellow_label4.hide()
                self.green_label4.hide()
            elif self.north > 30:
                self.north_label.setStyleSheet('color: yellow')
                self.red_label4.hide()
                self.yellow_label4.show()
                self.green_label4.hide()
            else:
                self.north_label.setStyleSheet('color: green')
                self.red_label4.hide()
                self.yellow_label4.hide()
                self.green_label4.show()

            if self.east_status == "High":
                if self.cur != "east":
                    if (self.cur == "west"
                            and self.west > 10) and self.west_status != 'High':
                        self.east = 70
                        self.south = 100
                        self.west = 10
                        self.north = 40
                    elif (self.cur == "north"
                          and self.north > 10) and self.north_status != 'High':
                        self.east = 40
                        self.south = 70
                        self.west = 100
                        self.north = 10
                    elif (self.cur == "south"
                          and self.south > 10) and self.south_status != 'High':
                        self.east = 100
                        self.south = 10
                        self.west = 40
                        self.north = 70
                #self.east_status = "low"
            elif self.south_status == "High":
                if self.cur != "south":
                    if (self.cur == "west"
                            and self.west > 10) and self.west_status != 'High':
                        self.east = 70
                        self.south = 100
                        self.west = 10
                        self.north = 40
                    elif (self.cur == "north"
                          and self.north > 10) and self.north_status != 'High':
                        self.east = 40
                        self.south = 70
                        self.west = 100
                        self.north = 10
                    elif (self.cur == "east"
                          and self.east > 10) and self.east_status != 'High':
                        self.east = 10
                        self.south = 40
                        self.west = 70
                        self.north = 100
                #self.south_status = "low"
            elif self.west_status == "High":
                if self.cur != "west":
                    if (self.cur == "east"
                            and self.east > 10) and self.east_status != 'High':
                        self.east = 10
                        self.south = 40
                        self.west = 70
                        self.north = 100
                    elif (self.cur == "south"
                          and self.south > 10) and self.south_status != 'High':
                        self.east = 100
                        self.south = 10
                        self.west = 40
                        self.north = 70
                    elif (self.cur == "north"
                          and self.north > 10) and self.north_status != 'High':
                        self.east = 40
                        self.south = 70
                        self.west = 100
                        self.north = 10
                #self.west_status = "low"
            elif self.north_status == "High":
                if self.cur != "north":
                    if (self.cur == "east"
                            and self.east > 10) and self.east_status != 'High':
                        self.east = 10
                        self.south = 40
                        self.west = 70
                        self.north = 100
                    elif (self.cur == "south"
                          and self.south > 10) and self.south_status != 'High':
                        self.east = 100
                        self.south = 10
                        self.west = 40
                        self.north = 70
                    elif (self.cur == "west"
                          and self.west > 10) and self.west_status != 'High':
                        self.east = 70
                        self.south = 100
                        self.west = 10
                        self.north = 40
                #self.north_status = "low"

            elif self.east_status == "Mod":
                if self.cur != "east":
                    if (self.cur == "west"
                            and self.west > 15) and self.west_status == 'low':
                        self.east = 75
                        self.south = 105
                        self.west = 15
                        self.north = 45
                    elif (self.cur == "north"
                          and self.north > 15) and self.north_status == 'low':
                        self.east = 45
                        self.south = 75
                        self.west = 105
                        self.north = 15
                    elif (self.cur == "south"
                          and self.south > 15) and self.south_status == 'low':
                        self.east = 105
                        self.south = 15
                        self.west = 45
                        self.north = 75
                #self.east_status = "low"
            elif self.south_status == "Mod":
                if self.cur != "south":
                    if (self.cur == "west"
                            and self.west > 15) and self.west_status == 'low':
                        self.east = 75
                        self.south = 105
                        self.west = 15
                        self.north = 45
                    elif (self.cur == "north"
                          and self.north > 15) and self.north_status == 'low':
                        self.east = 45
                        self.south = 75
                        self.west = 105
                        self.north = 15
                    elif (self.cur == "east"
                          and self.east > 15) and self.east_status == 'low':
                        self.east = 15
                        self.south = 45
                        self.west = 75
                        self.north = 105
                #self.south_status = "low"
            elif self.west_status == "Mod":
                if self.cur != "west":
                    if (self.cur == "east"
                            and self.east > 15) and self.east_status == 'low':
                        self.east = 15
                        self.south = 45
                        self.west = 75
                        self.north = 105
                    elif (self.cur == "south"
                          and self.south > 15) and self.south_status == 'low':
                        self.east = 105
                        self.south = 15
                        self.west = 45
                        self.north = 75
                    elif (self.cur == "north"
                          and self.north > 15) and self.north_status == 'low':
                        self.east = 45
                        self.south = 75
                        self.west = 105
                        self.north = 15
                #self.west_status = "low"
            elif self.north_status == "Mod":
                if self.cur != "north":
                    if (self.cur == "east"
                            and self.east > 15) and self.east_status == 'low':
                        self.east = 15
                        self.south = 45
                        self.west = 75
                        self.north = 105
                    elif (self.cur == "south"
                          and self.south > 15) and self.south_status == 'low':
                        self.east = 105
                        self.south = 15
                        self.west = 45
                        self.north = 75
                    elif (self.cur == "west"
                          and self.west > 15) and self.west_status == 'low':
                        self.east = 75
                        self.south = 105
                        self.west = 15
                        self.north = 45
                #self.north_status = "low"
            self.east_density.setText(self.east_status)
            self.south_density.setText(self.south_status)
            self.west_density.setText(self.west_status)
            self.north_density.setText(self.north_status)

            print(self.east, self.south, self.west, self.north)

            print(self.east_status, self.south_status, self.west_status,
                  self.north_status)

    def print_images(self):

        while True:
            self.east_road_pixmap = QPixmap('./Test/images/east.png')
            if not self.east_road_pixmap.isNull():
                self.east_road_pixmap = self.east_road_pixmap.scaled(150, 150)
                self.east_road.setPixmap(self.east_road_pixmap)
                self.east_road.resize(150, 150)
                self.east_road.move(630, 425)

            self.east_road_bbox_pixmap = QPixmap('./Test/images/east_bbox.png')
            if not self.east_road_bbox_pixmap.isNull():
                self.east_road_bbox_pixmap = self.east_road_bbox_pixmap.scaled(
                    150, 150)
                self.east_road_bbox.setPixmap(self.east_road_bbox_pixmap)
                self.east_road_bbox.resize(150, 150)
                self.east_road_bbox.move(840, 425)

            self.south_road_pixmap = QPixmap('./Test/images/south.png')
            if not self.south_road_pixmap.isNull():
                self.south_road_pixmap = self.south_road_pixmap.scaled(
                    150, 150)
                self.south_road.setPixmap(self.south_road_pixmap)
                self.south_road.resize(150, 150)
                self.south_road.move(425, 630)

            self.south_road_bbox_pixmap = QPixmap(
                './Test/images/south_bbox.png')
            if not self.south_road_bbox_pixmap.isNull():
                self.south_road_bbox_pixmap = self.south_road_bbox_pixmap.scaled(
                    150, 150)
                self.south_road_bbox.setPixmap(self.south_road_bbox_pixmap)
                self.south_road_bbox.move(425, 840)

            self.west_road_pixmap = QPixmap('./Test/images/west.png')
            if not self.west_road_pixmap.isNull():
                self.west_road_pixmap = self.west_road_pixmap.scaled(150, 150)
                self.west_road.setPixmap(self.west_road_pixmap)
                self.west_road.move(220, 425)

            self.west_road_bbox_pixmap = QPixmap('./Test/images/west_bbox.png')
            if not self.west_road_bbox_pixmap.isNull():
                self.west_road_bbox_pixmap = self.west_road_bbox_pixmap.scaled(
                    150, 150)
                self.west_road_bbox.setPixmap(self.west_road_bbox_pixmap)
                self.west_road_bbox.move(10, 425)

            self.north_road_pixmap = QPixmap('./Test/images/north.png')
            if not self.north_road_pixmap.isNull():
                self.north_road_pixmap = self.north_road_pixmap.scaled(
                    150, 150)
                self.north_road.setPixmap(self.north_road_pixmap)
                self.north_road.resize(150, 150)
                self.north_road.move(425, 220)

            self.north_road_bbox_pixmap = QPixmap(
                './Test/images/north_bbox.png')
            if not self.north_road_bbox_pixmap.isNull():
                self.north_road_bbox_pixmap = self.north_road_bbox_pixmap.scaled(
                    150, 150)
                self.north_road_bbox.setPixmap(self.north_road_bbox_pixmap)
                self.north_road_bbox.resize(150, 150)
                self.north_road_bbox.move(425, 10)

            time.sleep(0.3)
Beispiel #32
0
class MandelbrotWidget(QWidget):
    def __init__(self, parent=None):
        super(MandelbrotWidget, self).__init__(parent)

        self.thread = RenderThread()
        self.pixmap = QPixmap()
        self.pixmapOffset = QPoint()
        self.lastDragPos = QPoint()

        self.centerX = DefaultCenterX
        self.centerY = DefaultCenterY
        self.pixmapScale = DefaultScale
        self.curScale = DefaultScale

        self.thread.renderedImage.connect(self.updatePixmap)

        self.setWindowTitle("Mandelbrot")
        self.setCursor(Qt.CrossCursor)
        self.resize(550, 400)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(self.rect(), Qt.black)

        if self.pixmap.isNull():
            painter.setPen(Qt.white)
            painter.drawText(self.rect(), Qt.AlignCenter,
                    "Rendering initial image, please wait...")
            return

        if self.curScale == self.pixmapScale:
            painter.drawPixmap(self.pixmapOffset, self.pixmap)
        else:
            scaleFactor = self.pixmapScale / self.curScale
            newWidth = int(self.pixmap.width() * scaleFactor)
            newHeight = int(self.pixmap.height() * scaleFactor)
            newX = self.pixmapOffset.x() + (self.pixmap.width() - newWidth) / 2
            newY = self.pixmapOffset.y() + (self.pixmap.height() - newHeight) / 2

            painter.save()
            painter.translate(newX, newY)
            painter.scale(scaleFactor, scaleFactor)
            exposed, _ = painter.matrix().inverted()
            exposed = exposed.mapRect(self.rect()).adjusted(-1, -1, 1, 1)
            painter.drawPixmap(exposed, self.pixmap, exposed)
            painter.restore()

        text = "Use mouse wheel or the '+' and '-' keys to zoom. Press and " \
                "hold left mouse button to scroll."
        metrics = painter.fontMetrics()
        textWidth = metrics.width(text)

        painter.setPen(Qt.NoPen)
        painter.setBrush(QColor(0, 0, 0, 127))
        painter.drawRect((self.width() - textWidth) / 2 - 5, 0, textWidth + 10,
                metrics.lineSpacing() + 5)
        painter.setPen(Qt.white)
        painter.drawText((self.width() - textWidth) / 2,
                metrics.leading() + metrics.ascent(), text)

    def resizeEvent(self, event):
        self.thread.render(self.centerX, self.centerY, self.curScale,
                self.size())

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Plus:
            self.zoom(ZoomInFactor)
        elif event.key() == Qt.Key_Minus:
            self.zoom(ZoomOutFactor)
        elif event.key() == Qt.Key_Left:
            self.scroll(-ScrollStep, 0)
        elif event.key() == Qt.Key_Right:
            self.scroll(+ScrollStep, 0)
        elif event.key() == Qt.Key_Down:
            self.scroll(0, -ScrollStep)
        elif event.key() == Qt.Key_Up:
            self.scroll(0, +ScrollStep)
        else:
            super(MandelbrotWidget, self).keyPressEvent(event)

    def wheelEvent(self, event):
        numDegrees = event.angleDelta().y() / 8
        numSteps = numDegrees / 15.0
        self.zoom(pow(ZoomInFactor, numSteps))

    def mousePressEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.lastDragPos = QPoint(event.pos())

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.pixmapOffset += event.pos() - self.lastDragPos
            self.lastDragPos = QPoint(event.pos())
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.pixmapOffset += event.pos() - self.lastDragPos
            self.lastDragPos = QPoint()

            deltaX = (self.width() - self.pixmap.width()) / 2 - self.pixmapOffset.x()
            deltaY = (self.height() - self.pixmap.height()) / 2 - self.pixmapOffset.y()
            self.scroll(deltaX, deltaY)

    def updatePixmap(self, image, scaleFactor):
        if not self.lastDragPos.isNull():
            return

        self.pixmap = QPixmap.fromImage(image)
        self.pixmapOffset = QPoint()
        self.lastDragPosition = QPoint()
        self.pixmapScale = scaleFactor
        self.update()

    def zoom(self, zoomFactor):
        self.curScale *= zoomFactor
        self.update()
        self.thread.render(self.centerX, self.centerY, self.curScale,
                self.size())

    def scroll(self, deltaX, deltaY):
        self.centerX += deltaX * self.curScale
        self.centerY += deltaY * self.curScale
        self.update()
        self.thread.render(self.centerX, self.centerY, self.curScale,
                self.size())
Beispiel #33
0
class MandelbrotWidget(QWidget):
    def __init__(self, parent=None):
        super(MandelbrotWidget, self).__init__(parent)

        self.thread = RenderThread()
        self.pixmap = QPixmap()
        self.pixmapOffset = QPoint()
        self.lastDragPos = QPoint()

        self.centerX = DefaultCenterX
        self.centerY = DefaultCenterY
        self.pixmapScale = DefaultScale
        self.curScale = DefaultScale

        self.thread.renderedImage.connect(self.updatePixmap)

        self.setWindowTitle("Mandelbrot")
        self.setCursor(Qt.CrossCursor)
        self.resize(550, 400)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(self.rect(), Qt.black)

        if self.pixmap.isNull():
            painter.setPen(Qt.white)
            painter.drawText(self.rect(), Qt.AlignCenter,
                             "Rendering initial image, please wait...")
            return

        if self.curScale == self.pixmapScale:
            painter.drawPixmap(self.pixmapOffset, self.pixmap)
        else:
            scaleFactor = self.pixmapScale / self.curScale
            newWidth = int(self.pixmap.width() * scaleFactor)
            newHeight = int(self.pixmap.height() * scaleFactor)
            newX = self.pixmapOffset.x() + (self.pixmap.width() - newWidth) / 2
            newY = self.pixmapOffset.y() + (self.pixmap.height() -
                                            newHeight) / 2

            painter.save()
            painter.translate(newX, newY)
            painter.scale(scaleFactor, scaleFactor)
            exposed, _ = painter.matrix().inverted()
            exposed = exposed.mapRect(self.rect()).adjusted(-1, -1, 1, 1)
            painter.drawPixmap(exposed, self.pixmap, exposed)
            painter.restore()

        text = "Use mouse wheel or the '+' and '-' keys to zoom. Press and " \
                "hold left mouse button to scroll."
        metrics = painter.fontMetrics()
        textWidth = metrics.width(text)

        painter.setPen(Qt.NoPen)
        painter.setBrush(QColor(0, 0, 0, 127))
        painter.drawRect((self.width() - textWidth) / 2 - 5, 0, textWidth + 10,
                         metrics.lineSpacing() + 5)
        painter.setPen(Qt.white)
        painter.drawText((self.width() - textWidth) / 2,
                         metrics.leading() + metrics.ascent(), text)

    def resizeEvent(self, event):
        self.thread.render(self.centerX, self.centerY, self.curScale,
                           self.size())

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Plus:
            self.zoom(ZoomInFactor)
        elif event.key() == Qt.Key_Minus:
            self.zoom(ZoomOutFactor)
        elif event.key() == Qt.Key_Left:
            self.scroll(-ScrollStep, 0)
        elif event.key() == Qt.Key_Right:
            self.scroll(+ScrollStep, 0)
        elif event.key() == Qt.Key_Down:
            self.scroll(0, -ScrollStep)
        elif event.key() == Qt.Key_Up:
            self.scroll(0, +ScrollStep)
        else:
            super(MandelbrotWidget, self).keyPressEvent(event)

    def wheelEvent(self, event):
        numDegrees = event.angleDelta().y() / 8
        numSteps = numDegrees / 15.0
        self.zoom(pow(ZoomInFactor, numSteps))

    def mousePressEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.lastDragPos = QPoint(event.pos())

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.pixmapOffset += event.pos() - self.lastDragPos
            self.lastDragPos = QPoint(event.pos())
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.pixmapOffset += event.pos() - self.lastDragPos
            self.lastDragPos = QPoint()

            deltaX = (self.width() -
                      self.pixmap.width()) / 2 - self.pixmapOffset.x()
            deltaY = (self.height() -
                      self.pixmap.height()) / 2 - self.pixmapOffset.y()
            self.scroll(deltaX, deltaY)

    def updatePixmap(self, image, scaleFactor):
        if not self.lastDragPos.isNull():
            return

        self.pixmap = QPixmap.fromImage(image)
        self.pixmapOffset = QPoint()
        self.lastDragPosition = QPoint()
        self.pixmapScale = scaleFactor
        self.update()

    def zoom(self, zoomFactor):
        self.curScale *= zoomFactor
        self.update()
        self.thread.render(self.centerX, self.centerY, self.curScale,
                           self.size())

    def scroll(self, deltaX, deltaY):
        self.centerX += deltaX * self.curScale
        self.centerY += deltaY * self.curScale
        self.update()
        self.thread.render(self.centerX, self.centerY, self.curScale,
                           self.size())
Beispiel #34
0
class eventedLabel(QLabel):
    def __init__(self, parent_dim):
        """
        This class inherits the QLabel class and handles events internally. It handles all the intra-image events.
        I keep an unmodified version of the original image in the background.
        :param parent_dim: Tuple. The dimensions of the parent window
        """
        super().__init__()
        self.mouse_held = False
        self.press_location = (None, None)

        self.scale_factor = (1, 1)
        self.parent_height = parent_dim[0]
        self.parent_width = parent_dim[1]

        self.existing_rects = []

    def mousePressEvent(self, event):
        super().mousePressEvent(event)
        self.mouse_held = True
        self.press_location = (event.pos().x(), event.pos().y())

    def mouseReleaseEvent(self, event):
        super().mouseReleaseEvent(event)

        self.appendRect(
            *self.press_location,
            event.pos().x() - self.press_location[0],
            event.pos().y() - self.press_location[1]
        )

        self.drawExistingRects()
        self.mouse_held = False

    def appendRect(self, x, y, w, h):
        """
        If the user drags upwards or leftwards, the w,h of the rectangle could be negaive.

        :return: Tuple. (x, y, w, h) corrected so that x,y always describe the upper=left corner.
        """
        if w < 0:
            x = x + w
            w = abs(w)
        if h < 0:
            y = y + h
            h = abs(h)

        self.existing_rects.append([x, y, w, h])
        return x, y, w, h

    def mouseMoveEvent(self, event):
        super().mouseMoveEvent(event)

        self.drawTempRect(
            *self.press_location,
            event.pos().x() - self.press_location[0],
            event.pos().y() - self.press_location[1],
            Qt.red
        )

    def drawRect(self, x, y, w, h, c):
        self.painter = QPainter(self.pixmap)
        pen = QPen(c, 3)
        self.painter.setPen(pen)
        self.painter.drawRect(x, y, w, h)
        self.painter.end()
        self.setScaledPixmap()

    def drawTempRect(self, x, y, w, h, c):
        """
        This function draw a rectangle and clears it right up again. It is needed
        so that we dont start painting with rectangles on the image.

        :param c: QT constant. Color.
        :return:
        """
        self.drawExistingRects()
        self.drawRect(x, y, w, h, c)
        self.pixmap = self.static_pixmap.copy()

    def drawExistingRects(self):
        self.setScaledPixmap()
        for rect in self.existing_rects:
            self.drawRect(*rect, Qt.blue)

    def setImage(self, path, annotations):
        """
        Sets an image within the label and handle its annotations.
        :param path: Str. Path to the image file
        :param annotations: List of Lists. Bounding Box annotations of head location.
        [[x1,y1,w1,h1],
        [x2,y2,w2,h2]]

        :return: True if image loaded correctly. False otherwise.
        """
        self.existing_rects = []
        self.scale_factor = (1, 1)
        self.path = path
        self.pixmap = QPixmap(
            str(
                path
            )
        )

        if self.pixmap.isNull():
            print(f'Cannot load image {str(path)}')
            return False

        self.setScaledPixmap()
        self.static_pixmap = self.pixmap.copy()

        if len(annotations) > 0:
            self.existing_rects = self.useAnnotations(annotations)
        self.drawExistingRects()

        return True

    def setScaledPixmap(self):
        if self.pixmap.height() > self.parent_height or self.pixmap.width() > self.parent_width:
            original_size = self.pixmap.height(), self.pixmap.width()
            self.pixmap = self.pixmap.scaled(self.parent_width, self.parent_height, Qt.KeepAspectRatio)

            self.scale_factor = (original_size[0] / self.pixmap.height(), original_size[1] / self.pixmap.width())

        self.setPixmap(self.pixmap)

    def labelToImageCoordinates(self, x, y, w, h):
        """
        Translate between label coordinates (possibly scaled to fit the screen) and image coordinates.
        :return: xywh in image coordinates
        """
        x *= self.scale_factor[0]
        y *= self.scale_factor[1]

        w *= self.scale_factor[0]
        h *= self.scale_factor[1]

        return x, y, w, h

    def imageToLabelCoordinates(self, x, y, w, h):
        """
        Translate between image coordinates and label coordinates (possibly scaled to fit the screen).
        :return: xywh in label coordinates
        """
        x /= self.scale_factor[0]
        y /= self.scale_factor[1]

        w /= self.scale_factor[0]
        h /= self.scale_factor[1]

        return x, y, w, h

    def getAnnotations(self):
        """
        Parse annotations to the activating class.
        :return: Annotaions in image coordinates.
        """
        return [list(map(round, self.labelToImageCoordinates(*coords))) for coords in self.existing_rects]

    def useAnnotations(self, annotations):
        """
        Parse annotations from file.
        :param annotations: List of lists.
        :return: List of lists.
        """
        return [self.imageToLabelCoordinates(*coords) for coords in annotations]

    def deleteAndUpdate(self):
        self.existing_rects = self.existing_rects[:-1]
        self.setImage(self.path, self.getAnnotations())
        self.drawExistingRects()
Beispiel #35
0
    def createUI(self):
        """
        Set up the window for the VLC viewer
        """
        self.widget = QWidget(self)
        self.setCentralWidget(self.widget)

        # In this widget, the video will be drawn
        if sys.platform == "darwin": # for MacOS
            from PyQt5.QtWidgets import QMacCocoaViewContainer
            self.videoframe = QMacCocoaViewContainer(0)
        else:
            self.videoframe = QFrame()
        self.palette = self.videoframe.palette()
        self.palette.setColor (QPalette.Window,
                               QColor(0,0,0))
        self.videoframe.setPalette(self.palette)
        self.videoframe.setAutoFillBackground(True)

        self.hbuttonbox = QHBoxLayout()
        self.playbutton = QPushButton("Run my program")
        self.hbuttonbox.addWidget(self.playbutton)
        self.playbutton.clicked.connect(partial(self.drone_vision.run_user_code, self.playbutton))

        self.landbutton = QPushButton("Land NOW")
        self.hbuttonbox.addWidget(self.landbutton)
        self.landbutton.clicked.connect(self.drone_vision.land)

        self.stopbutton = QPushButton("Quit")
        self.hbuttonbox.addWidget(self.stopbutton)
        self.stopbutton.clicked.connect(self.drone_vision.close_exit)

        self.vboxlayout = QVBoxLayout()
        self.vboxlayout.addWidget(self.videoframe)

        if (self.drone_vision.user_draw_window_fn is not None):
            self.userWindow = QLabel()
            fullPath = inspect.getfile(DroneVisionGUI)
            shortPathIndex = fullPath.rfind("/")
            if (shortPathIndex == -1):
                # handle Windows paths
                shortPathIndex = fullPath.rfind("\\")
            print(shortPathIndex)
            shortPath = fullPath[0:shortPathIndex]
            pixmap = QPixmap('%s/demo_user_image.png' % shortPath)
            print(pixmap)
            print(pixmap.isNull())
            self.userWindow.setPixmap(pixmap)
            self.vboxlayout.addWidget(self.userWindow)

        self.vboxlayout.addLayout(self.hbuttonbox)

        self.widget.setLayout(self.vboxlayout)

        # the media player has to be 'connected' to the QFrame
        # (otherwise a video would be displayed in it's own window)
        # this is platform specific!
        # you have to give the id of the QFrame (or similar object) to
        # vlc, different platforms have different functions for this
        if sys.platform.startswith('linux'): # for Linux using the X Server
            self.mediaplayer.set_xwindow(self.videoframe.winId())
        elif sys.platform == "win32": # for Windows
            self.mediaplayer.set_hwnd(self.videoframe.winId())
        elif sys.platform == "darwin": # for MacOS
            self.mediaplayer.set_nsobject(int(self.videoframe.winId()))
Beispiel #36
0
class SnapWidget(QWidget, Ui_SnapWidget):
    """
    Class implementing the snapshot widget.
    """
    ModeFullscreen = 0
    ModeScreen = 1
    ModeRectangle = 2
    ModeFreehand = 3
    ModeEllipse = 4

    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        """
        super(SnapWidget, self).__init__(parent)
        self.setupUi(self)

        self.saveButton.setIcon(UI.PixmapCache.getIcon("fileSaveAs.png"))
        self.takeButton.setIcon(UI.PixmapCache.getIcon("cameraPhoto.png"))
        self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy.png"))
        self.copyPreviewButton.setIcon(UI.PixmapCache.getIcon("editCopy.png"))
        self.setWindowIcon(UI.PixmapCache.getIcon("ericSnap.png"))

        self.modeCombo.addItem(self.tr("Fullscreen"),
                               SnapWidget.ModeFullscreen)
        self.modeCombo.addItem(self.tr("Rectangular Selection"),
                               SnapWidget.ModeRectangle)
        self.modeCombo.addItem(self.tr("Ellipical Selection"),
                               SnapWidget.ModeEllipse)
        self.modeCombo.addItem(self.tr("Freehand Selection"),
                               SnapWidget.ModeFreehand)
        if QApplication.desktop().screenCount() > 1:
            self.modeCombo.addItem(self.tr("Current Screen"),
                                   SnapWidget.ModeScreen)
        self.__mode = int(Preferences.Prefs.settings.value("Snapshot/Mode", 0))
        index = self.modeCombo.findData(self.__mode)
        if index == -1:
            index = 0
        self.modeCombo.setCurrentIndex(index)

        self.__delay = int(
            Preferences.Prefs.settings.value("Snapshot/Delay", 0))
        self.delaySpin.setValue(self.__delay)

        if PYQT_VERSION_STR >= "5.0.0":
            from PyQt5.QtCore import QStandardPaths
            picturesLocation = QStandardPaths.writableLocation(
                QStandardPaths.PicturesLocation)
        else:
            from PyQt5.QtGui import QDesktopServices
            picturesLocation = QDesktopServices.storageLocation(
                QDesktopServices.PicturesLocation)
        self.__filename = Preferences.Prefs.settings.value(
            "Snapshot/Filename",
            os.path.join(picturesLocation,
                         self.tr("snapshot") + "1.png"))

        self.__grabber = None
        self.__snapshot = QPixmap()
        self.__savedPosition = QPoint()
        self.__modified = False
        self.__locale = QLocale()

        self.__grabberWidget = QWidget(None, Qt.X11BypassWindowManagerHint)
        self.__grabberWidget.move(-10000, -10000)
        self.__grabberWidget.installEventFilter(self)

        self.__initFileFilters()

        self.__initShortcuts()

        self.preview.startDrag.connect(self.__dragSnapshot)

        from .SnapshotTimer import SnapshotTimer
        self.__grabTimer = SnapshotTimer()
        self.__grabTimer.timeout.connect(self.__grabTimerTimeout)
        self.__updateTimer = QTimer()
        self.__updateTimer.setSingleShot(True)
        self.__updateTimer.timeout.connect(self.__updatePreview)

        self.__updateCaption()
        self.takeButton.setFocus()

    def __initFileFilters(self):
        """
        Private method to define the supported image file filters.
        """
        filters = {
            'bmp': self.tr("Windows Bitmap File (*.bmp)"),
            'gif': self.tr("Graphic Interchange Format File (*.gif)"),
            'ico': self.tr("Windows Icon File (*.ico)"),
            'jpg': self.tr("JPEG File (*.jpg)"),
            'mng': self.tr("Multiple-Image Network Graphics File (*.mng)"),
            'pbm': self.tr("Portable Bitmap File (*.pbm)"),
            'pcx': self.tr("Paintbrush Bitmap File (*.pcx)"),
            'pgm': self.tr("Portable Graymap File (*.pgm)"),
            'png': self.tr("Portable Network Graphics File (*.png)"),
            'ppm': self.tr("Portable Pixmap File (*.ppm)"),
            'sgi': self.tr("Silicon Graphics Image File (*.sgi)"),
            'svg': self.tr("Scalable Vector Graphics File (*.svg)"),
            'tga': self.tr("Targa Graphic File (*.tga)"),
            'tif': self.tr("TIFF File (*.tif)"),
            'xbm': self.tr("X11 Bitmap File (*.xbm)"),
            'xpm': self.tr("X11 Pixmap File (*.xpm)"),
        }

        outputFormats = []
        writeFormats = QImageWriter.supportedImageFormats()
        for writeFormat in writeFormats:
            try:
                outputFormats.append(filters[bytes(writeFormat).decode()])
            except KeyError:
                pass
        outputFormats.sort()
        self.__outputFilter = ';;'.join(outputFormats)

        self.__defaultFilter = filters['png']

    def __initShortcuts(self):
        """
        Private method to initialize the keyboard shortcuts.
        """
        self.__quitShortcut = QShortcut(QKeySequence(QKeySequence.Quit), self,
                                        self.close)

        self.__copyShortcut = QShortcut(QKeySequence(QKeySequence.Copy), self,
                                        self.copyButton.animateClick)

        self.__quickSaveShortcut = QShortcut(QKeySequence(Qt.Key_Q), self,
                                             self.__quickSave)

        self.__save1Shortcut = QShortcut(QKeySequence(QKeySequence.Save), self,
                                         self.saveButton.animateClick)
        self.__save2Shortcut = QShortcut(QKeySequence(Qt.Key_S), self,
                                         self.saveButton.animateClick)

        self.__grab1Shortcut = QShortcut(QKeySequence(QKeySequence.New), self,
                                         self.takeButton.animateClick)
        self.__grab2Shortcut = QShortcut(QKeySequence(Qt.Key_N), self,
                                         self.takeButton.animateClick)
        self.__grab3Shortcut = QShortcut(QKeySequence(Qt.Key_Space), self,
                                         self.takeButton.animateClick)

    def __quickSave(self):
        """
        Private slot to save the snapshot bypassing the file selection dialog.
        """
        if not self.__snapshot.isNull():
            while os.path.exists(self.__filename):
                self.__autoIncFilename()

            if self.__saveImage(self.__filename):
                self.__modified = False
                self.__autoIncFilename()
                self.__updateCaption()

    @pyqtSlot()
    def on_saveButton_clicked(self):
        """
        Private slot to save the snapshot.
        """
        if not self.__snapshot.isNull():
            while os.path.exists(self.__filename):
                self.__autoIncFilename()

            fileName, selectedFilter = E5FileDialog.getSaveFileNameAndFilter(
                self, self.tr("Save Snapshot"), self.__filename,
                self.__outputFilter, self.__defaultFilter,
                E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite))
            if not fileName:
                return

            ext = QFileInfo(fileName).suffix()
            if not ext:
                ex = selectedFilter.split("(*")[1].split(")")[0]
                if ex:
                    fileName += ex

            if self.__saveImage(fileName):
                self.__modified = False
                self.__filename = fileName
                self.__autoIncFilename()
                self.__updateCaption()

    def __saveImage(self, fileName):
        """
        Private method to save the snapshot.
        
        @param fileName name of the file to save to (string)
        @return flag indicating success (boolean)
        """
        if QFileInfo(fileName).exists():
            res = E5MessageBox.yesNo(
                self,
                self.tr("Save Snapshot"),
                self.tr("<p>The file <b>{0}</b> already exists."
                        " Overwrite it?</p>").format(fileName),
                icon=E5MessageBox.Warning)
            if not res:
                return False

        file = QFile(fileName)
        if not file.open(QFile.WriteOnly):
            E5MessageBox.warning(
                self, self.tr("Save Snapshot"),
                self.tr("Cannot write file '{0}:\n{1}.").format(
                    fileName, file.errorString()))
            return False

        ok = self.__snapshot.save(file)
        file.close()

        if not ok:
            E5MessageBox.warning(
                self, self.tr("Save Snapshot"),
                self.tr("Cannot write file '{0}:\n{1}.").format(
                    fileName, file.errorString()))

        return ok

    def __autoIncFilename(self):
        """
        Private method to auto-increment the file name.
        """
        # Extract the file name
        name = os.path.basename(self.__filename)

        # If the name contains a number, then increment it.
        numSearch = QRegExp("(^|[^\\d])(\\d+)")
        # We want to match as far left as possible, and when the number is
        # at the start of the name.

        # Does it have a number?
        start = numSearch.lastIndexIn(name)
        if start != -1:
            # It has a number, increment it.
            start = numSearch.pos(2)  # Only the second group is of interest.
            numAsStr = numSearch.capturedTexts()[2]
            number = "{0:0{width}d}".format(int(numAsStr) + 1,
                                            width=len(numAsStr))
            name = name[:start] + number + name[start + len(numAsStr):]
        else:
            # no number
            start = name.rfind('.')
            if start != -1:
                # has a '.' somewhere, e.g. it has an extension
                name = name[:start] + '1' + name[start:]
            else:
                # no extension, just tack it on to the end
                name += '1'

        self.__filename = os.path.join(os.path.dirname(self.__filename), name)
        self.__updateCaption()

    @pyqtSlot()
    def on_takeButton_clicked(self):
        """
        Private slot to take a snapshot.
        """
        self.__mode = self.modeCombo.itemData(self.modeCombo.currentIndex())
        self.__delay = self.delaySpin.value()

        self.__savedPosition = self.pos()
        self.hide()

        if self.__delay:
            self.__grabTimer.start(self.__delay)
        else:
            QTimer.singleShot(200, self.__startUndelayedGrab)

    def __grabTimerTimeout(self):
        """
        Private slot to perform a delayed grab operation.
        """
        if self.__mode == SnapWidget.ModeRectangle:
            self.__grabRectangle()
        elif self.__mode == SnapWidget.ModeEllipse:
            self.__grabEllipse()
        elif self.__mode == SnapWidget.ModeFreehand:
            self.__grabFreehand()
        else:
            self.__performGrab()

    def __startUndelayedGrab(self):
        """
        Private slot to perform an undelayed grab operation.
        """
        if self.__mode == SnapWidget.ModeRectangle:
            self.__grabRectangle()
        elif self.__mode == SnapWidget.ModeEllipse:
            self.__grabEllipse()
        elif self.__mode == SnapWidget.ModeFreehand:
            self.__grabFreehand()
        else:
            if Globals.isMacPlatform():
                self.__performGrab()
            else:
                self.__grabberWidget.show()
                self.__grabberWidget.grabMouse(Qt.CrossCursor)

    def __grabRectangle(self):
        """
        Private method to grab a rectangular screen region.
        """
        from .SnapshotRegionGrabber import SnapshotRegionGrabber
        self.__grabber = SnapshotRegionGrabber(
            mode=SnapshotRegionGrabber.Rectangle)
        self.__grabber.grabbed.connect(self.__captured)

    def __grabEllipse(self):
        """
        Private method to grab an elliptical screen region.
        """
        from .SnapshotRegionGrabber import SnapshotRegionGrabber
        self.__grabber = SnapshotRegionGrabber(
            mode=SnapshotRegionGrabber.Ellipse)
        self.__grabber.grabbed.connect(self.__captured)

    def __grabFreehand(self):
        """
        Private method to grab a non-rectangular screen region.
        """
        from .SnapshotFreehandGrabber import SnapshotFreehandGrabber
        self.__grabber = SnapshotFreehandGrabber()
        self.__grabber.grabbed.connect(self.__captured)

    def __performGrab(self):
        """
        Private method to perform a screen grab other than a selected region.
        """
        self.__grabberWidget.releaseMouse()
        self.__grabberWidget.hide()
        self.__grabTimer.stop()

        if self.__mode == SnapWidget.ModeFullscreen:
            desktop = QApplication.desktop()
            if qVersion() >= "5.0.0":
                self.__snapshot = QApplication.screens()[0].grabWindow(
                    desktop.winId(), desktop.x(), desktop.y(), desktop.width(),
                    desktop.height())
            else:
                self.__snapshot = QPixmap.grabWindow(desktop.winId(),
                                                     desktop.x(), desktop.y(),
                                                     desktop.width(),
                                                     desktop.height())
        elif self.__mode == SnapWidget.ModeScreen:
            desktop = QApplication.desktop()
            screenId = desktop.screenNumber(QCursor.pos())
            geom = desktop.screenGeometry(screenId)
            x = geom.x()
            y = geom.y()
            if qVersion() >= "5.0.0":
                self.__snapshot = QApplication.screens()[0].grabWindow(
                    desktop.winId(), x, y, geom.width(), geom.height())
            else:
                self.__snapshot = QPixmap.grabWindow(desktop.winId(), x, y,
                                                     geom.width(),
                                                     geom.height())
        else:
            self.__snapshot = QPixmap()

        self.__redisplay()
        self.__modified = True
        self.__updateCaption()

    def __redisplay(self):
        """
        Private method to redisplay the window.
        """
        self.__updatePreview()
        QApplication.restoreOverrideCursor()
        if not self.__savedPosition.isNull():
            self.move(self.__savedPosition)
        self.show()
        self.raise_()

        self.saveButton.setEnabled(not self.__snapshot.isNull())
        self.copyButton.setEnabled(not self.__snapshot.isNull())
        self.copyPreviewButton.setEnabled(not self.__snapshot.isNull())

    @pyqtSlot()
    def on_copyButton_clicked(self):
        """
        Private slot to copy the snapshot to the clipboard.
        """
        if not self.__snapshot.isNull():
            QApplication.clipboard().setPixmap(QPixmap(self.__snapshot))

    @pyqtSlot()
    def on_copyPreviewButton_clicked(self):
        """
        Private slot to copy the snapshot preview to the clipboard.
        """
        QApplication.clipboard().setPixmap(self.preview.pixmap())

    def __captured(self, pixmap):
        """
        Private slot to show a preview of the snapshot.
        
        @param pixmap pixmap of the snapshot (QPixmap)
        """
        self.__grabber.close()
        self.__snapshot = QPixmap(pixmap)

        self.__grabber.grabbed.disconnect(self.__captured)
        self.__grabber = None

        self.__redisplay()
        self.__modified = True
        self.__updateCaption()

    def __updatePreview(self):
        """
        Private slot to update the preview picture.
        """
        self.preview.setToolTip(
            self.tr("Preview of the snapshot image ({0} x {1})").format(
                self.__locale.toString(self.__snapshot.width()),
                self.__locale.toString(self.__snapshot.height())))
        self.preview.setPreview(self.__snapshot)
        self.preview.adjustSize()

    def resizeEvent(self, evt):
        """
        Protected method handling a resizing of the window.
        
        @param evt resize event (QResizeEvent)
        """
        self.__updateTimer.start(200)

    def __dragSnapshot(self):
        """
        Private slot handling the dragging of the preview picture.
        """
        drag = QDrag(self)
        mimeData = QMimeData()
        mimeData.setImageData(self.__snapshot)
        drag.setMimeData(mimeData)
        drag.setPixmap(self.preview.pixmap())
        drag.exec_(Qt.CopyAction)

    def eventFilter(self, obj, evt):
        """
        Public method to handle event for other objects.
        
        @param obj reference to the object (QObject)
        @param evt reference to the event (QEvent)
        @return flag indicating that the event should be filtered out (boolean)
        """
        if obj == self.__grabberWidget and \
                evt.type() == QEvent.MouseButtonPress:
            if QWidget.mouseGrabber() != self.__grabberWidget:
                return False
            if evt.button() == Qt.LeftButton:
                self.__performGrab()

        return False

    def closeEvent(self, evt):
        """
        Protected method handling the close event.
        
        @param evt close event (QCloseEvent)
        """
        if self.__modified:
            res = E5MessageBox.question(
                self, self.tr("Pymakr Snapshot"),
                self.tr("""The application contains an unsaved snapshot."""),
                E5MessageBox.StandardButtons(E5MessageBox.Abort
                                             | E5MessageBox.Discard
                                             | E5MessageBox.Save))
            if res == E5MessageBox.Abort:
                evt.ignore()
                return
            elif res == E5MessageBox.Save:
                self.on_saveButton_clicked()

        Preferences.Prefs.settings.setValue("Snapshot/Delay",
                                            self.delaySpin.value())
        Preferences.Prefs.settings.setValue(
            "Snapshot/Mode",
            self.modeCombo.itemData(self.modeCombo.currentIndex()))
        Preferences.Prefs.settings.setValue("Snapshot/Filename",
                                            self.__filename)
        Preferences.Prefs.settings.sync()

    def __updateCaption(self):
        """
        Private method to update the window caption.
        """
        self.setWindowTitle("{0}[*] - {1}".format(
            os.path.basename(self.__filename), self.tr("Pymakr Snapshot")))
        self.setWindowModified(self.__modified)
        self.pathNameEdit.setText(os.path.dirname(self.__filename))
Beispiel #37
0
class ImageLayer(Layer):
    ##
    # Constructor.
    ##
    def __init__(self, name, x, y, width, height):
        super().__init__(Layer.ImageLayerType, name, x, y, width, height)

        self.mImage = QPixmap()
        self.mTransparentColor = QColor()
        self.mImageSource = QString()

    ##
    # Destructor.
    ##
    def __del__(self):
        pass

    def usedTilesets(self):
        return QSet()

    def referencesTileset(self, arg1):
        return False

    def replaceReferencesToTileset(self, arg1, arg2):
        pass

    def canMergeWith(self, arg1):
        return False

    def mergedWith(self, arg1):
        return None

    ##
    # Returns the transparent color, or an invalid color if no transparent
    # color is used.
    ##
    def transparentColor(self):
        return QColor(self.mTransparentColor)

    ##
    # Sets the transparent color. Pixels with this color will be masked out
    # when loadFromImage() is called.
    ##
    def setTransparentColor(self, c):
        self.mTransparentColor = c

    ##
    #  Sets image source file name
    ##
    def setSource(self, source):
        self.mImageSource = source

    ##
    # Returns the file name of the layer image.
    ##
    def imageSource(self):
        return self.mImageSource

    ##
    # Returns the image of this layer.
    ##
    def image(self):
        return QPixmap(self.mImage)

    ##
    # Sets the image of this layer.
    ##
    def setImage(self, image):
        self.mImage = image

    ##
    # Resets layer image.
    ##
    def resetImage(self):
        self.mImage = QPixmap()
        self.mImageSource = ''

    ##
    # Load this layer from the given \a image. This will replace the existing
    # image. The \a fileName becomes the new imageSource, regardless of
    # whether the image could be loaded.
    #
    # @param image    the image to load the layer from
    # @param fileName the file name of the image, which will be remembered
    #                 as the image source of this layer.
    # @return <code>true</code> if loading was successful, otherwise
    #         returns <code>false</code>
    ##
    def loadFromImage(self, image, fileName):
        self.mImageSource = fileName
        if (image.isNull()):
            self.mImage = QPixmap()
            return False

        self.mImage = QPixmap.fromImage(image)
        if (self.mTransparentColor.isValid()):
            mask = image.createMaskFromColor(self.mTransparentColor.rgb())
            self.mImage.setMask(QBitmap.fromImage(mask))

        return True

    ##
    # Returns True if no image source has been set.
    ##
    def isEmpty(self):
        return self.mImage.isNull()

    def clone(self):
        return self.initializeClone(ImageLayer(self.mName, self.mX, self.mY, self.mWidth, self.mHeight))

    def initializeClone(self, clone):
        super().initializeClone(clone)
        clone.mImageSource = self.mImageSource
        clone.mTransparentColor = self.mTransparentColor
        clone.mImage = self.mImage
        return clone