示例#1
0
class GOBoard(QWidget):

    on_click = pyqtSignal(str, int)

    def __init__(self):
        super().__init__()
        self.__background_pixmap = QPixmap(get_asset_path("board.png"))
        self.__background_label = QLabel(self)
        self.__background_label.setPixmap(self.__background_pixmap)
        self.setMinimumSize(self.__background_pixmap.size())
        self.__pieces = {}

    def pixmap_height(self):
        return self.__background_pixmap.height()

    def add_square(self, letter, y, color):
        y -= 1
        letters = list(string.ascii_uppercase)
        letters.remove("I")
        a = letters.index(letter)
        if (letter, y + 1) in self.__pieces:
            print("ERROR: Space {},{} already occupied".format(letter, y + 1))
        else:
            piece = GOSquare(27 + a * 23, self.__background_pixmap.height() - (20 + y * 23), color, self)
            self.__pieces[(letter, y + 1)] = piece
            piece.show()

    def add_piece(self, letter, y, text, color):
        y -= 1
        letters = list(string.ascii_uppercase)
        letters.remove("I")
        a = letters.index(letter)
        if (letter, y + 1) in self.__pieces:
            print("ERROR: Space {},{} already occupied".format(letter, y + 1))
        else:
            piece = GOPiece(23 + a * 23, self.__background_pixmap.height() - (24 + y * 23), text, color, self)
            self.__pieces[(letter, y + 1)] = piece
            piece.show()

    def remove_piece(self, letter, y):
        if (letter, y) in self.__pieces:
            piece = self.__pieces[(letter, y)]
            piece.hide()
            piece.deleteLater()
            del self.__pieces[(letter, y)]
        else:
            print("ERROR: There is no piece at {},{}".format(letter, y))

    def mousePressEvent(self, e):
        x = (e.x() - 27) // 23
        y = (self.__background_pixmap.height() - 20 - e.y()) // 23
        y += 2
        letters = list(string.ascii_uppercase)
        letters.remove("I")
        letra = letters[x]
        if y <= 19 and letra <= "T":
            self.on_click.emit(letra, y)
示例#2
0
文件: text.py 项目: 089git/calibre
 def __init__(self, data, encoding, x0, y0, x1, y1, xsize, ysize):
     p = QPixmap()
     p.loadFromData(data, encoding, Qt.AutoColor)
     w, h = p.width(), p.height()
     p = p.copy(x0, y0, min(w, x1-x0), min(h, y1-y0))
     if p.width() != xsize or p.height() != ysize:
         p = p.scaled(xsize, ysize, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
     QGraphicsPixmapItem.__init__(self, p)
     self.height, self.width = ysize, xsize
     self.setTransformationMode(Qt.SmoothTransformation)
     self.setShapeMode(QGraphicsPixmapItem.BoundingRectShape)
示例#3
0
class Human(Entity):

    BRAVE = "brave"
    COWARD = "coward"
    CARELESS = "careless"
    CAUTIOUS = "cautious"
    RATIONAL = "rational"
    STUPID = "stupid"

    WEAPON_LONG = "long"
    WEAPON_SHORT = "short"
    NO_WEAPON = "noweapon"

    def __init__(self, personality, weapon, cord_x=0, cord_y=0, parent=None):
        super().__init__("human_{}_{}.png".format(personality, weapon), parent=parent)
        self.personality = personality
        self.weapon = weapon
        self.cord_x = cord_x
        self.cord_y = cord_y
        self.setFixedSize(73 * _SCALE, 73 * _SCALE)

    def change_weapon(self, weapon):
        self.weapon = weapon
        self._base_image = "human_{}_{}.png".format(self.personality, self.weapon)
        self.updatePixmap()

    def updatePixmap(self):
        path = _PATH + os.sep + "assets" + os.sep + self._base_image
        self.__pixmap = QPixmap(path)
        self.__pixmap = self.__pixmap.scaled(self.__pixmap.width() * _SCALE, self.__pixmap.height() * _SCALE)
        self.__pixmap = self.__pixmap.transformed(QTransform().rotate(self.angle))
        self._base_label.setPixmap(self.__pixmap)
    def addTestImage(self, color_image):
        self.ocr_areas = OCRAreasFinder(color_image, self.settings["contrast"])
        self.market_width = self.ocr_areas.market_width
        self.valid_market = self.ocr_areas.valid
        img = QPixmap(self.hiddentext)
        width = img.width()
        height = img.height()
        aspect_ratio = float(width)/height
        if aspect_ratio > 1.78:
            new_w = int(1.77778*height)
            rect = QRect((width-new_w)/2, 0, new_w, height)
            img = img.copy(rect)
            
        if self.valid_market:
            points = self.ocr_areas.market_table
            self.market_offset = (points[0][0], points[0][1])
            station = self.ocr_areas.station_name
            self.station_offset = (station[0][0], station[0][1])
            rect = QRect(0, 0, points[1][0] + 20, points[1][1] + 20)
            cut = img.copy(rect)
            return cut
        else:
            self.market_offset = (0, 0)
            self.station_offset = (0, 0)

            
        
        return img
示例#5
0
    def select_icon(self, item):
        icon = str(item.text())
        p = os.path.join(self.selected_dir, self.selected_theme, self.selected_sub_dir, icon)

        pixmap = QPixmap(p)
        self.image.setPixmap(pixmap)
        self.image.resize(pixmap.width(), pixmap.height())
示例#6
0
 def drawStationName(self):
     """Draw station name snippet to station_name_img"""
     res = self.current_result
     name = res.station.name
     #self.station_name.setText('')
     #self.station_name.clear()
     #self.station_name.addItems(name.optional_values)
     if not self.file_list.currentItem().station is None:
             self.station_name.setText(self.file_list.currentItem().station)
     else:
         self.station_name.setText(name.value)
     #font = QFont("Consolas", 11)
     #self.station_name.lineEdit().setFont(font)
     #self.setConfidenceColor(self.station_name, name)
     img = self.cutImage(res.contrast_station_img, name)
     if self.dark_theme: 
         img = 255 - img
     processedimage = array2qimage(img)
     pix = QPixmap()
     pix.convertFromImage(processedimage)
     if self.station_name_img.height() < pix.height():
         pix = pix.scaled(self.station_name_img.size(),
                          Qt.KeepAspectRatio,
                          Qt.SmoothTransformation)
     scene = QGraphicsScene()
     scene.addPixmap(pix)
     
     self.station_name_img.setScene(scene)
     self.station_name_img.show()
    def addTestImage(self, color_image):
        self.ocr_areas = OCRAreasFinder(color_image, self.settings["contrast"])
        self.market_width = self.ocr_areas.market_width
        self.valid_market = self.ocr_areas.valid
        if self.settings['gray_preview']:
            img = cv2.imread(unicode(self.hiddentext).encode(sys.getfilesystemencoding()), 0)
            img = array2qimage(img)
            pix = QPixmap.fromImage(img)
        else:
            pix = QPixmap(self.hiddentext)
        width = pix.width()
        height = pix.height()
        if height > 0:
            aspect_ratio = float(width)/height
            if aspect_ratio > 1.78:
                new_w = int(1.77778*height)
                rect = QRect((width-new_w)/2, 0, new_w, height)
                pix = pix.copy(rect)
            
        if self.valid_market:
            points = self.ocr_areas.market_table
            self.market_offset = (points[0][0], points[0][1])
            station = self.ocr_areas.station_name
            self.station_offset = (station[0][0], station[0][1])
            rect = QRect(0, 0, points[1][0] + 20, points[1][1] + 20)
            cut = pix.copy(rect)
            return cut
        else:
            self.market_offset = (0, 0)
            self.station_offset = (0, 0)

        return pix
class ResizableImage(QLabel):
    def __init__(self, filename, height, min_scale, max_scale):
        super(ResizableImage, self).__init__()
        self.setAlignment(Qt.AlignCenter)
        self.full_pixmap = None
        self.scaled_pixmap = None
        self.aspect = None
        self.set_file(filename)
        self.set_height(height)
        self.min_height = self.full_pixmap.height() * min_scale * self.aspect
        self.min_width = self.full_pixmap.width() * min_scale / self.aspect
        self.max_height = self.full_pixmap.height() * max_scale * self.aspect
        self.max_width = self.full_pixmap.width() * max_scale / self.aspect

    def set_file(self, filename):
        self.full_pixmap = QPixmap(filename)
        self.aspect = float(self.full_pixmap.height()) / self.full_pixmap.width()
        if self.scaled_pixmap is not None:
            self.set_height(self.scaled_pixmap.height())

    def set_height(self, height):
        self.scaled_pixmap = self.full_pixmap.scaledToHeight(height, Qt.SmoothTransformation)
        self.setPixmap(self.scaled_pixmap)

    def set_width(self, width):
        self.scaled_pixmap = self.full_pixmap.scaledToWidth(width, Qt.SmoothTransformation)
        self.setPixmap(self.scaled_pixmap)

    def resizeEvent(self, ev):
        width, height = ev.size().width(), ev.size().height()
        label_aspect = height / width
        if label_aspect > self.aspect:
            self.set_width(min(max(.9 * width, self.min_width), self.max_width))
        else:
            self.set_height(min(max(.9 * height, self.min_height), self.max_height))
示例#9
0
    def __init__(self, parent=None, filename=None):
        super(MainForm, self).__init__(parent)

        self.view = GraphicsView()
        background = QPixmap(filename)

        self.filename = os.path.splitext(filename)[0]
        if ("-%s" % ORG) in self.filename:
            self.filename = self.filename[:-len(ORG)-5] + ".png"

        self.view.setBackgroundBrush(QBrush(background))
        # self.view.setCacheMode(QGraphicsView.CacheBackground)
        # self.view.setDragMode(QGraphicsView.ScrollHandDrag)

        self.scene = QGraphicsScene(self)
        global scene
        scene = self.scene
        self.view.dialog = self
        self.view.setScene(self.scene)
        self.prevPoint = QPoint()
        self.lastStamp = -1 

        buttonLayout = QVBoxLayout()
        for text, slot in (
                ("&Tag", self.addTag),
                ("Align &bottom", self.alignBottom),
                ("Align &left", self.alignLeft),
                ("&Save", self.save),
                ("&Quit", self.accept)):
            button = QPushButton(text)
            if not MAC:
                button.setFocusPolicy(Qt.NoFocus)
            self.connect(button, SIGNAL("clicked()"), slot)
            if text == "&Save":
                buttonLayout.addStretch(5)
            if text == "&Quit":
                buttonLayout.addStretch(1)
            buttonLayout.addWidget(button)
        buttonLayout.addStretch()

        self.view.resize(background.width(), background.height())
        self.scene.setSceneRect(0, 0, background.size().width(), background.size().height())
        self.view.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        layout = QHBoxLayout()
        layout.addWidget(self.view, 1)
        layout.addLayout(buttonLayout)
        self.setLayout(layout)

        self.setWindowTitle(AppName)
        
        info_name = self.filename + "-" + TAG + ".txt"
            
        if os.path.exists(info_name):
            for tag, x, y in [line.strip().split("\t") for line in open(info_name, "rt").readlines()]:
                self.addTag(int(tag), QPointF(int(x), int(y)), adjust_position=False)
        global Dirty; Dirty=False
        self.show()
        self.raise_()
示例#10
0
    def __init__(self, image_path, sprite_width, sprite_height, label):
        pixmap = QPixmap(image_path)
        width, height = pixmap.width(), pixmap.height()
        self.pixmaps = []
        for x in range(0, width, sprite_width):
            for y in range(0, height, sprite_height):
                self.pixmaps.append(pixmap.copy(x, y, sprite_width, sprite_height))

        self._current_frame = 0
        self.label = label
示例#11
0
        def run(self):
                listofimages, nameparts, padding, dirname = self.listrestofsequence(self.f)
                numberofframes = self.numberofframes
                duration = (float(numberofframes)/ 25.0)*1000.0
                
                tempfolder = self._refreshTempFolder(gTEMPFOLDER + '/images')
                
                image = QPixmap("%s"%(listofimages[0]))
                size = '%sx%s' % (image.width(),image.height())
                
                # emit setup frames, duration, size
                
                self.EmitSetupPlayer(numberofframes,duration,size)  

                
                if nameparts[2].lower() != '.png': 
                        # convert list of images to png first, it's the only format supported by pyqt when compiled
                        # emit start of tempfolder to init dialogbox
                        self.EmitTempfolderUpdate(tempfolder,'start',len(listofimages),"Processing images... ")                
                        
                        # use ffmpeg to convert the entire list to png
                        inputfile = '%s/%s%s%sd%s' %(dirname, nameparts[0],'%0',padding,nameparts[2])
                        outputfile = '%s/%s%sd%s' % (tempfolder, 'temp.%0',padding,'.png')
                        singlefile = outputfile % 1
                        
                        # run the ffmpeg command
                        command = gFFMPEG + ' -i "'+inputfile+'" -f image2 -sameq '+outputfile
                        self.process = self.Command(command)
                        self.process.wait()
                        
                        # replace the listofimages with the new one from ffmpeg
                        listofimages, nameparts, padding, dirname = self.listrestofsequence(singlefile)
                        numberofframes = len(listofimages)
                        duration = (float(numberofframes) / 25.0)*1000.0
                        
                        # emit the signal done
                        self.EmitTempfolderUpdate(tempfolder,'done',len(listofimages), "Done.")
                        
                
            
                """
                self.EmitStartRegPdBox('start', 0, numberofframes, "Reading Images..." )
                
                for i in range(numberofframes):
                        image=QPixmap("%s"%(listofimages[i]))
                        self.EmitImage2Datablock(image,i)
                        self.EmitStartRegPdBox('between', i, numberofframes)

                
                self.EmitStartRegPdBox('end', numberofframes, numberofframes)
                
                
                self.EmitSetupPlayer(numberofframes,duration,size)  
                """
                return
示例#12
0
    def paint(self, painter, option, index):
        filePath = self.model.filePath(index)
        fileName = self.model.fileName(index)
        r = option.rect

        img = QPixmap(filePath)
        if img.isNull():
            # If not image file, try to load icon with QFileIconProvider
            # according to file type (extension name).
            # Currently not work as intended.
            fileInfo = self.model.fileInfo(index)
            icon = QFileIconProvider().icon(fileInfo)
            img = icon.pixmap(QSize(32, 32))

        # Scale to height, align center horizontally, align bottom vertically.
        if img.height() > self.thumbHeight:
            img = img.scaledToHeight(self.thumbHeight, Qt.SmoothTransformation)
        if img.width() > self.thumbHeight:
            img = img.scaledToWidth(self.thumbHeight, 
                    Qt.SmoothTransformation)
        imgLeft = (self.width - img.width()) / 2
        imgTop = self.thumbHeight - img.height()
        painter.drawPixmap(r.left()+imgLeft, r.top()+imgTop, img)

        rect = QRect(r.left(), r.top()+self.thumbHeight,
                     self.width, self.nameHeight)
        flag = Qt.AlignHCenter | Qt.TextWrapAnywhere
        # get the bounding rectangle of the fileName
        bdRect = painter.boundingRect(rect, flag, fileName)
        if bdRect.height() < rect.height():
            rect = bdRect

        if option.state & QStyle.State_Selected:
            painter.setBrush(self.parent().palette().highlight())
            painter.drawRoundedRect(rect, 5, 5)
            pen = QPen(self.parent().palette().highlightedText(), 1, Qt.SolidLine)
        else:
            pen = QPen(self.parent().palette().text(), 1, Qt.SolidLine)

        painter.setPen(pen)
        painter.drawText(rect, flag, fileName)
示例#13
0
文件: dyr.py 项目: iacopy/dyr
 def open_file(self, filePath):
     """
     Try to read the currently selected file and print it out to the stdout.
     """
     fileInfo = QFileInfo(filePath)
     fname = unicode(fileInfo.fileName())
     name, ext = path.splitext(fname)
     if ext.lower() in u'.bmp .gif .ico .jpg .png .tif .xbm'.split():
         # apertura come immagine
         message = u'Opening image {}...'.format(filePath)
         logging.info(message)
         self.status_bar.showMessage(message)
         pixmap = QPixmap(filePath)
         self.image_window = QScrollArea()
         self.image_label = QLabel()
         self.image_label.setPixmap(pixmap)
         self.image_window.setWidget(self.image_label)
         self.image_window.show()
         self.image_label.show()
         message = u'Image size: {}x{}'.format(pixmap.width(), pixmap.height())
         self.status_bar.showMessage(message)
     else:
         message = u'Opening file {}...'.format(filePath)
         logging.info(message)
         self.status_bar.showMessage(message)
         nchars = 1000000  # number of first characters showed (temp)
         try:
             fobj = open(unicode(filePath), 'rb')
         except Exception as err:
             # [Errno 22] invalid mode ('r') or filename: PyQt4.QtCore.QString(u'F:/\u65e5\u672c.txt')
             print('open error: {}'.format(err))
             logging.error(err)
             self.status_bar.showMessage(str(err))
         else:
             try:
                 data = fobj.read(nchars)
             except Exception as err:
                 print('read error: {}'.format(err))
                 logging.error(err)
                 self.status_bar.showMessage(str(err))
             else:
                 #sts, old_output = getstatusoutput('chardetect.py "{}"'.format(filePath))
                 dec = data.decode('utf-8')
                 # override existing text window
                 self.text_window.setPlainText(dec)
                 if not self.text_window.isVisible():
                     self.text_window.show()
                 status_msg = u"'{}' file read.".format(fname)
                 if len(data) == nchars:
                     status_msg += u' (NB: showed {:,} first bytes only!)'.format(nchars)
                 self.status_bar.showMessage(status_msg)
             finally:
                 fobj.close()
示例#14
0
class PixmapButton(QPushButton):
    def __init__(self, parent):
        QPushButton.__init__(self, parent)

        self.fPixmapNormal = QPixmap()
        self.fPixmapDown   = QPixmap()
        self.fPixmapHover  = QPixmap()
        self.fPixmapRect   = QRectF(0, 0, 0, 0)

        self.fIsHovered = False

        self.setText("")

    def setPixmaps(self, normal, down, hover):
        self.fPixmapNormal.load(normal)
        self.fPixmapDown.load(down)
        self.fPixmapHover.load(hover)

        width  = self.fPixmapNormal.width()
        height = self.fPixmapNormal.height()

        self.fPixmapRect = QRectF(0, 0, width, height)

        self.setMinimumSize(width, height)
        self.setMaximumSize(width, height)

    def enterEvent(self, event):
        self.fIsHovered = True
        QPushButton.enterEvent(self, event)

    def leaveEvent(self, event):
        self.fIsHovered = False
        QPushButton.leaveEvent(self, event)

    def paintEvent(self, event):
        painter = QPainter(self)
        event.accept()

        if not self.isEnabled():
            painter.save()
            painter.setOpacity(0.2)
            painter.drawPixmap(self.fPixmapRect, self.fPixmapNormal, self.fPixmapRect)
            painter.restore()

        elif self.isChecked() or self.isDown():
            painter.drawPixmap(self.fPixmapRect, self.fPixmapDown, self.fPixmapRect)

        elif self.fIsHovered:
            painter.drawPixmap(self.fPixmapRect, self.fPixmapHover, self.fPixmapRect)

        else:
            painter.drawPixmap(self.fPixmapRect, self.fPixmapNormal, self.fPixmapRect)
 def addCustomIcon(self):
   m_dir = os.path.expanduser("~/")
   customIcon = QFileDialog.getOpenFileName(self, "Select Custom Icon", m_dir, "Image Files (*.png *.jpg *.gif)")
   if customIcon is "":
     return
   else:
     icon1 = QPixmap(customIcon)
     if icon1.width() > 128 or icon1.height() > 128:
       QMessageBox.warning(self, "Large Icon File", "The custom icon is too large.\nPlease select an Icon around the size of 24x24 pixels.")
       return
     else:
       self.flagInfo = customIcon
       self.ui.flagLabel.setPixmap(icon1)
       self.flagIcon = icon1
示例#16
0
 def drawSnippet(self, graphicsview, item):
     """Draw single result item to graphicsview"""
     res = self.current_result
     snippet = self.cutImage(res.contrast_commodities_img, item)
     #cv2.imwrite('snippets/'+str(self.currentsnippet)+'.png',snippet)
     #self.currentsnippet += 1
     processedimage = array2qimage(snippet)
     pix = QPixmap()
     pix.convertFromImage(processedimage)
     if graphicsview.height() < pix.height():
         pix = pix.scaled(graphicsview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
     scene = QGraphicsScene()
     scene.addPixmap(pix)
     graphicsview.setScene(scene)
     graphicsview.show()
示例#17
0
    def loadImage(self, inputFile):
        self._setStatusLabel('load', ProcessStatus.Running)
        if (not inputFile.exists()):
            self._showStatus('ERROR: Input file not found! File path was ' + inputFile.absoluteFilePath())
            self._setStatusLabel('load', ProcessStatus.Failure)
            return False

        self._inputFile = inputFile
        pixmap = QPixmap(self._inputFile.absoluteFilePath())
        if pixmap.isNull():
            self._signalError('Loading of raw image failed.')
            return

        pixmap = QPixmap(self._inputFile.absoluteFilePath())
        w = pixmap.width()
        h = pixmap.height()

        self._scene.addPixmap(pixmap)
        self._scene.setSceneRect(QRectF(0, 0, w, h))

        self.planView.setSceneView(self._scene, QRectF(0, 0, w, h))
        self.headerView.setSceneView(self._scene, QRectF(0, 0, w, 200))
        self.footerView.setSceneView(self._scene, QRectF(100, h - 600, w - 200, 500))

        self.gcpWidget1.setScene(self._scene, 250, 100, 2)
        self.gcpWidget2.setScene(self._scene, 250, 3050, 2)
        self.gcpWidget3.setScene(self._scene, 3200, 3050, 2)
        self.gcpWidget4.setScene(self._scene, 3200, 100, 2)

        self.inputFileNameLabel.setText(self._inputFile.baseName())
        drawing = Drawing(self._inputFile)
        if drawing.isValid():
            self.siteEdit.setText(drawing.item().siteCode())
            self.typeCombo.setCurrentIndex(self.typeCombo.findData(drawing.item().classCode()))
            self.numberSpin.setValue(int(drawing.item().itemId()) or 0)
            self.eastSpin.setValue(drawing.easting() or 0)
            self.northSpin.setValue(drawing.northing() or 0)
            self.suffixEdit.setText(drawing.suffix())
            self._updateFileNames(drawing)
            self._updateGeoPoints()
            pointFile = self.pointFileInfo()
            if pointFile.exists():
                self._loadGcp(pointFile.absoluteFilePath())
            self._setStatusLabel('load', ProcessStatus.Success)
            QCoreApplication.processEvents()
            return True

        return False
示例#18
0
 def draw_image(self):
     data = urllib.request.urlopen(self.url).read()
     image = QtGui.QImage()
     image.loadFromData(data)
     
     app = QApplication(sys.argv)
     w = QWidget()
     w.setWindowTitle('Pokemon')
     
     label = QLabel(w)
     pixmap = QPixmap(image)
     label.setPixmap(pixmap)
     w.resize(pixmap.width(), pixmap.height())
     
     w.show()
     app.exec_()
示例#19
0
    def createListOption(self):
        def addItem(label, icon_pixmap, width, height):
            item = QListWidgetItem(list_option)
            item.setText(label)
            item.setTextAlignment(Qt.AlignHCenter)
            item.setIcon(QIcon(icon_pixmap))
            item.setSizeHint(QSize(width, height))

        list_option = QListWidget()
        list_option.setAutoFillBackground(True)
        list_option.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        list_option.setTextElideMode(Qt.ElideNone)
        list_option.setMovement(QListView.Static)
        list_option.setFlow(QListView.TopToBottom)
        list_option.setProperty("isWrapping", QVariant(False))
        list_option.setSpacing(3)
        list_option.setViewMode(QListView.IconMode)

        items = []
        items.append((QApplication.translate("option", "Connections"), "connections.png"))
        items.append((QApplication.translate("option", "Accounts"), "accounts.png"))
        items.append((QApplication.translate("option", "Aliases"), "aliases.png"))
        items.append((QApplication.translate("option", "Macros"), "macros.png"))
        items.append((QApplication.translate("option", "Keypad"), "keypad.png"))
        items.append((QApplication.translate("option", "Triggers"), "triggers.png"))
        items.append((QApplication.translate("option", "Preferences"), "preferences.png"))

        max_width = 0
        for label, icon_name in items:
            w = list_option.fontMetrics().boundingRect(label).width()
            if w > max_width:
                max_width = w

        # An empiric method to align element in the center of the QListWidget
        max_width += 15
        total_height = 0

        for label, icon_name in items:
            icon_pixmap = QPixmap(":/images/" + icon_name)
            height = icon_pixmap.height() + list_option.fontMetrics().height() + 3
            total_height += height + 5
            addItem(label, icon_pixmap, max_width, height)

        list_option.setUniformItemSizes(True)
        list_option.setFixedWidth(max_width + 10)
        list_option.setMinimumHeight(total_height)
        return list_option
示例#20
0
 def __init__(self,parent,nfile):
     QDialog.__init__(self,parent)
     tab = QLabel()
     pal = QPalette(self.palette())
     bgcolor = QColor("#ffffff")
     pal.setColor(QPalette.Background,bgcolor)
     tab.setPalette(pal)
     if nfile == "":
         return
     pix = QPixmap(nfile)
     tab.setPixmap(pix)
     scrollArea = QScrollArea()
     scrollArea.setWidget(tab)
     mainLayout = QVBoxLayout()
     mainLayout.addWidget(scrollArea)
     self.setLayout(mainLayout)
     self.resize(pix.width()+25, pix.height()+25)
示例#21
0
 def drawStationName(self):
     """Draw station name snippet to station_name_img"""
     res = self.current_result
     name = res.station.name
     self.station_name.setEditText(name.value)
     img = self.cutImage(res.contrast_station_img, name)
     processedimage = array2qimage(img)
     pix = QPixmap()
     pix.convertFromImage(processedimage)
     if self.station_name_img.height() < pix.height():
         pix = pix.scaled(self.station_name_img.size(),
                          Qt.KeepAspectRatio,
                          Qt.SmoothTransformation)
     scene = QGraphicsScene()
     scene.addPixmap(pix)
     
     self.station_name_img.setScene(scene)
     self.station_name_img.show()
示例#22
0
def show():
    """
    Simple function to show how to load an image from a resource file and
    add it to a widget.
    @return:
    """
    # Create window
    app = QApplication(sys.argv)
    w = QWidget()
    w.setWindowTitle("PyQT4")
    # Create widget
    label = QLabel(w)
    image = ':/alba-logo.png'
    pixmap = QPixmap(image)
    label.setPixmap(pixmap)
    w.resize(pixmap.width(), pixmap.height())
    # Draw window
    w.show()
    sys.exit(app.exec_())
示例#23
0
def show():
    """
    Simple function to show how to load an image from a resource file and
    add it to a widget.
    @return:
    """
    # Create window
    app = QApplication(sys.argv)
    w = QWidget()
    w.setWindowTitle("PyQT4")
    # Create widget
    label = QLabel(w)
    image = resource_filename(Requirement.parse("setuptools_resource_example_pkg"), "mypkg/resources/alba-logo.png")
    pixmap = QPixmap(image)
    label.setPixmap(pixmap)
    w.resize(pixmap.width(), pixmap.height())
    # Draw window
    w.show()
    sys.exit(app.exec_())
示例#24
0
def crop_pixmaps(path, mask, pretend=False):
    """ crop all pixmaps in a dir according to a masks.  This function
    does nothing in regards to validating modules. If the pixmaps
    exist and an entry exists in masks, the pixmaps get chopped.
    """
    from PyQt4.QtGui import QPixmap
    for fname in os.listdir(path):
        if extension(fname) == 'png':
            fpath = os.path.join(path, fname)
            pixmap = QPixmap(fpath)
            x, y, w, h = mask[0], mask[1], mask[2], mask[3]
            if pixmap.isNull() is False and \
               pixmap.width() > w and \
               pixmap.height() > h:
                pixmap = pixmap.copy(x, y, w, h)
                if pretend:
                    print 'PRETEND:',
                else:
                    pixmap.save(fpath, 'PNG')
                print 'wrote %s x=%i y=%i w=%i h=%i' % (fpath, x, y, w, h)
示例#25
0
def getImageInformationsHeader(path, graphicsItem):
	"""
	This definition returns a :class:`sibl_gui.libraries.freeImage.freeImage.ImageInformationsHeader` class
	from given path and graphics item.

	:param path: Image path. ( String )
	:param graphicsItem: Image graphics item. ( QImage, QPixmap, QIcon )
	:return: Image informations header. ( ImageInformationsHeader )
	"""

	if not foundations.common.pathExists(path):
		raise foundations.exceptions.FileExistsError("{0} | '{1}' file doesn't exists!".format(__name__, path))

	if type(graphicsItem) is QIcon:
		graphicsItem = QPixmap(path)

	return ImageInformationsHeader(path=path,
									width=graphicsItem.width(),
									height=graphicsItem.height(),
									bpp=graphicsItem.depth(),
									osStats=os.stat(path))
示例#26
0
	def openImage(self ):
		"""
		Öffnet einen Dialog zum Laden eines Charakterbildes und speichert selbiges im Charakter-Speicher.

		\note Das Bild wird auf eine in der Configurationsdatei festgelegte Maximalgröße skaliert, um die Größe überschaubar zu halten.
		"""

		appPath = PathTools.program_path()

		# Pfad zum Speicherverzeichnis
		savePath = ""
		if os.name == "nt":
			savePath = os.environ['HOMEPATH']
		else:
			savePath = os.environ['HOME']

		# Wenn Unterverzeichnis nicht existiert, suche im Programmverzeichnis.
		if ( not os.path.exists( savePath ) ):
			savePath = appPath

		fileData = QFileDialog.getOpenFileName(
			self,
			self.tr( "Select Image File" ),
			savePath,
			self.tr( "Images (*.jpg *.jpeg *.png *.bmp *.gif *.pgm *.pbm *.ppm *.svg )" )
		)

		# Sollte PySide verwendet werden!
		#filePath = fileData[0]
		# Sollte PyQt4 verwendet werden!
		filePath = fileData

		if ( filePath ):
			image = QPixmap(filePath)
			if image.width() > Config.CHARACTER_PIC_WIDTH_MAX or image.height() > Config.CHARACTER_PIC_HEIGHT_MAX:
				image = image.scaled(800, 800, Qt.KeepAspectRatio)

			self.updatePicture(image)

			self.__character.picture = image
示例#27
0
class GOBoard(QWidget):

    on_click = pyqtSignal(str, int)

    def __init__(self):
        super().__init__()
        self.__background_pixmap = QPixmap(get_asset_path("board.png"))
        self.__background_label = QLabel(self)
        self.__background_label.setPixmap(self.__background_pixmap)
        self.setMinimumSize(self.__background_pixmap.size())
        self.__pieces = {}

    def pixmap_height(self):
        return self.__background_pixmap.height()

    def add_square(self, letter, y, color):
        y -= 1
        letters = list(string.ascii_uppercase)
        letters.remove("I")
        a = letters.index(letter)
        if (letter, y + 1) in self.__pieces:
            print("ERROR: Space {},{} already occupied".format(letter, y + 1))
        else:
            piece = GOSquare(27 + a * 23,
                             self.__background_pixmap.height() - (20 + y * 23),
                             color, self)
            self.__pieces[(letter, y + 1)] = piece
            piece.show()

    def add_piece(self, letter, y, text, color):
        y -= 1
        letters = list(string.ascii_uppercase)
        letters.remove("I")
        a = letters.index(letter)
        if (letter, y + 1) in self.__pieces:
            print("ERROR: Space {},{} already occupied".format(letter, y + 1))
        else:
            piece = GOPiece(23 + a * 23,
                            self.__background_pixmap.height() - (24 + y * 23),
                            text, color, self)
            self.__pieces[(letter, y + 1)] = piece
            piece.show()

    def remove_piece(self, letter, y):
        if (letter, y) in self.__pieces:
            piece = self.__pieces[(letter, y)]
            piece.hide()
            piece.deleteLater()
            del self.__pieces[(letter, y)]
        else:
            print("ERROR: There is no piece at {},{}".format(letter, y))

    def mousePressEvent(self, e):
        x = (e.x() - 27) // 23
        y = (self.__background_pixmap.height() - 20 - e.y()) // 23
        y += 2
        letters = list(string.ascii_uppercase)
        letters.remove("I")
        letra = letters[x]
        if y <= 19 and letra <= "T":
            self.on_click.emit(letra, y)
示例#28
0
class Entity(QWidget):

    def __init__(self, base_image, parent=None):
        super().__init__(parent)
        self._base_label = QLabel(self)
        self._base_image = base_image

        self._decor_label = QLabel(self)
        self._decor_pixmap = None

        self.__pixmap = None
        """:type: PyQt4.QtGui.QPixmap"""

        self.__cord_x = 0
        self.__cord_y = 0
        self.__angle = 0
        self.setAlignment(Qt.AlignCenter)
        self.updatePixmap()

        if _debugging:
            self.setStyleSheet("border: 1px solid black")

    @property
    def angle(self):
        return self.__angle

    @angle.setter
    def angle(self, angle):
        self.__angle = angle
        self.updatePixmap()

    @property
    def cord_x(self):
        return self.__cord_x

    @cord_x.setter
    def cord_x(self, cord):
        self.__cord_x = cord
        self.move(self.cord_x, self.cord_y)

    @property
    def cord_y(self):
        return self.__cord_y

    @cord_y.setter
    def cord_y(self, cord):
        self.__cord_y = cord
        self.move(self.cord_x, self.cord_y)

    def add_decoration(self, path):
        if path is None:
            self._decor_label.hide()
        else:
            self._decor_label = QLabel(self)
            self._decor_pixmap = QPixmap(path)
            self._decor_pixmap = self._decor_pixmap.scaled(self._decor_pixmap.width() * _SCALE,
                                                           self._decor_pixmap.height() * _SCALE)
            self._decor_pixmap = self._decor_pixmap.transformed(QTransform().rotate(self.angle))
            self._decor_label.setPixmap(self._decor_pixmap)

    def updatePixmap(self):
        path = _PATH + os.sep + "assets" + os.sep + self._base_image
        self.__pixmap = QPixmap(path)
        self.__pixmap = self.__pixmap.scaled(self.__pixmap.width()*_SCALE, self.__pixmap.height()*_SCALE)
        self.__pixmap = self.__pixmap.transformed(QTransform().rotate(self.angle))
        self._base_label.setPixmap(self.__pixmap)
        self.setFixedSize(self.__pixmap.width(), self.__pixmap.height())

    def setFixedSize(self, x, y):
        super().setFixedSize(x, y)
        self._base_label.setFixedSize(x, y)

    def setAlignment(self, alignment):
        self._base_label.setAlignment(alignment)
        self._decor_label.setAlignment(alignment)
示例#29
0
class Radar(QtGui.QLabel):
    def __init__(self, parent, radar, rect, myname):
        global xscale, yscale
        self.myname = myname
        self.rect = rect
        self.anim = 5
        self.zoom = radar["zoom"]
        self.point = radar["center"]
        self.radar = radar
        self.baseurl = self.mapurl(radar, rect)
        print "map base url: " + self.baseurl
        QtGui.QLabel.__init__(self, parent)
        self.interval = Config.radar_refresh * 60
        self.lastwx = 0
        self.retries = 0
        self.corners = getCorners(self.point, self.zoom, rect.width(),
                                  rect.height())
        self.baseTime = 0
        self.cornerTiles = {
            "NW":
            getTileXY(LatLng(self.corners["N"], self.corners["W"]), self.zoom),
            "NE":
            getTileXY(LatLng(self.corners["N"], self.corners["E"]), self.zoom),
            "SE":
            getTileXY(LatLng(self.corners["S"], self.corners["E"]), self.zoom),
            "SW":
            getTileXY(LatLng(self.corners["S"], self.corners["W"]), self.zoom)
        }
        self.tiles = []
        self.tiletails = []
        self.totalWidth = 0
        self.totalHeight = 0
        self.tilesWidth = 0
        self.tilesHeight = 0

        self.setObjectName("radar")
        self.setGeometry(rect)
        self.setStyleSheet("#radar { background-color: grey; }")
        self.setAlignment(Qt.AlignCenter)

        self.wwx = QtGui.QLabel(self)
        self.wwx.setObjectName("wx")
        self.wwx.setStyleSheet("#wx { background-color: transparent; }")
        self.wwx.setGeometry(0, 0, rect.width(), rect.height())

        self.wmk = QtGui.QLabel(self)
        self.wmk.setObjectName("mk")
        self.wmk.setStyleSheet("#mk { background-color: transparent; }")
        self.wmk.setGeometry(0, 0, rect.width(), rect.height())

        for y in range(int(self.cornerTiles["NW"]["Y"]),
                       int(self.cornerTiles["SW"]["Y"]) + 1):
            self.totalHeight += 256
            self.tilesHeight += 1
            for x in range(int(self.cornerTiles["NW"]["X"]),
                           int(self.cornerTiles["NE"]["X"]) + 1):
                tile = {"X": x, "Y": y}
                self.tiles.append(tile)
                if 'color' not in radar:
                    radar['color'] = 6
                if 'smooth' not in radar:
                    radar['smooth'] = 1
                if 'snow' not in radar:
                    radar['snow'] = 1
                tail = "/256/%d/%d/%d/%d/%d_%d.png" % (
                    self.zoom, x, y, radar['color'], radar['smooth'],
                    radar['snow'])
                if 'oldcolor' in radar:
                    tail = "/256/%d/%d/%d.png?color=%d" % (self.zoom, x, y,
                                                           radar['color'])
                self.tiletails.append(tail)
        for x in range(int(self.cornerTiles["NW"]["X"]),
                       int(self.cornerTiles["NE"]["X"]) + 1):
            self.totalWidth += 256
            self.tilesWidth += 1
        self.frameImages = []
        self.frameIndex = 0
        self.displayedFrame = 0
        self.ticker = 0
        self.lastget = 0

    def rtick(self):
        if time.time() > (self.lastget + self.interval):
            self.get(time.time())
            self.lastget = time.time()
        if len(self.frameImages) < 1:
            return
        if self.displayedFrame == 0:
            self.ticker += 1
            if self.ticker < 5:
                return
        self.ticker = 0
        f = self.frameImages[self.displayedFrame]
        self.wwx.setPixmap(f["image"])
        self.displayedFrame += 1
        if self.displayedFrame >= len(self.frameImages):
            self.displayedFrame = 0

    def get(self, t=0):
        t = int(t / 600) * 600
        if t > 0 and self.baseTime == t:
            return
        if t == 0:
            t = self.baseTime
        else:
            self.baseTime = t
        newf = []
        for f in self.frameImages:
            if f["time"] >= (t - self.anim * 600):
                newf.append(f)
        self.frameImages = newf
        firstt = t - self.anim * 600
        for tt in range(firstt, t + 1, 600):
            print "get... " + str(tt) + " " + self.myname
            gotit = False
            for f in self.frameImages:
                if f["time"] == tt:
                    gotit = True
            if not gotit:
                self.getTiles(tt)
                break

    def getTiles(self, t, i=0):
        t = int(t / 600) * 600
        self.getTime = t
        self.getIndex = i
        if i == 0:
            self.tileurls = []
            self.tileQimages = []
            for tt in self.tiletails:
                tileurl = "https://tilecache.rainviewer.com/v2/radar/%d/%s" \
                    % (t, tt)
                self.tileurls.append(tileurl)
        print self.myname + " " + str(self.getIndex) + " " + self.tileurls[i]
        self.tilereq = QNetworkRequest(QUrl(self.tileurls[i]))
        self.tilereply = manager.get(self.tilereq)
        QtCore.QObject.connect(self.tilereply, QtCore.SIGNAL("finished()"),
                               self.getTilesReply)

    def getTilesReply(self):
        print "getTilesReply " + str(self.getIndex)
        if self.tilereply.error() != QNetworkReply.NoError:
            return
        self.tileQimages.append(QImage())
        self.tileQimages[self.getIndex].loadFromData(self.tilereply.readAll())
        self.getIndex = self.getIndex + 1
        if self.getIndex < len(self.tileurls):
            self.getTiles(self.getTime, self.getIndex)
        else:
            self.combineTiles()
            self.get()

    def combineTiles(self):
        global radar1
        ii = QImage(self.tilesWidth * 256, self.tilesHeight * 256,
                    QImage.Format_ARGB32)
        painter = QPainter()
        painter.begin(ii)
        painter.setPen(QColor(255, 255, 255, 255))
        painter.setFont(QFont("Arial", 10))
        i = 0
        xo = self.cornerTiles["NW"]["X"]
        xo = int((int(xo) - xo) * 256)
        yo = self.cornerTiles["NW"]["Y"]
        yo = int((int(yo) - yo) * 256)
        for y in range(0, self.totalHeight, 256):
            for x in range(0, self.totalWidth, 256):
                if self.tileQimages[i].format() == 5:
                    painter.drawImage(x, y, self.tileQimages[i])
                # painter.drawRect(x, y, 255, 255)
                # painter.drawText(x+3, y+12, self.tiletails[i])
                i += 1
        painter.end()
        painter = None
        self.tileQimages = []
        ii2 = ii.copy(-xo, -yo, self.rect.width(), self.rect.height())
        ii = None
        painter2 = QPainter()
        painter2.begin(ii2)
        timestamp = "{0:%H:%M} rainvewer.com".format(
            datetime.datetime.fromtimestamp(self.getTime))
        painter2.setPen(QColor(63, 63, 63, 255))
        painter2.setFont(QFont("Arial", 8))
        painter2.setRenderHint(QPainter.TextAntialiasing)
        painter2.drawText(3 - 1, 12 - 1, timestamp)
        painter2.drawText(3 + 2, 12 + 1, timestamp)
        painter2.setPen(QColor(255, 255, 255, 255))
        painter2.drawText(3, 12, timestamp)
        painter2.drawText(3 + 1, 12, timestamp)
        painter2.end()
        painter2 = None
        ii3 = QPixmap(ii2)
        ii2 = None
        self.frameImages.append({"time": self.getTime, "image": ii3})
        ii3 = None

    def mapurl(self, radar, rect):
        mb = 0
        try:
            mb = Config.usemapbox
        except:
            pass
        if mb:
            return self.mapboxurl(radar, rect)
        else:
            return self.googlemapurl(radar, rect)

    def mapboxurl(self, radar, rect):
        #  note we're using google maps zoom factor.
        #  Mapbox equivilant zoom is one less
        #  They seem to be using 512x512 tiles instead of 256x256
        style = 'mapbox/satellite-streets-v10'
        if 'style' in radar:
            style = radar['style']
        return 'https://api.mapbox.com/styles/v1/' + \
               style + \
               '/static/' + \
               str(radar['center'].lng) + ',' + \
               str(radar['center'].lat) + ',' + \
               str(radar['zoom']-1) + ',0,0/' + \
               str(rect.width()) + 'x' + str(rect.height()) + \
               '?access_token=' + ApiKeys.mbapi

    def googlemapurl(self, radar, rect):
        urlp = []
        if len(ApiKeys.googleapi) > 0:
            urlp.append('key=' + ApiKeys.googleapi)
        urlp.append('center=' + str(radar['center'].lat) + ',' +
                    str(radar['center'].lng))
        zoom = radar['zoom']
        rsize = rect.size()
        if rsize.width() > 640 or rsize.height() > 640:
            rsize = QtCore.QSize(rsize.width() / 2, rsize.height() / 2)
            zoom -= 1
        urlp.append('zoom=' + str(zoom))
        urlp.append('size=' + str(rsize.width()) + 'x' + str(rsize.height()))
        urlp.append('maptype=hybrid')

        return 'http://maps.googleapis.com/maps/api/staticmap?' + \
            '&'.join(urlp)

    def basefinished(self):
        if self.basereply.error() != QNetworkReply.NoError:
            return
        self.basepixmap = QPixmap()
        self.basepixmap.loadFromData(self.basereply.readAll())
        if self.basepixmap.size() != self.rect.size():
            self.basepixmap = self.basepixmap.scaled(self.rect.size(),
                                                     Qt.KeepAspectRatio,
                                                     Qt.SmoothTransformation)
        self.setPixmap(self.basepixmap)

        # make marker pixmap
        self.mkpixmap = QPixmap(self.basepixmap.size())
        self.mkpixmap.fill(Qt.transparent)
        br = QBrush(QColor(Config.dimcolor))
        painter = QPainter()
        painter.begin(self.mkpixmap)
        painter.fillRect(0, 0, self.mkpixmap.width(), self.mkpixmap.height(),
                         br)
        for marker in self.radar['markers']:
            if 'visible' not in marker or marker['visible'] == 1:
                pt = getPoint(marker["location"], self.point, self.zoom,
                              self.rect.width(), self.rect.height())
                mk2 = QImage()
                mkfile = 'teardrop'
                if 'image' in marker:
                    mkfile = marker['image']
                if os.path.dirname(mkfile) == '':
                    mkfile = os.path.join('markers', mkfile)
                if os.path.splitext(mkfile)[1] == '':
                    mkfile += '.png'
                mk2.load(mkfile)
                if mk2.format != QImage.Format_ARGB32:
                    mk2 = mk2.convertToFormat(QImage.Format_ARGB32)
                mkh = 80  # self.rect.height() / 5
                if 'size' in marker:
                    if marker['size'] == 'small':
                        mkh = 64
                    if marker['size'] == 'mid':
                        mkh = 70
                    if marker['size'] == 'tiny':
                        mkh = 40
                if 'color' in marker:
                    c = QColor(marker['color'])
                    (cr, cg, cb, ca) = c.getRgbF()
                    for x in range(0, mk2.width()):
                        for y in range(0, mk2.height()):
                            (r, g, b,
                             a) = QColor.fromRgba(mk2.pixel(x, y)).getRgbF()
                            r = r * cr
                            g = g * cg
                            b = b * cb
                            mk2.setPixel(x, y,
                                         QColor.fromRgbF(r, g, b, a).rgba())
                mk2 = mk2.scaledToHeight(mkh, 1)
                painter.drawImage(pt.x - mkh / 2, pt.y - mkh / 2, mk2)

        painter.end()

        self.wmk.setPixmap(self.mkpixmap)

    def getbase(self):
        global manager
        self.basereq = QNetworkRequest(QUrl(self.baseurl))
        self.basereply = manager.get(self.basereq)
        QtCore.QObject.connect(self.basereply, QtCore.SIGNAL("finished()"),
                               self.basefinished)

    def start(self, interval=0):
        if interval > 0:
            self.interval = interval
        self.getbase()
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.rtick)
        self.lastget = time.time() - self.interval + random.uniform(3, 10)

    def wxstart(self):
        print "wxstart for " + self.myname
        self.timer.start(200)

    def wxstop(self):
        print "wxstop for " + self.myname
        self.timer.stop()

    def stop(self):
        try:
            self.timer.stop()
            self.timer = None
        except Exception:
            pass
示例#30
0
文件: EkdWidgets.py 项目: Ptaah/Ekd
class EkdPreview():
    """ On gère un cache des Pixmap générés
    La méthode est simple : au lieu de charger toute l'image et d'en faire une préview après
    on génère la préview au chargement de l'image. On est ainsi moins dépendant de la taille
    de l'image à prévisualiser
    Pour faire ça, on utilise le QImageReader
    On utilise également la fonction de cache pour éviter d'avoir à regénérer à chaque fois les
    apperçus"""
    def __init__(self, imagePath, width=64, height=0, quality=0, Cache=True, keepRatio=True, magnify=False):
        """
        imagePath : chemin de l'image a charger
        size : taille de la préview a générer
        quality : qualité de la preview (0=mavaise, 10=très bonne)
        keepRation : garde-t-on les proportion de l'image
        magnify : agrandit-on l'image si la preview demandée est plus grande que l'image originale
        """
        self.preview = QPixmap()
        if width == 0:
            width = 64
        if height == 0:
            height = width
        self.size = QSize(width, height)
        self.quality = quality
        self.imageName = imagePath
        self.keepRatio = keepRatio
        self.magnify = magnify
        self.cache = Cache
        QPixmapCache.setCacheLimit(50*1024)
        self.update()

    def get_preview(self):
        return self.preview

    def toggle_keepRatio(self):
        self.keepRatio = not self.keepRatio

    def get_image(self):
        return self.preview.toImage()

    def get_imageName(self):
        return self.imageName

    def set_imageName(self, path):
        self.imageName = path

    def get_size(self):
        return self.size

    def set_size(self, size):
        self.size = size

    def get_quality(self):
        return self.quality

    def set_quality(self, quality):
        self.quality = quality

    def width(self):
        return self.preview.width()

    def height(self):
        return self.preview.height()

    def origin(self):
        old_keepRatio=self.keepRatio
        self.keepRatio=False
        self.set_size(self.origineSize)
        self.update()
        self.keepRatio=old_keepRatio

    def update(self):
        """ Fonction de mise à jour de la préview :
            * Si la taille de l'image est plus petite que la taille souhaité, on n'agrandi pas l'image, on prend la plus petite des deux
            * Le cache contient en index les images+size"""
        miniImg = QImage()
        image = QImageReader(self.imageName)
        self.origineSize = image.size()
        image.setQuality(self.quality)
        if not self.magnify :
            if ( ( self.size.width() + self.size.height() ) > (image.size().width() + image.size().height() ) ) :
                self.size = image.size()

        if self.keepRatio :
            image.setScaledSize(QSize(self.size.width(), image.size().height() * self.size.width() / image.size().width() ) )
        else :
            image.setScaledSize(self.size)

        if not QPixmapCache.find(self.imageName + str(self.size), self.preview) or not self.cache:
            image.read(miniImg)
            self.preview = self.preview.fromImage(miniImg)
            if self.cache :
                QPixmapCache.insert(self.imageName + str(self.size), self.preview)
示例#31
0
class Radar(QtGui.QLabel):
    def __init__(self, parent, radar, rect, myname):
        global xscale, yscale
        self.myname = myname
        self.rect = rect
        self.satellite = Config.satellite
        try:
            if radar["satellite"]:
                self.satellite = 1
        except KeyError:
            pass
        self.baseurl = self.mapurl(radar, rect, False)
        print "google map base url: " + self.baseurl
        self.mkurl = self.mapurl(radar, rect, True)
        self.wxurl = self.radarurl(radar, rect)
        print "radar url: " + self.wxurl
        QtGui.QLabel.__init__(self, parent)
        self.interval = Config.radar_refresh * 60
        self.lastwx = 0
        self.retries = 0

        self.setObjectName("radar")
        self.setGeometry(rect)
        self.setStyleSheet("#radar { background-color: grey; }")
        self.setAlignment(Qt.AlignCenter)

        self.wwx = QtGui.QLabel(self)
        self.wwx.setObjectName("wx")
        self.wwx.setStyleSheet("#wx { background-color: transparent; }")
        self.wwx.setGeometry(0, 0, rect.width(), rect.height())

        self.wmk = QtGui.QLabel(self)
        self.wmk.setObjectName("mk")
        self.wmk.setStyleSheet("#mk { background-color: transparent; }")
        self.wmk.setGeometry(0, 0, rect.width(), rect.height())

        self.wxmovie = QMovie()

    def mapurl(self, radar, rect, markersonly):
        # 'https://maps.googleapis.com/maps/api/staticmap?maptype=hybrid&center='+rcenter.lat+','+rcenter.lng+'&zoom='+rzoom+'&size=300x275'+markersr;
        urlp = []

        if len(ApiKeys.googleapi) > 0:
            urlp.append('key=' + ApiKeys.googleapi)
        urlp.append('center=' + str(radar['center'].lat) + ',' +
                    str(radar['center'].lng))
        zoom = radar['zoom']
        rsize = rect.size()
        if rsize.width() > 640 or rsize.height() > 640:
            rsize = QtCore.QSize(rsize.width() / 2, rsize.height() / 2)
            zoom -= 1
        urlp.append('zoom=' + str(zoom))
        urlp.append('size=' + str(rsize.width()) + 'x' + str(rsize.height()))
        if markersonly:
            urlp.append('style=visibility:off')
        else:
            urlp.append('maptype=hybrid')
        for marker in radar['markers']:
            marks = []
            for opts in marker:
                if opts != 'location':
                    marks.append(opts + ':' + marker[opts])
            marks.append(
                str(marker['location'].lat) + ',' +
                str(marker['location'].lng))
            urlp.append('markers=' + '|'.join(marks))

        return 'http://maps.googleapis.com/maps/api/staticmap?' + \
            '&'.join(urlp)

    def radarurl(self, radar, rect):
        # wuprefix = 'http://api.wunderground.com/api/';
        # wuprefix+wuapi+'/animatedradar/image.gif?maxlat='+rNE.lat+'&maxlon='+
        #       rNE.lng+'&minlat='+rSW.lat+'&minlon='+rSW.lng+wuoptionsr;
        # wuoptionsr = '&width=300&height=275&newmaps=0&reproj.automerc=1&num=5
        #       &delay=25&timelabel=1&timelabel.y=10&rainsnow=1&smooth=1';
        rr = getCorners(radar['center'], radar['zoom'], rect.width(),
                        rect.height())
        if self.satellite:
            return (Config.wuprefix + ApiKeys.wuapi +
                    '/animatedsatellite/lang:' + Config.wuLanguage +
                    '/image.gif' + '?maxlat=' + str(rr['N']) + '&maxlon=' +
                    str(rr['E']) + '&minlat=' + str(rr['S']) + '&minlon=' +
                    str(rr['W']) + '&width=' + str(rect.width()) + '&height=' +
                    str(rect.height()) +
                    '&newmaps=0&reproj.automerc=1&num=5&delay=25' +
                    '&timelabel=1&timelabel.y=10&smooth=1&key=sat_ir4_bottom')
        else:
            return (Config.wuprefix + ApiKeys.wuapi + '/animatedradar/lang:' +
                    Config.wuLanguage + '/image.gif' + '?maxlat=' +
                    str(rr['N']) + '&maxlon=' + str(rr['E']) + '&minlat=' +
                    str(rr['S']) + '&minlon=' + str(rr['W']) + '&width=' +
                    str(rect.width()) + '&height=' + str(rect.height()) +
                    '&newmaps=0&reproj.automerc=1&num=5&delay=25' +
                    '&timelabel=1&timelabel.y=10&rainsnow=1&smooth=1' +
                    '&radar_bitmap=1&xnoclutter=1&xnoclutter_mask=1&cors=1')

    def basefinished(self):
        if self.basereply.error() != QNetworkReply.NoError:
            return
        self.basepixmap = QPixmap()
        self.basepixmap.loadFromData(self.basereply.readAll())
        if self.basepixmap.size() != self.rect.size():
            self.basepixmap = self.basepixmap.scaled(self.rect.size(),
                                                     Qt.KeepAspectRatio,
                                                     Qt.SmoothTransformation)
        if self.satellite:
            p = QPixmap(self.basepixmap.size())
            p.fill(Qt.transparent)
            painter = QPainter()
            painter.begin(p)
            painter.setOpacity(0.6)
            painter.drawPixmap(0, 0, self.basepixmap)
            painter.end()
            self.basepixmap = p
            self.wwx.setPixmap(self.basepixmap)
        else:
            self.setPixmap(self.basepixmap)

    def mkfinished(self):
        if self.mkreply.error() != QNetworkReply.NoError:
            return
        self.mkpixmap = QPixmap()
        self.mkpixmap.loadFromData(self.mkreply.readAll())
        if self.mkpixmap.size() != self.rect.size():
            self.mkpixmap = self.mkpixmap.scaled(self.rect.size(),
                                                 Qt.KeepAspectRatio,
                                                 Qt.SmoothTransformation)
        br = QBrush(QColor(Config.dimcolor))
        painter = QPainter()
        painter.begin(self.mkpixmap)
        painter.fillRect(0, 0, self.mkpixmap.width(), self.mkpixmap.height(),
                         br)
        painter.end()
        self.wmk.setPixmap(self.mkpixmap)

    def wxfinished(self):
        if self.wxreply.error() != QNetworkReply.NoError:
            print "get radar error " + self.myname + ":" + \
                str(self.wxreply.error())
            self.lastwx = 0
            return
        print "radar map received:" + self.myname + ":" + time.ctime()
        self.wxmovie.stop()
        self.wxdata = QtCore.QByteArray(self.wxreply.readAll())
        self.wxbuff = QtCore.QBuffer(self.wxdata)
        self.wxbuff.open(QtCore.QIODevice.ReadOnly)
        mov = QMovie(self.wxbuff, 'GIF')
        print "radar map frame count:" + self.myname + ":" + \
            str(mov.frameCount()) + ":r" + str(self.retries)
        if mov.frameCount() > 2:
            self.lastwx = time.time()
            self.retries = 0
        else:
            # radar image retreval failed
            if self.retries > 3:
                # give up, last successful animation stays.
                # the next normal radar_refresh time (default 10min) will apply
                self.lastwx = time.time()
                return

            self.lastwx = 0
            # count retries
            self.retries = self.retries + 1
            # retry in 5 seconds
            QtCore.QTimer.singleShot(5 * 1000, self.getwx)
            return
        self.wxmovie = mov
        if self.satellite:
            self.setMovie(self.wxmovie)
        else:
            self.wwx.setMovie(self.wxmovie)
        if self.parent().isVisible():
            self.wxmovie.start()

    def getwx(self):
        global lastapiget
        i = 0.1
        # making sure there is at least 2 seconds between radar api calls
        lastapiget += 2
        if time.time() > lastapiget:
            lastapiget = time.time()
        else:
            i = lastapiget - time.time()
        print "get radar api call spacing oneshot get i=" + str(i)
        QtCore.QTimer.singleShot(i * 1000, self.getwx2)

    def getwx2(self):
        global manager
        try:
            if self.wxreply.isRunning():
                return
        except Exception:
            pass
        print "getting radar map " + self.myname + ":" + time.ctime()
        self.wxreq = QNetworkRequest(
            QUrl(self.wxurl + '&rrrand=' + str(time.time())))
        self.wxreply = manager.get(self.wxreq)
        QtCore.QObject.connect(self.wxreply, QtCore.SIGNAL("finished()"),
                               self.wxfinished)

    def getbase(self):
        global manager
        self.basereq = QNetworkRequest(QUrl(self.baseurl))
        self.basereply = manager.get(self.basereq)
        QtCore.QObject.connect(self.basereply, QtCore.SIGNAL("finished()"),
                               self.basefinished)

    def getmk(self):
        global manager
        self.mkreq = QNetworkRequest(QUrl(self.mkurl))
        self.mkreply = manager.get(self.mkreq)
        QtCore.QObject.connect(self.mkreply, QtCore.SIGNAL("finished()"),
                               self.mkfinished)

    def start(self, interval=0):
        if interval > 0:
            self.interval = interval
        self.getbase()
        self.getmk()
        self.timer = QtCore.QTimer()
        QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"),
                               self.getwx)

    def wxstart(self):
        print "wxstart for " + self.myname
        if (self.lastwx == 0 or (self.lastwx + self.interval) < time.time()):
            self.getwx()
        # random 1 to 10 seconds added to refresh interval to spread the
        # queries over time
        i = (self.interval + random.uniform(1, 10)) * 1000
        self.timer.start(i)
        self.wxmovie.start()
        QtCore.QTimer.singleShot(1000, self.wxmovie.start)

    def wxstop(self):
        print "wxstop for " + self.myname
        self.timer.stop()
        self.wxmovie.stop()

    def stop(self):
        try:
            self.timer.stop()
            self.timer = None
            if self.wxmovie:
                self.wxmovie.stop()
        except Exception:
            pass
示例#32
0
文件: main.py 项目: cgomez4/Selekti
 def updateMainImage(self, image):
     pixmap = QPixmap(image)
     if pixmap.width() == 0 or pixmap.width() > self.width() or pixmap.height() > self.height():
         QMessageBox.critical(self, "Uh oh!", "Could not display:\n {}".format(image))
     else:
         self.main_imageLabel.setPixmap(pixmap)
示例#33
0
文件: main.py 项目: cgomez4/Selekti
    def __init__(self, parent=None):
        super(Ui_Train, self).__init__(parent)

        self.setWindowTitle(("Train"))   
        self.setWindowState(QtCore.Qt.WindowMaximized)
        self.isTrainWindowShown = True
        self.importedFiles = ImageData(self.imgs, self.isTrainWindowShown)

        # Random images will be taken from imgs_unscored
        for imgPath in self.importedFiles.images:
            self.imgs_unscored.append({'imgPath': imgPath})
        
        # print("[INFO] imgs_unscored:")
        # print(json.dumps(self.imgs_unscored, indent=2))

        self.mainMenu = self.menuBar()

        # Actions which can be seen from the drop-down of each menu selection	
        self.instructionsAction = QtGui.QAction("&Instructions", self)	
        self.instructionsAction.triggered.connect(self.instructions_Button_clicked)	

        # Menu selections that show on the menubar on the Selekti screen	
        self.helpMenu = self.mainMenu.addMenu('&Help')	
        self.helpMenu.addAction(self.instructionsAction)

        self.rate_label = QtGui.QLabel(self)
        self.rate_label.setText("What do you think of this photo?")
        self.rate_label.setStyleSheet("QLabel { color: white; font: 18px; }")
        self.rate_label.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)

        star_empty = QPixmap("star_empty.png")
        star_filled = QPixmap("star_filled.png")
        star_size = star_empty.rect().size()

        stars = []

        # Make the stars
        self.star_1 = StarButton('', self)
        self.star_2 = StarButton('', self)
        self.star_3 = StarButton('', self)
        self.star_4 = StarButton('', self)
        self.star_5 = StarButton('', self)

        stars.append(self.star_1)
        stars.append(self.star_2)
        stars.append(self.star_3)
        stars.append(self.star_4)
        stars.append(self.star_5)

        # Ideally all this stuff would go into StarButton's constructor but I couldn't find out how to override it properly
        for btn in stars:
            btn.initStarList()
            btn.setIcon(QIcon(star_empty))
            btn.setDefaultIcon(QIcon(star_empty))
            btn.setOnHoverIcon(QIcon(star_filled))
            btn.setFixedSize(star_size)
            btn.setIconSize(QSize(50,50))
            btn.setStyleSheet("QPushButton { border: none; }")
            btn.setEnabled(True)

        # Clicking a star will rate the image with the level of the star
        self.star_1.clicked.connect(lambda: self.rate_Button_clicked(1))
        self.star_2.clicked.connect(lambda: self.rate_Button_clicked(2))
        self.star_3.clicked.connect(lambda: self.rate_Button_clicked(3))
        self.star_4.clicked.connect(lambda: self.rate_Button_clicked(4))
        self.star_5.clicked.connect(lambda: self.rate_Button_clicked(5))

        # when the current star is hovered over, all the stars to its left
        # should also be highlighted 
        self.star_2.addDependentStar(self.star_1)

        self.star_3.addDependentStar(self.star_1)
        self.star_3.addDependentStar(self.star_2)

        self.star_4.addDependentStar(self.star_1)
        self.star_4.addDependentStar(self.star_2)
        self.star_4.addDependentStar(self.star_3)

        self.star_5.addDependentStar(self.star_1)
        self.star_5.addDependentStar(self.star_2)
        self.star_5.addDependentStar(self.star_3)
        self.star_5.addDependentStar(self.star_4)


        self.finish_Button = QtGui.QPushButton('Finish', self)
        self.finish_Button.clicked.connect(self.finish_Button_clicked)

        self.train_imageLabel = QtGui.QLabel(self)
        self.train_imageLabel.setAlignment(QtCore.Qt.AlignCenter)

        # need to show the win before trying to access its size below
        self.show()

        # prevent window minimization
        self.setFixedSize(self.width(), self.height())

        self.rate_label.setGeometry(QtCore.QRect((self.width()*0.40), (self.height()*0.065), 400, 30))
        self.finish_Button.setGeometry(QtCore.QRect((self.width()*0.70), (self.height()*0.95), 100, 30))

        self.star_1.setGeometry(QtCore.QRect((self.width()*0.40), (self.height()*0.88), 97, 27))
        self.star_2.setGeometry(QtCore.QRect((self.width()*0.45), (self.height()*0.88), 97, 27))
        self.star_3.setGeometry(QtCore.QRect((self.width()*0.50), (self.height()*0.88), 97, 27))
        self.star_4.setGeometry(QtCore.QRect((self.width()*0.55), (self.height()*0.88), 97, 27))
        self.star_5.setGeometry(QtCore.QRect((self.width()*0.60), (self.height()*0.88), 97, 27))


        self.current_img = self.get_next_image(self.imgs_unscored)
        if  self.current_img == None:
            print("[INFO] No images to score.")
        else:
            # click on the train image
            pixmap = QPixmap(self.current_img['imgPath'])

            # sometimes the pixmap is null
            if pixmap.width() == 0 or pixmap.width() > self.width() or pixmap.height() > self.height():
                QMessageBox.critical(self, "Uh oh!", "Could not display:\n {}\n\nYou can still rate it by clicking on a star.".format(self.current_img['imgPath']))

            else:
                print("[INFO] displaying a pixmap")
                self.train_imageLabel.setPixmap(pixmap)
                self.train_imageLabel.setGeometry(QtCore.QRect((self.width()/2) - (pixmap.width()/2), (self.height()/2) - (pixmap.height()/2), pixmap.width(), pixmap.height()))

            self.train_imageLabel.setObjectName('train_imageLabel')
            self.train_imageLabel.mousePressEvent = self.train_image_clicked
            print("[INFO] Starting image was set.")

        # Feedback consists of the user's score for an image along with that image's feature vector
        # It's stored in a dictionary where the feat vectors are the keys and the scores are the values
        self.feedback_path = "feedback.cpickle"
        if os.path.isfile(self.feedback_path):
            feedback_file = open(self.feedback_path, "rb")
            self.feedback = pickle.load(feedback_file)
            # print("[INFO] feedback on OPEN: {}".format(self.feedback))
            feedback_file.close()
        else:
            self.feedback = {}
示例#34
0
文件: main.py 项目: cgomez4/Selekti
    def rate_Button_clicked(self, starNumber): 

        if self.current_img == None:
            print("[INFO] No image to rate.")
            return
        # Before this btn is clicked, the user has already chosen the score on the slider
        # Therefore we can remove the current img from the unscored list
        print("[INFO] Removing {} from imgs_unscored".format(self.current_img))
        self.imgs_unscored.remove(self.current_img)

        # Add the scored image to imgs_scored
        imgScored = {'imgPath': self.current_img['imgPath'],
                     'imgScore': starNumber }
        self.imgs_scored.append(imgScored)


        # Compute hash for the image to prevent duplicates 
        # If the user has already rated this image, the new score overwrites the old one
        dhasher = DHash()
        difference_hash = dhasher.encode_image(image_file = self.current_img['imgPath'])

        f_vec = self.model.getFeatureVector(self.current_img['imgPath'])  

        self.feedback[difference_hash] = (starNumber, f_vec)


        # print("[INFO] List of scored images:")
        # print(json.dumps(self.imgs_scored, indent=2))

        # Move on to next pic
        self.current_img = self.get_next_image(self.imgs_unscored)
        if  self.current_img == None:
            print("[INFO] No image to rate.")
            # TODO: Produce dialog informing user end of list acheived
        else:
            pixmap = QPixmap(self.current_img['imgPath'])
            self.train_imageLabel.setPixmap(pixmap)
            self.train_imageLabel.setGeometry(QtCore.QRect((self.width()/2) - (pixmap.width()/2), (self.height()/2) - (pixmap.height()/2), pixmap.width(), pixmap.height()))

            print("[INFO] RATE btn clicked. Next image should be visible.")
示例#35
0
 def _renderPixmaps(self):
     self._pixmaps=[]
     for i in range(self._steps+1):
         angle = int(i * 360.0 / self._steps)
         pixmap = QPixmap(self._resource)
         # if problem with loading png
         if pixmap.size().width()==0:
             self._pixmaps=None
             return
         rotate_matrix = QMatrix()
         rotate_matrix.rotate(angle)
         pixmap_rotated = pixmap.transformed(rotate_matrix)
         pixmap_moved = QPixmap(pixmap.size())
         pixmap_moved.fill(Qt.transparent)
         painter = QPainter()
         painter.begin(pixmap_moved)
         painter.drawPixmap((pixmap_moved.width() - pixmap_rotated.width()) / 2.0, (pixmap_moved.height() - pixmap_rotated.height()) / 2.0, pixmap_rotated)
         painter.end()
         self._pixmaps+=[pixmap_moved.scaled(self._width, self._height)]
示例#36
0
class VCSIndicator:
    " Holds an indicator properties "

    def __init__( self, configLine ):
        """ Config line looks as follows:
            id:::pathOrString:::ForegroundColor:::BackgroundColor:::Tooltip
            It comes from a config file or from a plugin
        """
        self.identifier = None
        self.pixmap = None
        self.text = None
        self.backgroundColor = None
        self.foregroundColor = None
        self.defaultTooltip = ""

        self.__parseConfigLine( configLine )
        return

    def __parseConfigLine( self, configLine ):
        " Fills the members "
        if type( configLine ) == tuple or type( configLine ) == list:
            # Came from a plugin
            self.__parsePluginProvidedTuple( configLine )
        else:
            # Came from a config file
            self.__parseConfigFileProvidedString( configLine )
        self.__scalePixmap()
        return

    def __setBrokenIndicator( self, msg ):
        " Sets the indicator to the broken state "
        self.text = BROKEN_INDICATOR
        self.backgroundColor = QColor( 0, 255, 255 )
        self.foregroundColor = QColor( 255, 0, 0 )
        self.defaultTooltip = msg
        return

    def __parseConfigFileProvidedString( self, configLine ):
        " Parses config file provided values "
        parts = configLine.split( ":::" )
        if len( parts ) != 5:
            raise Exception( "Unexpected format of an indicator "
                             "description. Expected 5 values." )
        # ID field
        self.identifier = int( parts[ 0 ] )

        # path or text field
        if os.path.isabs( parts[ 1 ] ):
            # That must be a path to the pixmap
            try:
                self.pixmap = QPixmap( parts[ 1 ] )
            except:
                self.__setBrokenIndicator( "Failed to load pixmap from " +
                                           parts[ 1 ] )
                return
        else:
            # Try to find the pixmap in the standard pixmap directory
            candidate = parts[ 1 ].strip()
            searchPath = os.path.dirname( os.path.abspath( sys.argv[0] ) ) + \
                         os.path.sep + 'pixmaps' + os.path.sep + candidate
            if candidate != "" and os.path.exists( searchPath ):
                try:
                    self.pixmap = QPixmap( searchPath )
                except:
                    self.__setBrokenIndicator( "Failed to load pixmap from " +
                                               parts[ 1 ] )
                    return
            else:
                # It is just a text. Cut it to up to 2 letters
                self.__setText( parts[ 1 ] )

        # Foreground color
        if parts[ 2 ].lower() == "none":
            self.foregroundColor = None
        else:
            self.foregroundColor = buildColor( parts[ 2 ] )

        # Background color
        if parts[ 3 ].lower() == "none":
            self.backgroundColor = None
        else:
            self.backgroundColor = buildColor( parts[ 3 ] )

        # Default tooltip
        if parts[ 4 ].lower() == "none":
            self.defaultTooltip = ""
        else:
            self.defaultTooltip = str( parts[ 4 ] ).strip()
        return

    def __parsePluginProvidedTuple( self, pluginIndicator ):
        " Checks what plugin provided "
        if len( pluginIndicator ) != 5:
            raise Exception( "Unexpected format of an indicator "
                             "description. Expected 5 values." )
        # ID field
        self.identifier = int( pluginIndicator[ 0 ] )

        # Pixmap/text field
        if type( pluginIndicator[ 1 ] ) == str:
            self.__setText( pluginIndicator[ 1 ] )
        else:
            try:
                self.pixmap = QPixmap( pluginIndicator[ 1 ] )
            except:
                self.__setBrokenIndicator( "Failed to get plugin indicator "
                                           "pixmap. Indicator id: " +
                                           str( self.identifier ) )
                return

        # Foreground color
        if pluginIndicator[ 2 ] is None:
            self.foregroundColor = None
        else:
            if type( pluginIndicator[ 2 ] ) == str:
                self.foregroundColor = buildColor( pluginIndicator[ 2 ] )
            else:
                self.foregroundColor = QColor( pluginIndicator[ 2 ] )

        # Background color
        if pluginIndicator[ 3 ] is None:
            self.backgroundColor = None
        else:
            if type( pluginIndicator[ 3 ] ) == str:
                self.backgroundColor = buildColor( pluginIndicator[ 3 ] )
            else:
                self.backgroundColor = QColor( pluginIndicator[ 3 ] )

        # Default tooltip
        if pluginIndicator[ 4 ] is None:
            self.defaultTooltip = ""
        else:
            self.defaultTooltip = str( pluginIndicator[ 4 ] ).strip()
        return

    def __setText( self, value ):
        " Sets the indicator text "
        if len( value ) > MAX_TEXT_INDICATOR_LENGTH:
            self.text = value[ : MAX_TEXT_INDICATOR_LENGTH ]
        else:
            self.text = value
        self.text = self.text.strip()
        return

    def __scalePixmap( self ):
        " Scales the pixmap if necessary "
        if self.pixmap is None:
            return

        if self.pixmap.width() > MAX_PIXMAP_INDICATOR_WIDTH or \
           self.pixmap.height() > MAX_PIXMAP_INDICATOR_HEIGHT:
            maxSize = QSize( MAX_PIXMAP_INDICATOR_WIDTH,
                             MAX_PIXMAP_INDICATOR_HEIGHT )
            self.pixmap = self.pixmap.scaled( maxSize, Qt.KeepAspectRatio )
        return

    def isPixmap( self ):
        " True if it is a pixmap label "
        return self.pixmap is not None

    def draw( self, label ):
        " Draws the indicator as members tell. label is QLabel "
        label.setPalette( QLabel().palette() )
        if self.isPixmap():
            label.setAutoFillBackground( False )
            label.setFrameStyle( QLabel().frameStyle() )
            label.setPixmap( self.pixmap )
        else:
            label.setFrameStyle( QFrame.StyledPanel )
            label.setAutoFillBackground( True )
            palette = label.palette()
            if self.backgroundColor is not None:
                palette.setColor( QPalette.Background, self.backgroundColor )
            if self.foregroundColor is not None:
                palette.setColor( QPalette.Foreground, self.foregroundColor )
            label.setPalette( palette )
            label.setText( self.text )
        return
示例#37
0
class Entity(QWidget):
    def __init__(self, base_image, parent=None):
        super().__init__(parent)
        self._base_label = QLabel(self)
        self._base_image = base_image

        self._decor_label = None
        self._decor_pixmap = None

        self.__pixmap = None
        """:type: PyQt4.QtGui.QPixmap"""

        self.__cord_x = 0
        self.__cord_y = 0
        self.__angle = 0
        self.setAlignment(Qt.AlignCenter)
        self.updatePixmap()

        if _debugging:
            self.setStyleSheet("border: 1px solid black")

    @property
    def angle(self):
        return self.__angle

    @angle.setter
    def angle(self, angle):
        self.__angle = angle
        self.updatePixmap()

    @property
    def cord_x(self):
        return self.__cord_x

    @cord_x.setter
    def cord_x(self, cord):
        self.__cord_x = cord
        self.move(self.cord_x, self.cord_y)

    @property
    def cord_y(self):
        return self.__cord_y

    @cord_y.setter
    def cord_y(self, cord):
        self.__cord_y = cord
        self.move(self.cord_x, self.cord_y)

    def add_decoration(self, path):
        if path is None:
            self._decor_label.deleteLater()
            self._decor_label = None
        else:
            self._decor_label = QLabel(self)
            self._decor_pixmap = QPixmap(path)
            self._decor_pixmap = self._decor_pixmap.scaled(
                self._decor_pixmap.width() * _SCALE,
                self._decor_pixmap.height() * _SCALE)
            self._decor_pixmap = self._decor_pixmap.transformed(
                QTransform().rotate(self.angle))
            self._decor_label.setPixmap(self._decor_pixmap)
            self._decor_label.setAlignment(Qt.AlignCenter)
            self._decor_label.show()

    def updatePixmap(self):
        path = _PATH + os.sep + "assets" + os.sep + self._base_image
        self.__pixmap = QPixmap(path)
        self.__pixmap = self.__pixmap.scaled(self.__pixmap.width() * _SCALE,
                                             self.__pixmap.height() * _SCALE)
        self.__pixmap = self.__pixmap.transformed(QTransform().rotate(
            self.angle))
        self._base_label.setPixmap(self.__pixmap)
        self.setFixedSize(self.__pixmap.width(), self.__pixmap.height())

    def setFixedSize(self, x, y):
        super().setFixedSize(x, y)
        self._base_label.setFixedSize(x, y)

    def setAlignment(self, alignment):
        self._base_label.setAlignment(alignment)
示例#38
0
class OWParallelGraph(OWPlot, ScaleData):
    show_distributions = Setting(False)
    show_attr_values = Setting(True)
    show_statistics = Setting(default=False)

    group_lines = Setting(default=False)
    number_of_groups = Setting(default=5)
    number_of_steps = Setting(default=30)

    use_splines = Setting(False)
    alpha_value = Setting(150)
    alpha_value_2 = Setting(150)

    def __init__(self, widget, parent=None, name=None):
        OWPlot.__init__(self, parent, name, axes=[], widget=widget)
        ScaleData.__init__(self)

        self.update_antialiasing(False)

        self.widget = widget
        self.last_selected_curve = None
        self.enableGridXB(0)
        self.enableGridYL(0)
        self.domain_contingencies = None
        self.auto_update_axes = 1
        self.old_legend_keys = []
        self.selection_conditions = {}
        self.attributes = []
        self.visualized_mid_labels = []
        self.attribute_indices = []
        self.valid_data = []
        self.groups = {}

        self.selected_examples = []
        self.unselected_examples = []
        self.bottom_pixmap = QPixmap(os.path.join(environ.widget_install_dir, "icons/upgreenarrow.png"))
        self.top_pixmap = QPixmap(os.path.join(environ.widget_install_dir, "icons/downgreenarrow.png"))

    def set_data(self, data, subset_data=None, **args):
        self.start_progress()
        self.set_progress(1, 100)
        self.data = data
        self.have_data = True
        self.domain_contingencies = None
        self.groups = {}
        OWPlot.setData(self, data)
        ScaleData.set_data(self, data, subset_data, no_data=True, **args)
        self.end_progress()


    def update_data(self, attributes, mid_labels=None):
        old_selection_conditions = self.selection_conditions

        self.clear()

        if not (self.have_data or self.have_subset_data):
            return
        if len(attributes) < 2:
            return

        if self.show_statistics:
            self.alpha_value = TRANSPARENT
            self.alpha_value_2 = VISIBLE
        else:
            self.alpha_value = VISIBLE
            self.alpha_value_2 = TRANSPARENT

        self.attributes = attributes
        self.attribute_indices = [self.attribute_name_index[name] for name in self.attributes]
        self.valid_data = self.get_valid_list(self.attribute_indices)

        self.visualized_mid_labels = mid_labels
        self.add_relevant_selections(old_selection_conditions)

        if self.data_has_discrete_class:
            self.discrete_palette.set_number_of_colors(len(self.data_domain.class_var.values))

        if self.group_lines:
            self.show_statistics = False
            self.draw_groups()
        else:
            self.show_statistics = False
            self.draw_curves()
        self.draw_distributions()
        self.draw_axes()
        self.draw_statistics()
        self.draw_mid_labels(mid_labels)
        self.draw_legend()

        self.replot()

    def add_relevant_selections(self, old_selection_conditions):
        """Keep only conditions related to the currently visualized attributes"""
        for name, value in old_selection_conditions.items():
            if name in self.attributes:
                self.selection_conditions[name] = value

    def draw_axes(self):
        self.remove_all_axes()
        for i in range(len(self.attributes)):
            axis_id = UserAxis + i
            a = self.add_axis(axis_id, line=QLineF(i, 0, i, 1), arrows=AxisStart | AxisEnd,
                              zoomable=True)
            a.always_horizontal_text = True
            a.max_text_width = 100
            a.title_margin = -10
            a.text_margin = 0
            a.setZValue(5)
            self.set_axis_title(axis_id, self.data_domain[self.attributes[i]].name)
            self.set_show_axis_title(axis_id, self.show_attr_values)
            if self.show_attr_values:
                attr = self.data_domain[self.attributes[i]]
                if isinstance(attr, ContinuousVariable):
                    self.set_axis_scale(axis_id, self.attr_values[attr.name][0], self.attr_values[attr.name][1])
                elif isinstance(attr, DiscreteVariable):
                    attribute_values = get_variable_values_sorted(self.data_domain[self.attributes[i]])
                    attr_len = len(attribute_values)
                    values = [float(1.0 + 2.0 * j) / float(2 * attr_len) for j in range(len(attribute_values))]
                    a.set_bounds((0, 1))
                    self.set_axis_labels(axis_id, labels=attribute_values, values=values)

    def draw_curves(self):
        conditions = {name: self.attributes.index(name) for name in self.selection_conditions.keys()}

        def is_selected(example):
            return all(self.selection_conditions[name][0] <= example[index] <= self.selection_conditions[name][1]
                       for (name, index) in list(conditions.items()))

        selected_curves = defaultdict(list)
        background_curves = defaultdict(list)

        diff, mins = [], []
        for i in self.attribute_indices:
            var = self.data_domain[i]
            if isinstance(var, DiscreteVariable):
                diff.append(len(var.values))
                mins.append(-0.5)
            else:
                diff.append(self.domain_data_stat[i].max - self.domain_data_stat[i].min or 1)
                mins.append(self.domain_data_stat[i].min)

        def scale_row(row):
            return [(x - m) / d for x, m, d in zip(row, mins, diff)]

        for row_idx, row in enumerate(self.data[:, self.attribute_indices]):
            if any(np.isnan(v) for v in row.x):
                continue

            color = self.select_color(row_idx)

            if is_selected(row):
                color += (self.alpha_value,)
                selected_curves[color].extend(scale_row(row))
                self.selected_examples.append(row_idx)
            else:
                color += (self.alpha_value_2,)
                background_curves[color].extend(row)
                self.unselected_examples.append(row_idx)

        self._draw_curves(selected_curves)
        self._draw_curves(background_curves)

    def select_color(self, row_index):
        if self.data_has_class:
            if self.data_has_continuous_class:
                return self.continuous_palette.getRGB(self.data[row_index, self.data_class_index])
            else:
                return self.discrete_palette.getRGB(self.data[row_index, self.data_class_index])
        else:
            return 0, 0, 0

    def _draw_curves(self, selected_curves):
        n_attr = len(self.attributes)
        for color, y_values in sorted(selected_curves.items()):
            n_rows = int(len(y_values) / n_attr)
            x_values = list(range(n_attr)) * n_rows
            curve = OWCurve()
            curve.set_style(OWCurve.Lines)
            curve.set_color(QColor(*color))
            curve.set_segment_length(n_attr)
            curve.set_data(x_values, y_values)
            curve.attach(self)

    def draw_groups(self):
        phis, mus, sigmas = self.compute_groups()

        diff, mins = [], []
        for i in self.attribute_indices:
            var = self.data_domain[i]
            if isinstance(var, DiscreteVariable):
                diff.append(len(var.values))
                mins.append(-0.5)
            else:
                diff.append(self.domain_data_stat[i].max - self.domain_data_stat[i].min or 1)
                mins.append(self.domain_data_stat[i].min)

        for j, (phi, cluster_mus, cluster_sigma) in enumerate(zip(phis, mus, sigmas)):
            for i, (mu1, sigma1, mu2, sigma2), in enumerate(
                    zip(cluster_mus, cluster_sigma, cluster_mus[1:], cluster_sigma[1:])):
                nmu1 = (mu1 - mins[i]) / diff[i]
                nmu2 = (mu2 - mins[i + 1]) / diff[i + 1]
                nsigma1 = math.sqrt(sigma1) / diff[i]
                nsigma2 = math.sqrt(sigma2) / diff[i + 1]

                polygon = ParallelCoordinatePolygon(i, nmu1, nmu2, nsigma1, nsigma2, phi,
                                                    self.discrete_palette.getRGB(j))
                polygon.attach(self)

        self.replot()

    def compute_groups(self):
        key = (tuple(self.attributes), self.number_of_groups, self.number_of_steps)
        if key not in self.groups:
            def callback(i, n):
                self.set_progress(i, 2*n)

            conts = create_contingencies(self.data[:, self.attribute_indices], callback=callback)
            self.set_progress(50, 100)
            w, mu, sigma, phi = lac(conts, self.number_of_groups, self.number_of_steps)
            self.set_progress(100, 100)
            self.groups[key] = map(np.nan_to_num, (phi, mu, sigma))
        return self.groups[key]

    def draw_legend(self):
        if self.data_has_class:
            if isinstance(self.data_domain.class_var, DiscreteVariable):
                self.legend().clear()
                values = get_variable_values_sorted(self.data_domain.class_var)
                for i, value in enumerate(values):
                    self.legend().add_item(self.data_domain.class_var.name, value,
                                           OWPoint(OWPoint.Rect, self.discrete_palette[i], self.point_width))
            else:
                values = self.attr_values[self.data_domain.class_var.name]
                decimals = self.data_domain.class_var.number_of_decimals
                self.legend().add_color_gradient(self.data_domain.class_var.name,
                                                 ["%%.%df" % decimals % v for v in values])
        else:
            self.legend().clear()
            self.old_legend_keys = []

    def draw_mid_labels(self, mid_labels):
        if mid_labels:
            for j in range(len(mid_labels)):
                self.addMarker(mid_labels[j], j + 0.5, 1.0, alignment=Qt.AlignCenter | Qt.AlignTop)

    def draw_statistics(self):
        """Draw lines that represent standard deviation or quartiles"""
        return # TODO: Implement using BasicStats
        if self.show_statistics and self.have_data:
            data = []
            for attr_idx in self.attribute_indices:
                if not isinstance(self.data_domain[attr_idx], ContinuousVariable):
                    data.append([()])
                    continue  # only for continuous attributes

                if not self.data_has_class or self.data_has_continuous_class:    # no class
                    if self.show_statistics == MEANS:
                        m = self.domain_data_stat[attr_idx].mean
                        dev = self.domain_data_stat[attr_idx].var
                        data.append([(m - dev, m, m + dev)])
                    elif self.show_statistics == MEDIAN:
                        data.append([(0, 0, 0)]); continue

                        sorted_array = np.sort(attr_values)
                        if len(sorted_array) > 0:
                            data.append([(sorted_array[int(len(sorted_array) / 4.0)],
                                          sorted_array[int(len(sorted_array) / 2.0)],
                                          sorted_array[int(len(sorted_array) * 0.75)])])
                        else:
                            data.append([(0, 0, 0)])
                else:
                    curr = []
                    class_values = get_variable_values_sorted(self.data_domain.class_var)

                    for c in range(len(class_values)):
                        attr_values = self.data[attr_idx, self.data[self.data_class_index] == c]
                        attr_values = attr_values[~np.isnan(attr_values)]

                        if len(attr_values) == 0:
                            curr.append((0, 0, 0))
                            continue
                        if self.show_statistics == MEANS:
                            m = attr_values.mean()
                            dev = attr_values.std()
                            curr.append((m - dev, m, m + dev))
                        elif self.show_statistics == MEDIAN:
                            sorted_array = np.sort(attr_values)
                            curr.append((sorted_array[int(len(attr_values) / 4.0)],
                                         sorted_array[int(len(attr_values) / 2.0)],
                                         sorted_array[int(len(attr_values) * 0.75)]))
                    data.append(curr)

            # draw vertical lines
            for i in range(len(data)):
                for c in range(len(data[i])):
                    if data[i][c] == ():
                        continue
                    x = i - 0.03 * (len(data[i]) - 1) / 2.0 + c * 0.03
                    col = QColor(self.discrete_palette[c])
                    col.setAlpha(self.alpha_value_2)
                    self.add_curve("", col, col, 3, OWCurve.Lines, OWPoint.NoSymbol, xData=[x, x, x],
                                   yData=[data[i][c][0], data[i][c][1], data[i][c][2]], lineWidth=4)
                    self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=[x - 0.03, x + 0.03],
                                   yData=[data[i][c][0], data[i][c][0]], lineWidth=4)
                    self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=[x - 0.03, x + 0.03],
                                   yData=[data[i][c][1], data[i][c][1]], lineWidth=4)
                    self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=[x - 0.03, x + 0.03],
                                   yData=[data[i][c][2], data[i][c][2]], lineWidth=4)

            # draw lines with mean/median values
            if not self.data_has_class or self.data_has_continuous_class:
                class_count = 1
            else:
                class_count = len(self.data_domain.class_var.values)
            for c in range(class_count):
                diff = - 0.03 * (class_count - 1) / 2.0 + c * 0.03
                ys = []
                xs = []
                for i in range(len(data)):
                    if data[i] != [()]:
                        ys.append(data[i][c][1])
                        xs.append(i + diff)
                    else:
                        if len(xs) > 1:
                            col = QColor(self.discrete_palette[c])
                            col.setAlpha(self.alpha_value_2)
                            self.add_curve("", col, col, 1, OWCurve.Lines,
                                           OWPoint.NoSymbol, xData=xs, yData=ys, lineWidth=4)
                        xs = []
                        ys = []
                col = QColor(self.discrete_palette[c])
                col.setAlpha(self.alpha_value_2)
                self.add_curve("", col, col, 1, OWCurve.Lines,
                               OWPoint.NoSymbol, xData=xs, yData=ys, lineWidth=4)

    def draw_distributions(self):
        """Draw distributions with discrete attributes"""
        if not (self.show_distributions and self.have_data and self.data_has_discrete_class):
            return
        class_count = len(self.data_domain.class_var.values)
        class_ = self.data_domain.class_var

        # we create a hash table of possible class values (happens only if we have a discrete class)
        if self.domain_contingencies is None:
            self.domain_contingencies = dict(
                zip([attr for attr in self.data_domain if isinstance(attr, DiscreteVariable)],
                    get_contingencies(self.raw_data, skipContinuous=True)))
            self.domain_contingencies[class_] = get_contingency(self.raw_data, class_, class_)

        max_count = max([contingency.max() for contingency in self.domain_contingencies.values()] or [1])
        sorted_class_values = get_variable_values_sorted(self.data_domain.class_var)

        for axis_idx, attr_idx in enumerate(self.attribute_indices):
            attr = self.data_domain[attr_idx]
            if isinstance(attr, DiscreteVariable):
                continue

            contingency = self.domain_contingencies[attr]
            attr_len = len(attr.values)

            # we create a hash table of variable values and their indices
            sorted_variable_values = get_variable_values_sorted(attr)

            # create bar curve
            for j in range(attr_len):
                attribute_value = sorted_variable_values[j]
                value_count = contingency[:, attribute_value]

                for i in range(class_count):
                    class_value = sorted_class_values[i]

                    color = QColor(self.discrete_palette[i])
                    color.setAlpha(self.alpha_value)

                    width = float(value_count[class_value] * 0.5) / float(max_count)
                    y_off = float(1.0 + 2.0 * j) / float(2 * attr_len)
                    height = 0.7 / float(class_count * attr_len)

                    y_low_bottom = y_off + float(class_count * height) / 2.0 - i * height
                    curve = PolygonCurve(QPen(color),
                                         QBrush(color),
                                         xData=[axis_idx, axis_idx + width,
                                                axis_idx + width, axis_idx],
                                         yData=[y_low_bottom, y_low_bottom, y_low_bottom - height,
                                                y_low_bottom - height],
                                         tooltip=attr.name)
                    curve.attach(self)

    # handle tooltip events
    def event(self, ev):
        if ev.type() == QEvent.ToolTip:
            x = self.inv_transform(xBottom, ev.pos().x())
            y = self.inv_transform(yLeft, ev.pos().y())

            canvas_position = self.mapToScene(ev.pos())
            x_float = self.inv_transform(xBottom, canvas_position.x())
            contact, (index, pos) = self.testArrowContact(int(round(x_float)), canvas_position.x(),
                                                          canvas_position.y())
            if contact:
                attr = self.data_domain[self.attributes[index]]
                if isinstance(attr, ContinuousVariable):
                    condition = self.selection_conditions.get(attr.name, [0, 1])
                    val = self.attr_values[attr.name][0] + condition[pos] * (
                        self.attr_values[attr.name][1] - self.attr_values[attr.name][0])
                    str_val = attr.name + "= %%.%df" % attr.number_of_decimals % val
                    QToolTip.showText(ev.globalPos(), str_val)
            else:
                for curve in self.items():
                    if type(curve) == PolygonCurve and \
                            curve.boundingRect().contains(x, y) and \
                            getattr(curve, "tooltip", None):
                        (name, value, total, dist) = curve.tooltip
                        count = sum([v[1] for v in dist])
                        if count == 0:
                            continue
                        tooltip_text = "Attribute: <b>%s</b><br>Value: <b>%s</b><br>" \
                                       "Total instances: <b>%i</b> (%.1f%%)<br>" \
                                       "Class distribution:<br>" % (
                                           name, value, count, 100.0 * count / float(total))
                        for (val, n) in dist:
                            tooltip_text += "&nbsp; &nbsp; <b>%s</b> : <b>%i</b> (%.1f%%)<br>" % (
                                val, n, 100.0 * float(n) / float(count))
                        QToolTip.showText(ev.globalPos(), tooltip_text[:-4])

        elif ev.type() == QEvent.MouseMove:
            QToolTip.hideText()

        return OWPlot.event(self, ev)

    def testArrowContact(self, indices, x, y):
        if type(indices) != list: indices = [indices]
        for index in indices:
            if index >= len(self.attributes) or index < 0:
                continue
            int_x = self.transform(xBottom, index)
            bottom = self.transform(yLeft,
                                    self.selection_conditions.get(self.attributes[index], [0, 1])[0])
            bottom_rect = QRect(int_x - self.bottom_pixmap.width() / 2, bottom, self.bottom_pixmap.width(),
                                self.bottom_pixmap.height())
            if bottom_rect.contains(QPoint(x, y)):
                return 1, (index, 0)
            top = self.transform(yLeft,
                                 self.selection_conditions.get(self.attributes[index], [0, 1])[1])
            top_rect = QRect(int_x - self.top_pixmap.width() / 2, top - self.top_pixmap.height(),
                             self.top_pixmap.width(),
                             self.top_pixmap.height())
            if top_rect.contains(QPoint(x, y)):
                return 1, (index, 1)
        return 0, (0, 0)

    def mousePressEvent(self, e):
        canvas_position = self.mapToScene(e.pos())
        x = self.inv_transform(xBottom, canvas_position.x())
        contact, info = self.testArrowContact(int(round(x)), canvas_position.x(), canvas_position.y())

        if contact:
            self.pressed_arrow = info
        else:
            OWPlot.mousePressEvent(self, e)

    def mouseMoveEvent(self, e):
        if hasattr(self, "pressed_arrow"):
            canvas_position = self.mapToScene(e.pos())
            y = min(1, max(0, self.inv_transform(yLeft, canvas_position.y())))
            index, pos = self.pressed_arrow
            attr = self.data_domain[self.attributes[index]]
            old_condition = self.selection_conditions.get(attr.name, [0, 1])
            old_condition[pos] = y
            self.selection_conditions[attr.name] = old_condition
            self.update_data(self.attributes, self.visualized_mid_labels)

            if isinstance(attr, ContinuousVariable):
                val = self.attr_values[attr.name][0] + old_condition[pos] * (
                    self.attr_values[attr.name][1] - self.attr_values[attr.name][0])
                strVal = attr.name + "= %.2f" % val
                QToolTip.showText(e.globalPos(), strVal)
            if self.sendSelectionOnUpdate and self.auto_send_selection_callback:
                self.auto_send_selection_callback()

        else:
            OWPlot.mouseMoveEvent(self, e)

    def mouseReleaseEvent(self, e):
        if hasattr(self, "pressed_arrow"):
            del self.pressed_arrow
        else:
            OWPlot.mouseReleaseEvent(self, e)

    def zoom_to_rect(self, r):
        r.setTop(self.graph_area.top())
        r.setBottom(self.graph_area.bottom())
        super().zoom_to_rect(r)

    def removeAllSelections(self, send=1):
        self.selection_conditions = {}
        self.update_data(self.attributes, self.visualized_mid_labels)

    # draw the curves and the selection conditions
    def drawCanvas(self, painter):
        OWPlot.drawCanvas(self, painter)
        for i in range(
                int(max(0, math.floor(self.axisScaleDiv(xBottom).interval().minValue()))),
                int(min(len(self.attributes),
                        math.ceil(self.axisScaleDiv(xBottom).interval().maxValue()) + 1))):
            bottom, top = self.selection_conditions.get(self.attributes[i], (0, 1))
            painter.drawPixmap(self.transform(xBottom, i) - self.bottom_pixmap.width() / 2,
                               self.transform(yLeft, bottom), self.bottom_pixmap)
            painter.drawPixmap(self.transform(xBottom, i) - self.top_pixmap.width() / 2,
                               self.transform(yLeft, top) - self.top_pixmap.height(), self.top_pixmap)

    def auto_send_selection_callback(self):
        pass

    def clear(self):
        super().clear()

        self.attributes = []
        self.visualized_mid_labels = []
        self.selected_examples = []
        self.unselected_examples = []
        self.selection_conditions = {}
示例#39
0
class OWParallelGraph(OWPlot, ScaleData):
    show_distributions = Setting(False)
    show_attr_values = Setting(True)
    show_statistics = Setting(default=False)

    group_lines = Setting(default=False)
    number_of_groups = Setting(default=5)
    number_of_steps = Setting(default=30)

    use_splines = Setting(False)
    alpha_value = Setting(150)
    alpha_value_2 = Setting(150)

    def __init__(self, widget, parent=None, name=None):
        OWPlot.__init__(self, parent, name, axes=[], widget=widget)
        ScaleData.__init__(self)

        self.update_antialiasing(False)

        self.widget = widget
        self.last_selected_curve = None
        self.enableGridXB(0)
        self.enableGridYL(0)
        self.domain_contingencies = None
        self.auto_update_axes = 1
        self.old_legend_keys = []
        self.selection_conditions = {}
        self.attributes = []
        self.visualized_mid_labels = []
        self.attribute_indices = []
        self.valid_data = []
        self.groups = {}

        self.selected_examples = []
        self.unselected_examples = []
        self.bottom_pixmap = QPixmap(
            os.path.join(environ.widget_install_dir, "icons/upgreenarrow.png"))
        self.top_pixmap = QPixmap(
            os.path.join(environ.widget_install_dir,
                         "icons/downgreenarrow.png"))

    def set_data(self, data, subset_data=None, **args):
        self.start_progress()
        self.set_progress(1, 100)
        self.data = data
        self.have_data = True
        self.domain_contingencies = None
        self.groups = {}
        OWPlot.setData(self, data)
        ScaleData.set_data(self, data, subset_data, no_data=True, **args)
        self.end_progress()

    def update_data(self, attributes, mid_labels=None):
        old_selection_conditions = self.selection_conditions

        self.clear()

        if not (self.have_data or self.have_subset_data):
            return
        if len(attributes) < 2:
            return

        if self.show_statistics:
            self.alpha_value = TRANSPARENT
            self.alpha_value_2 = VISIBLE
        else:
            self.alpha_value = VISIBLE
            self.alpha_value_2 = TRANSPARENT

        self.attributes = attributes
        self.attribute_indices = [
            self.attribute_name_index[name] for name in self.attributes
        ]
        self.valid_data = self.get_valid_list(self.attribute_indices)

        self.visualized_mid_labels = mid_labels
        self.add_relevant_selections(old_selection_conditions)

        if self.data_has_discrete_class:
            self.discrete_palette.set_number_of_colors(
                len(self.data_domain.class_var.values))

        if self.group_lines:
            self.show_statistics = False
            self.draw_groups()
        else:
            self.show_statistics = False
            self.draw_curves()
        self.draw_distributions()
        self.draw_axes()
        self.draw_statistics()
        self.draw_mid_labels(mid_labels)
        self.draw_legend()

        self.replot()

    def add_relevant_selections(self, old_selection_conditions):
        """Keep only conditions related to the currently visualized attributes"""
        for name, value in old_selection_conditions.items():
            if name in self.attributes:
                self.selection_conditions[name] = value

    def draw_axes(self):
        self.remove_all_axes()
        for i in range(len(self.attributes)):
            axis_id = UserAxis + i
            a = self.add_axis(axis_id,
                              line=QLineF(i, 0, i, 1),
                              arrows=AxisStart | AxisEnd,
                              zoomable=True)
            a.always_horizontal_text = True
            a.max_text_width = 100
            a.title_margin = -10
            a.text_margin = 0
            a.setZValue(5)
            self.set_axis_title(axis_id,
                                self.data_domain[self.attributes[i]].name)
            self.set_show_axis_title(axis_id, self.show_attr_values)
            if self.show_attr_values:
                attr = self.data_domain[self.attributes[i]]
                if isinstance(attr, ContinuousVariable):
                    self.set_axis_scale(axis_id,
                                        self.attr_values[attr.name][0],
                                        self.attr_values[attr.name][1])
                elif isinstance(attr, DiscreteVariable):
                    attribute_values = get_variable_values_sorted(
                        self.data_domain[self.attributes[i]])
                    attr_len = len(attribute_values)
                    values = [
                        float(1.0 + 2.0 * j) / float(2 * attr_len)
                        for j in range(len(attribute_values))
                    ]
                    a.set_bounds((0, 1))
                    self.set_axis_labels(axis_id,
                                         labels=attribute_values,
                                         values=values)

    def draw_curves(self):
        conditions = {
            name: self.attributes.index(name)
            for name in self.selection_conditions.keys()
        }

        def is_selected(example):
            return all(self.selection_conditions[name][0] <= example[index] <=
                       self.selection_conditions[name][1]
                       for (name, index) in list(conditions.items()))

        selected_curves = defaultdict(list)
        background_curves = defaultdict(list)

        diff, mins = [], []
        for i in self.attribute_indices:
            var = self.data_domain[i]
            if isinstance(var, DiscreteVariable):
                diff.append(len(var.values))
                mins.append(-0.5)
            else:
                diff.append(
                    self.domain_data_stat[i].max - self.domain_data_stat[i].min
                    or 1)
                mins.append(self.domain_data_stat[i].min)

        def scale_row(row):
            return [(x - m) / d for x, m, d in zip(row, mins, diff)]

        for row_idx, row in enumerate(self.data[:, self.attribute_indices]):
            if any(np.isnan(v) for v in row.x):
                continue

            color = self.select_color(row_idx)

            if is_selected(row):
                color += (self.alpha_value, )
                selected_curves[color].extend(scale_row(row))
                self.selected_examples.append(row_idx)
            else:
                color += (self.alpha_value_2, )
                background_curves[color].extend(row)
                self.unselected_examples.append(row_idx)

        self._draw_curves(selected_curves)
        self._draw_curves(background_curves)

    def select_color(self, row_index):
        if self.data_has_class:
            if self.data_has_continuous_class:
                return self.continuous_palette.getRGB(
                    self.data[row_index, self.data_class_index])
            else:
                return self.discrete_palette.getRGB(
                    self.data[row_index, self.data_class_index])
        else:
            return 0, 0, 0

    def _draw_curves(self, selected_curves):
        n_attr = len(self.attributes)
        for color, y_values in sorted(selected_curves.items()):
            n_rows = int(len(y_values) / n_attr)
            x_values = list(range(n_attr)) * n_rows
            curve = OWCurve()
            curve.set_style(OWCurve.Lines)
            curve.set_color(QColor(*color))
            curve.set_segment_length(n_attr)
            curve.set_data(x_values, y_values)
            curve.attach(self)

    def draw_groups(self):
        phis, mus, sigmas = self.compute_groups()

        diff, mins = [], []
        for i in self.attribute_indices:
            var = self.data_domain[i]
            if isinstance(var, DiscreteVariable):
                diff.append(len(var.values))
                mins.append(-0.5)
            else:
                diff.append(
                    self.domain_data_stat[i].max - self.domain_data_stat[i].min
                    or 1)
                mins.append(self.domain_data_stat[i].min)

        for j, (phi, cluster_mus,
                cluster_sigma) in enumerate(zip(phis, mus, sigmas)):
            for i, (mu1, sigma1, mu2, sigma2), in enumerate(
                    zip(cluster_mus, cluster_sigma, cluster_mus[1:],
                        cluster_sigma[1:])):
                nmu1 = (mu1 - mins[i]) / diff[i]
                nmu2 = (mu2 - mins[i + 1]) / diff[i + 1]
                nsigma1 = math.sqrt(sigma1) / diff[i]
                nsigma2 = math.sqrt(sigma2) / diff[i + 1]

                polygon = ParallelCoordinatePolygon(
                    i, nmu1, nmu2, nsigma1, nsigma2, phi,
                    self.discrete_palette.getRGB(j))
                polygon.attach(self)

        self.replot()

    def compute_groups(self):
        key = (tuple(self.attributes), self.number_of_groups,
               self.number_of_steps)
        if key not in self.groups:

            def callback(i, n):
                self.set_progress(i, 2 * n)

            conts = create_contingencies(self.data[:, self.attribute_indices],
                                         callback=callback)
            self.set_progress(50, 100)
            w, mu, sigma, phi = lac(conts, self.number_of_groups,
                                    self.number_of_steps)
            self.set_progress(100, 100)
            self.groups[key] = map(np.nan_to_num, (phi, mu, sigma))
        return self.groups[key]

    def draw_legend(self):
        if self.data_has_class:
            if isinstance(self.data_domain.class_var, DiscreteVariable):
                self.legend().clear()
                values = get_variable_values_sorted(self.data_domain.class_var)
                for i, value in enumerate(values):
                    self.legend().add_item(
                        self.data_domain.class_var.name, value,
                        OWPoint(OWPoint.Rect, self.discrete_palette[i],
                                self.point_width))
            else:
                values = self.attr_values[self.data_domain.class_var.name]
                decimals = self.data_domain.class_var.number_of_decimals
                self.legend().add_color_gradient(
                    self.data_domain.class_var.name,
                    ["%%.%df" % decimals % v for v in values])
        else:
            self.legend().clear()
            self.old_legend_keys = []

    def draw_mid_labels(self, mid_labels):
        if mid_labels:
            for j in range(len(mid_labels)):
                self.addMarker(mid_labels[j],
                               j + 0.5,
                               1.0,
                               alignment=Qt.AlignCenter | Qt.AlignTop)

    def draw_statistics(self):
        """Draw lines that represent standard deviation or quartiles"""
        return  # TODO: Implement using BasicStats
        if self.show_statistics and self.have_data:
            data = []
            for attr_idx in self.attribute_indices:
                if not isinstance(self.data_domain[attr_idx],
                                  ContinuousVariable):
                    data.append([()])
                    continue  # only for continuous attributes

                if not self.data_has_class or self.data_has_continuous_class:  # no class
                    if self.show_statistics == MEANS:
                        m = self.domain_data_stat[attr_idx].mean
                        dev = self.domain_data_stat[attr_idx].var
                        data.append([(m - dev, m, m + dev)])
                    elif self.show_statistics == MEDIAN:
                        data.append([(0, 0, 0)])
                        continue

                        sorted_array = np.sort(attr_values)
                        if len(sorted_array) > 0:
                            data.append([
                                (sorted_array[int(len(sorted_array) / 4.0)],
                                 sorted_array[int(len(sorted_array) / 2.0)],
                                 sorted_array[int(len(sorted_array) * 0.75)])
                            ])
                        else:
                            data.append([(0, 0, 0)])
                else:
                    curr = []
                    class_values = get_variable_values_sorted(
                        self.data_domain.class_var)

                    for c in range(len(class_values)):
                        attr_values = self.data[
                            attr_idx, self.data[self.data_class_index] == c]
                        attr_values = attr_values[~np.isnan(attr_values)]

                        if len(attr_values) == 0:
                            curr.append((0, 0, 0))
                            continue
                        if self.show_statistics == MEANS:
                            m = attr_values.mean()
                            dev = attr_values.std()
                            curr.append((m - dev, m, m + dev))
                        elif self.show_statistics == MEDIAN:
                            sorted_array = np.sort(attr_values)
                            curr.append(
                                (sorted_array[int(len(attr_values) / 4.0)],
                                 sorted_array[int(len(attr_values) / 2.0)],
                                 sorted_array[int(len(attr_values) * 0.75)]))
                    data.append(curr)

            # draw vertical lines
            for i in range(len(data)):
                for c in range(len(data[i])):
                    if data[i][c] == ():
                        continue
                    x = i - 0.03 * (len(data[i]) - 1) / 2.0 + c * 0.03
                    col = QColor(self.discrete_palette[c])
                    col.setAlpha(self.alpha_value_2)
                    self.add_curve(
                        "",
                        col,
                        col,
                        3,
                        OWCurve.Lines,
                        OWPoint.NoSymbol,
                        xData=[x, x, x],
                        yData=[data[i][c][0], data[i][c][1], data[i][c][2]],
                        lineWidth=4)
                    self.add_curve("",
                                   col,
                                   col,
                                   1,
                                   OWCurve.Lines,
                                   OWPoint.NoSymbol,
                                   xData=[x - 0.03, x + 0.03],
                                   yData=[data[i][c][0], data[i][c][0]],
                                   lineWidth=4)
                    self.add_curve("",
                                   col,
                                   col,
                                   1,
                                   OWCurve.Lines,
                                   OWPoint.NoSymbol,
                                   xData=[x - 0.03, x + 0.03],
                                   yData=[data[i][c][1], data[i][c][1]],
                                   lineWidth=4)
                    self.add_curve("",
                                   col,
                                   col,
                                   1,
                                   OWCurve.Lines,
                                   OWPoint.NoSymbol,
                                   xData=[x - 0.03, x + 0.03],
                                   yData=[data[i][c][2], data[i][c][2]],
                                   lineWidth=4)

            # draw lines with mean/median values
            if not self.data_has_class or self.data_has_continuous_class:
                class_count = 1
            else:
                class_count = len(self.data_domain.class_var.values)
            for c in range(class_count):
                diff = -0.03 * (class_count - 1) / 2.0 + c * 0.03
                ys = []
                xs = []
                for i in range(len(data)):
                    if data[i] != [()]:
                        ys.append(data[i][c][1])
                        xs.append(i + diff)
                    else:
                        if len(xs) > 1:
                            col = QColor(self.discrete_palette[c])
                            col.setAlpha(self.alpha_value_2)
                            self.add_curve("",
                                           col,
                                           col,
                                           1,
                                           OWCurve.Lines,
                                           OWPoint.NoSymbol,
                                           xData=xs,
                                           yData=ys,
                                           lineWidth=4)
                        xs = []
                        ys = []
                col = QColor(self.discrete_palette[c])
                col.setAlpha(self.alpha_value_2)
                self.add_curve("",
                               col,
                               col,
                               1,
                               OWCurve.Lines,
                               OWPoint.NoSymbol,
                               xData=xs,
                               yData=ys,
                               lineWidth=4)

    def draw_distributions(self):
        """Draw distributions with discrete attributes"""
        if not (self.show_distributions and self.have_data
                and self.data_has_discrete_class):
            return
        class_count = len(self.data_domain.class_var.values)
        class_ = self.data_domain.class_var

        # we create a hash table of possible class values (happens only if we have a discrete class)
        if self.domain_contingencies is None:
            self.domain_contingencies = dict(
                zip([
                    attr for attr in self.data_domain
                    if isinstance(attr, DiscreteVariable)
                ], get_contingencies(self.raw_data, skipContinuous=True)))
            self.domain_contingencies[class_] = get_contingency(
                self.raw_data, class_, class_)

        max_count = max([
            contingency.max()
            for contingency in self.domain_contingencies.values()
        ] or [1])
        sorted_class_values = get_variable_values_sorted(
            self.data_domain.class_var)

        for axis_idx, attr_idx in enumerate(self.attribute_indices):
            attr = self.data_domain[attr_idx]
            if isinstance(attr, DiscreteVariable):
                continue

            contingency = self.domain_contingencies[attr]
            attr_len = len(attr.values)

            # we create a hash table of variable values and their indices
            sorted_variable_values = get_variable_values_sorted(attr)

            # create bar curve
            for j in range(attr_len):
                attribute_value = sorted_variable_values[j]
                value_count = contingency[:, attribute_value]

                for i in range(class_count):
                    class_value = sorted_class_values[i]

                    color = QColor(self.discrete_palette[i])
                    color.setAlpha(self.alpha_value)

                    width = float(
                        value_count[class_value] * 0.5) / float(max_count)
                    y_off = float(1.0 + 2.0 * j) / float(2 * attr_len)
                    height = 0.7 / float(class_count * attr_len)

                    y_low_bottom = y_off + float(
                        class_count * height) / 2.0 - i * height
                    curve = PolygonCurve(QPen(color),
                                         QBrush(color),
                                         xData=[
                                             axis_idx, axis_idx + width,
                                             axis_idx + width, axis_idx
                                         ],
                                         yData=[
                                             y_low_bottom, y_low_bottom,
                                             y_low_bottom - height,
                                             y_low_bottom - height
                                         ],
                                         tooltip=attr.name)
                    curve.attach(self)

    # handle tooltip events
    def event(self, ev):
        if ev.type() == QEvent.ToolTip:
            x = self.inv_transform(xBottom, ev.pos().x())
            y = self.inv_transform(yLeft, ev.pos().y())

            canvas_position = self.mapToScene(ev.pos())
            x_float = self.inv_transform(xBottom, canvas_position.x())
            contact, (index,
                      pos) = self.testArrowContact(int(round(x_float)),
                                                   canvas_position.x(),
                                                   canvas_position.y())
            if contact:
                attr = self.data_domain[self.attributes[index]]
                if isinstance(attr, ContinuousVariable):
                    condition = self.selection_conditions.get(
                        attr.name, [0, 1])
                    val = self.attr_values[attr.name][0] + condition[pos] * (
                        self.attr_values[attr.name][1] -
                        self.attr_values[attr.name][0])
                    str_val = attr.name + "= %%.%df" % attr.number_of_decimals % val
                    QToolTip.showText(ev.globalPos(), str_val)
            else:
                for curve in self.items():
                    if type(curve) == PolygonCurve and \
                            curve.boundingRect().contains(x, y) and \
                            getattr(curve, "tooltip", None):
                        (name, value, total, dist) = curve.tooltip
                        count = sum([v[1] for v in dist])
                        if count == 0:
                            continue
                        tooltip_text = "Attribute: <b>%s</b><br>Value: <b>%s</b><br>" \
                                       "Total instances: <b>%i</b> (%.1f%%)<br>" \
                                       "Class distribution:<br>" % (
                                           name, value, count, 100.0 * count / float(total))
                        for (val, n) in dist:
                            tooltip_text += "&nbsp; &nbsp; <b>%s</b> : <b>%i</b> (%.1f%%)<br>" % (
                                val, n, 100.0 * float(n) / float(count))
                        QToolTip.showText(ev.globalPos(), tooltip_text[:-4])

        elif ev.type() == QEvent.MouseMove:
            QToolTip.hideText()

        return OWPlot.event(self, ev)

    def testArrowContact(self, indices, x, y):
        if type(indices) != list: indices = [indices]
        for index in indices:
            if index >= len(self.attributes) or index < 0:
                continue
            int_x = self.transform(xBottom, index)
            bottom = self.transform(
                yLeft,
                self.selection_conditions.get(self.attributes[index],
                                              [0, 1])[0])
            bottom_rect = QRect(int_x - self.bottom_pixmap.width() / 2, bottom,
                                self.bottom_pixmap.width(),
                                self.bottom_pixmap.height())
            if bottom_rect.contains(QPoint(x, y)):
                return 1, (index, 0)
            top = self.transform(
                yLeft,
                self.selection_conditions.get(self.attributes[index],
                                              [0, 1])[1])
            top_rect = QRect(int_x - self.top_pixmap.width() / 2,
                             top - self.top_pixmap.height(),
                             self.top_pixmap.width(), self.top_pixmap.height())
            if top_rect.contains(QPoint(x, y)):
                return 1, (index, 1)
        return 0, (0, 0)

    def mousePressEvent(self, e):
        canvas_position = self.mapToScene(e.pos())
        x = self.inv_transform(xBottom, canvas_position.x())
        contact, info = self.testArrowContact(int(round(x)),
                                              canvas_position.x(),
                                              canvas_position.y())

        if contact:
            self.pressed_arrow = info
        else:
            OWPlot.mousePressEvent(self, e)

    def mouseMoveEvent(self, e):
        if hasattr(self, "pressed_arrow"):
            canvas_position = self.mapToScene(e.pos())
            y = min(1, max(0, self.inv_transform(yLeft, canvas_position.y())))
            index, pos = self.pressed_arrow
            attr = self.data_domain[self.attributes[index]]
            old_condition = self.selection_conditions.get(attr.name, [0, 1])
            old_condition[pos] = y
            self.selection_conditions[attr.name] = old_condition
            self.update_data(self.attributes, self.visualized_mid_labels)

            if isinstance(attr, ContinuousVariable):
                val = self.attr_values[attr.name][0] + old_condition[pos] * (
                    self.attr_values[attr.name][1] -
                    self.attr_values[attr.name][0])
                strVal = attr.name + "= %.2f" % val
                QToolTip.showText(e.globalPos(), strVal)
            if self.sendSelectionOnUpdate and self.auto_send_selection_callback:
                self.auto_send_selection_callback()

        else:
            OWPlot.mouseMoveEvent(self, e)

    def mouseReleaseEvent(self, e):
        if hasattr(self, "pressed_arrow"):
            del self.pressed_arrow
        else:
            OWPlot.mouseReleaseEvent(self, e)

    def zoom_to_rect(self, r):
        r.setTop(self.graph_area.top())
        r.setBottom(self.graph_area.bottom())
        super().zoom_to_rect(r)

    def removeAllSelections(self, send=1):
        self.selection_conditions = {}
        self.update_data(self.attributes, self.visualized_mid_labels)

    # draw the curves and the selection conditions
    def drawCanvas(self, painter):
        OWPlot.drawCanvas(self, painter)
        for i in range(
                int(
                    max(
                        0,
                        math.floor(
                            self.axisScaleDiv(
                                xBottom).interval().minValue()))),
                int(
                    min(
                        len(self.attributes),
                        math.ceil(
                            self.axisScaleDiv(xBottom).interval().maxValue()) +
                        1))):
            bottom, top = self.selection_conditions.get(
                self.attributes[i], (0, 1))
            painter.drawPixmap(
                self.transform(xBottom, i) - self.bottom_pixmap.width() / 2,
                self.transform(yLeft, bottom), self.bottom_pixmap)
            painter.drawPixmap(
                self.transform(xBottom, i) - self.top_pixmap.width() / 2,
                self.transform(yLeft, top) - self.top_pixmap.height(),
                self.top_pixmap)

    def auto_send_selection_callback(self):
        pass

    def clear(self):
        super().clear()

        self.attributes = []
        self.visualized_mid_labels = []
        self.selected_examples = []
        self.unselected_examples = []
        self.selection_conditions = {}