예제 #1
0
파일: imageviewer.py 프로젝트: vertrex/DFF
 def mouseReleaseEvent(self, event):
     if not self.rubberBand.size().isEmpty():
         rect = QRect(self.rubberBand.pos(), self.rubberBand.size())
         rect.moveLeft(rect.left() -
                       (self.width() - self.pixmap().width()) / 2.0)
         rect.moveTop(rect.top() -
                      (self.height() - self.pixmap().height()) / 2.0)
         self.currentSelection = rect
         self.copySelectionMenu.popup(QCursor.pos())
     else:
         self.copyMenu.popup(QCursor.pos())
     self.rubberBand.hide()
예제 #2
0
    def __init__(self, url):
        QWidget.__init__(self, None, Qt.ToolTip)
        self.url = url
        
        self.font = QFont(QApplication.font(self))
        self.font.setPointSize(8)
        
        desktop = QApplication.desktop().availableGeometry(self)
        cursor = QCursor.pos()
        rect = QRect(cursor + QPoint(-10, 10), QSize(240,180 + QFontMetrics(self.font).height()))
        if rect.left() < desktop.left():
            rect.moveLeft(desktop.left())
        if rect.right() > desktop.right():
            rect.moveRight(cursor.x() - 10)
        if rect.bottom() > desktop.bottom():
            rect.moveBottom(cursor.y() - 10)
        self.setGeometry(rect)
        
        self.pixmap = None
        self.progress = 0
        self.title = unicode(self.url)

        self.webView = QWebView()
        self.webView.page().mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self.webView.page().mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff)
        self.webView.resize(1024,768)
        self.webView.load(QUrl(url))
        
        self.timer = QTimer(self)
        self.connect(self.timer, SIGNAL("timeout()"), self.refresh)
        self.timer.start(3000)
        
        self.connect(self.webView, SIGNAL("loadFinished(bool)"), self.refresh)
        self.connect(self.webView, SIGNAL("loadProgress(int)"), self.updateProgress)
        self.connect(self.webView, SIGNAL("urlChanged(const QUrl&)"), self.newUrl)
        self.connect(self.webView, SIGNAL("titleChanged(const QString&)"), self.newTitle)
예제 #3
0
    def paint(self, painter, option, index):
        """
		Draws the widget

		Arguments:
		painter -- a QPainter
		option -- a QStyleOptionView
		index -- a QModelIndex
		"""

        # Retrieve the data
        model = index.model()
        record = model.data(index)
        text = record.toString()
        zoteroItem = zoteroCache[unicode(text)]
        l = zoteroItem.full_format().split(u"\n")
        if zoteroItem.fulltext == None:
            pixmap = self.noPdfPixmap
        else:
            pixmap = self.pdfPixmap

        # Choose the colors
        self.palette = self.qnotero.ui.listWidgetResults.palette()
        if option.state & QStyle.State_MouseOver:
            background = self.palette.Highlight
            foreground = self.palette.HighlightedText
            _note = zoteroItem.get_note()
            if _note != None:
                self.qnotero.showNoteHint()
            else:
                self.qnotero.hideNoteHint()

        elif option.state & QStyle.State_Selected:
            background = self.palette.Dark
            foreground = self.palette.WindowText
        else:
            background = self.palette.Base
            foreground = self.palette.WindowText

        # Draw the frame
        _rect = option.rect.adjusted(self._margin, self._margin, \
         -2*self._margin, -self._margin)
        pen = painter.pen()
        pen.setColor(self.palette.color(background))
        painter.setPen(pen)
        painter.setBrush(self.palette.brush(background))
        painter.drawRoundedRect(_rect, self.roundness, self.roundness)
        font = painter.font
        pen = painter.pen()
        pen.setColor(self.palette.color(foreground))
        painter.setPen(pen)

        # Draw icon
        _rect = QRect(option.rect)
        _rect.moveBottom(_rect.bottom() + 0.5 * self.dy)
        _rect.moveLeft(_rect.left() + 0.5 * self.dy)
        _rect.setHeight(self.pixmapSize)
        _rect.setWidth(self.pixmapSize)
        painter.drawPixmap(_rect, pixmap)

        # Draw the text
        _rect = option.rect.adjusted(self.pixmapSize+self.dy, 0.5*self.dy, \
         -self.dy, 0)

        f = [self.tagFont, self.italicFont, self.regularFont, \
         self.boldFont]
        l.reverse()
        while len(l) > 0:
            s = l.pop()
            if len(f) > 0:
                painter.setFont(f.pop())
            painter.drawText(_rect, Qt.AlignLeft, s)
            _rect = _rect.adjusted(0, self.dy, 0, 0)
예제 #4
0
class PlottingThread(QThread):
    def __init__(self, parent):
        QThread.__init__(self)
        self.result = None
        self.parent = parent
        self._stopped = False
        self.mutex = QMutex()
        self.filePrefix = None
        self.fileFormat = None
        self.wallColoring = None
        self.cellColoring = None
        self.pointColoring = None
        self.extraDrawing = []
        self.pointSize = None
        self.pointLineColor = None
        self.pointLineThickness = None
        self.ellipsisDraw = None
        self.overSampling = None
        self.wallThickness = None
        self.bgColor = None
        self.loading = False
        self._crop = QRect(0,0,1,1)
        self._pix = None
        self._end_image_plot = False
        self._loading_arguments = {}
        self.retryObject = None

    def end_step(self):
        return len(self.result)+1

    def stop(self, value = True):
        self.mutex.lock()
        self._stopped = value
        self.mutex.unlock()

    def stopped(self):
        self.mutex.lock()
        val = self._stopped
        self.mutex.unlock()
        return val

    def nextImage(self):
        QCoreApplication.postEvent(self.parent, NextImageEvent())

    def abort(self, reason, **others):
        e = AbortPlottingEvent(reason)
        if others:
            e.others = others
        QCoreApplication.postEvent(self.parent, e)

    def finished(self):
        if self.loading:
            QCoreApplication.postEvent(self.parent, FinishLoadingEvent())
            self.loading = False
        else:
            QCoreApplication.postEvent(self.parent, FinishPlottingEvent())

    def image_ready(self):
        QCoreApplication.postEvent(self.parent, ImageReadyPlottingEvent())

    def update_nb_images(self, nb):
        QCoreApplication.postEvent(self.parent, UpdateNbImageEvent(nb))

    @property
    def crop_left(self):
        return self._crop.left()

    @crop_left.setter
    def crop_left(self, value):
        self._crop.moveLeft(int(value))

    @property
    def crop_top(self):
        return self._crop.top()

    @crop_top.setter
    def crop_top(self, value):
        self._crop.moveTop(int(value))

    @property
    def crop_width(self):
        return self._crop.width()

    @crop_width.setter
    def crop_width(self, value):
        self._crop.setWidth(int(value))

    @property
    def crop_height(self):
        return self._crop.height()

    @crop_height.setter
    def crop_height(self, value):
        self._crop.setHeight(int(value))

    def reset_crop(self):
        self._crop = QRect(QPoint(0,0), self.img_size)

    @property
    def crop(self):
        return QRect(self._crop)

    @crop.deleter
    def crop(self):
        self.reset_crop()

    @property
    def end_image_plot(self):
        '''
        If true, plot the growth data on the end image rather than the start image of the growth calculation.
        '''
        return self._end_image_plot

    @end_image_plot.setter
    def end_image_plot(self, value):
        self._end_image_plot = bool(value)

    @property
    def pix(self):
        '''Thread-safe image storage.'''
        self.mutex.lock()
        pix = self._pix
        self.mutex.unlock()
        return pix

    @pix.setter
    def pix(self, value):
        self.mutex.lock()
        self._pix = value
        self.mutex.unlock()

    def render_valid(self):
        if self.result is None:
            log_debug("result is None")
            return False
        if self.parent is None:
            log_debug("parent is None")
            return False
        if self.ellipsisDraw is None:
            log_debug("ellipsisDraw is None")
            return False
        if self.cellColoring is None:
            log_debug("cellColoring is None")
            return False
        if self.wallColoring is None:
            log_debug("wallColoring is None")
            return False
        if self.pointColoring is None:
            log_debug("pointColoring is None")
            return False
        if self.pointSize is None:
            log_debug("pointSize is None")
            return False
        if self.pointLineThickness is None:
            log_debug("pointSize is None")
            return False
        if self.pointLineColor is None:
            log_debug("pointSize is None")
            return False
        if self.wallThickness is None:
            log_debug("wallThickness is None")
            return False
        if self.overSampling is None:
            log_debug("overSampling is None")
            return False
        if self.bgColor is None:
            log_debug("bgColor is None")
            return False
        return True

    def valid(self):
        if self.filePrefix is None:
            log_debug("filePrefix is None")
            return False
        if not self.filePrefix:
            log_debug("filePrefix is Empty")
            return False
        if self.fileFormat is None:
            log_debug("fileFormat is None")
            return False
        return self.render_valid()

    def drawImage(self, imageid):
        cache = image_cache.cache
        cellColoring = self.cellColoring
        wallColoring = self.wallColoring
        pointColoring = self.pointColoring
        ellipsisDraw = self.ellipsisDraw
        overSampling = self.overSampling
        extraDrawing = self.extraDrawing
        bgColor = self.bgColor.rgb()
        result = self.result
        if self.result_type == "Data":
            data = result
            img_name = result.images_name[imageid]
        else:
            data = result.data
            img_name = result.images[imageid]
        #scale = data.images_scale[img_name]
        min_scale = data.minScale()
        img = cache.image(data.image_path(img_name))
        img_data = data[img_name]
        size = self._crop.size()
        pix = QImage(size*overSampling, QImage.Format_ARGB32)
        pix.fill(bgColor)
        painter = QPainter()
        if not painter.begin(pix):
            self.abort("Cannot create painter on QImage")
            return None, None, None
        painter.setRenderHints(QPainter.SmoothPixmapTransform, True)
        painter.setRenderHints(QPainter.Antialiasing, True)
        if overSampling > 1:
            painter.scale(overSampling, overSampling)
        painter.translate(-self._crop.topLeft())
        painter.save()
        painter.translate(self.translate)
        log_debug("Translating: %gx%g" % (self.translate.x(), self.translate.y()) )
        painter.scale(1/min_scale, 1/min_scale)
        painter.save()
        matrix = img_data.matrix()
        painter.setWorldTransform(matrix, True)
        painter.drawImage(QPoint(0,0), img)
        painter.restore()
        #pt_matrix = QTransform()
        #pt_matrix.scale(1/min_scale, 1/min_scale)
        #painter.setTransform(pt_matrix, True)
        cellColoring.startImage(painter, imageid)
        wallColoring.startImage(painter, imageid)
        for ed in extraDrawing:
            ed.startImage(painter, imageid)
        if self.result_type == "Growth":
            cells = result.cells[imageid]
            walls = result.walls[imageid]
        else:
            cells = img_data.cells
            walls = set()
            for cid in img_data.cells:
                pts = [ pt for pt in data.cells[cid] if pt in img_data ]
                if len(pts) > 1:
                    for i in range(len(pts)):
                        walls.add(data.wallId(pts[i-1], pts[i]))
        # Now, draw the cells and the ellipsis
        for cid in cells:
            painter.setPen(Qt.NoPen)
            color = cellColoring(imageid, cid)
            painter.setBrush(color)
            pts = data.cellAtTime(cid, img_data.index)
            if pts:
                pts.append(pts[0])
                ppts = []
                for p1,p2 in zip(pts[:-1], pts[1:]):
                    ppts.append(img_data[p1])
                    ppts.extend(img_data.walls[p1,p2])
                ppts.append(ppts[0])
                poly = QPolygonF(ppts)
                painter.drawPolygon(poly)
        # And draw the walls
        wallThickness = self.wallThickness*min_scale
        for wid in walls:
            color = wallColoring(imageid, wid)
            if color.alpha() > 0:
                pen = QPen(color)
                pen.setWidthF(wallThickness)
                painter.setPen(pen)
                pts = [img_data[wid[0]]] + img_data.walls[wid[0], wid[1]] + [img_data[wid[1]]]
                #painter.drawLine(img_data[wid[0]], img_data[wid[1]])
                painter.drawPolyline(*pts)
        # Then, draw the points
        pointSize = self.pointSize*min_scale
        pointLineColor = self.pointLineColor
        pointLineThickness = self.pointLineThickness*min_scale
        log_debug("pointSize = %g" % pointSize)
        for pid in img_data:
            color = pointColoring(imageid, pid)
            if color.alpha() > 0:
                pen = QPen(pointLineColor)
                pen.setWidthF(pointLineThickness)
                brush = QBrush(color)
                painter.setPen(pen)
                painter.setBrush(brush)
                pos = img_data[pid]
                rect = QRectF(pos.x()-pointSize, pos.y()-pointSize, 2*pointSize, 2*pointSize)
                painter.drawEllipse(rect)
        if ellipsisDraw.plot:
            for cid in cells:
                pts = data.cellAtTime(cid, img_data.index)
                if pts:
                    pts.append(pts[0])
                    ppts = []
                    for p1,p2 in zip(pts[:-1], pts[1:]):
                        ppts.append(img_data[p1])
                        ppts.extend(img_data.walls[p1,p2])
                    ppts.append(ppts[0])
                    #poly = QPolygonF(ppts)
                    #painter.drawPolygon(poly)
                    ellipsisDraw(painter, imageid, cid, ppts, min_scale)
        # At last, draw the extra data
        for ed in extraDrawing:
            ed(painter, imageid)
        tr = painter.worldTransform()
        painter.restore()
        pic_w = wallColoring.finalizeImage(painter, imageid, tr, self.crop)
        pic_c = cellColoring.finalizeImage(painter, imageid, tr, self.crop)
        for ed in extraDrawing:
            ed.finalizeImage(painter, imageid, tr, self.crop)
        painter.end()
        return pix, pic_w, pic_c

    def start(self):
        if self.isRunning():
            assert not self.rendering_all, "Cannot run twice the rendering of all images with the same object."
            return
        if parameters.instance.use_thread:
            log_debug("Starting rendering thread.")
            QThread.start(self)
            return False
        else:
            self.run()
            return True

    def render_all(self):
        self.rendering_all = True
        return self.start()

    def render_single(self, img_id, retry=False):
        if retry:
            while self.isRunning():
                self.wait(10000)
        elif self.isRunning():
            return
        self.rendering_all = False
        self.current_image = img_id
        return self.start()

    def load(self, filename):
        self.loading = True
        self.result = filename
        return self.start()

    def run(self):
        if self.loading:
            self.run_loader()
        elif self.rendering_all:
            self.run_full()
        else:
            self.run_single()

    def run_single(self):
        img = self.current_image
        self.cellColoring.init()
        self.wallColoring.init()
        self.pointColoring.init()
        log_debug("Rendering image %d" % img)
        self.pix, self.pic_w, self.pic_c = self.drawImage(img)
        if self.pic_w is not None:
            log_debug("Has wall image")
        if self.pic_c is not None:
            log_debug("Has cell image")
        if self.pix is not None:
            log_debug("Pix correctly rendered")
        log_debug("Rendered image %d  = %s" % (img, self.pix))
        self.image_ready()

    def reload(self):
        if self.retryObject is None:
            return
        self._loading_arguments.update(self.retryObject.method_args)
        self.load(self.retryObject.filename)

    def run_loader(self):
        filename = self.result
        try:
            self.retryObject = None
# First, prepare the data by getting the images and computing how big they
# should be
            f = open(filename)
            first_line = f.readline()
            f.close()
            if first_line.startswith("TRKR_VERSION"):
                result = Result(None)
                result.load(self.result, **self._loading_arguments)
                result_type = "Growth"
            else:
                result = TrackingData()
                result.load(self.result, **self._loading_arguments)
                result_type = "Data"
            self.result = result
            self.result_type = result_type
            if result_type == "Data":
                data = result
                images = data.images_name
                if data.cells:
                    self.has_cells = True
                    self.has_walls = True
                else:
                    self.has_cells = False
                    self.has_walls = False
                self.has_points = bool(data.cell_points)
            else:
                data = result.data
                images = result.images
                self.has_cells = False
                self.has_walls = False
                self.has_points = False
            self.images = images
            cache = image_cache.cache
            self.update_nb_images(len(result))
            bbox = QRectF()
            ms = data.minScale()
            for i in range(len(result)):
                img_name = images[i]
                img_data = data[img_name]
                img = cache.image(data.image_path(img_name))
                matrix = QTransform()
                matrix = img_data.matrix()
                sc = QTransform()
                sc.scale(1.0/ms, 1.0/ms)
                matrix *= sc
                r = QRectF(img.rect())
                rbox = matrix.map(QPolygonF(r)).boundingRect()
                bbox |= rbox
                log_debug("Image '%s':\n\tSize = %gx%g\n\tTransformed = %gx%g %+g %+g\n\tGlobal bbox = %gx%g %+g %+g\n" %
                             (img_name, r.width(), r.height(), rbox.width(), rbox.height(), rbox.left(), rbox.top(),
                              bbox.width(), bbox.height(), bbox.left(), bbox.top()))
                log_debug("Matrix:\n%g\t%g\t%g\n%g\t%g\t%g\n" %
                            (matrix.m11(), matrix.m12(), matrix.dx(), matrix.m21(), matrix.m22(), matrix.dy()))
                if result_type == "Growth":
                    if result.cells[i]:
                        self.has_cells = True
                    if result.walls[i]:
                        self.has_walls = True
                    self.has_points = bool(result.data.cell_points)
                self.nextImage()
            translate = bbox.topLeft()
            translate *= -1
            self.translate = translate
            size = bbox.size().toSize()
            self.img_size = size
            self._crop = QRect(QPoint(0,0), size)
            self.finished()
            self._loading_arguments = {} # All done, we don't need that anymore
        except RetryTrackingDataException as ex:
            ex.filename = filename
            self.retryObject = ex
            self.finished()
            return
        except Exception as ex:
            _, _, exceptionTraceback = sys.exc_info()
            self.abort(ex, traceback=exceptionTraceback)
            raise

    def run_full(self):
        if not self.valid():
            self.abort("Object was not correctly initialized")
            return
        self.stop(False)
        painter = None
        try:
            result = self.result
            self.update_nb_images(len(result))
#            if self.result_type == "Data":
#                data = result
#                images = result.images_name
#            else:
#                data = result.data
#                images = result.images
#            cache = image_cache.cache
            cellColoring = self.cellColoring
            wallColoring = self.wallColoring
            pointColoring = self.pointColoring
            file_format = self.fileFormat
            file_pattern = "%s%%0%dd.%s" % (self.filePrefix, len(str(len(result))), file_format)
            wall_file_pattern = "%s%%0%dd_wall.%s" % (self.filePrefix, len(str(len(result))), file_format)
            cell_file_pattern = "%s%%0%dd_cell.%s" % (self.filePrefix, len(str(len(result))), file_format)
            cellColoring.init()
            wallColoring.init()
            pointColoring.init()
            self.nextImage()
            for i in range(len(result)):
                if self.stopped():
                    self.abort("User interruption")
                    return
                pix, pic_w, pic_c = self.drawImage(i)
                pix.save(file_pattern % (i+1), file_format)
                if pic_w is not None:
                    self.saveExtra(pic_w, wall_file_pattern % (i+1), file_format)
                if pic_c is not None:
                    self.saveExtra(pic_c, cell_file_pattern % (i+1), file_format)
                self.nextImage()
            self.finished()
        except Exception as ex:
            if painter is not None:
                painter.end()
            _, _, exceptionTraceback = sys.exc_info()
            self.abort(ex, traceback=exceptionTraceback)
            raise

    def saveExtra(self, picture, file_name, file_format):
        rect = picture.boundingRect()
        pix = QImage(rect.size(), QImage.Format_ARGB32)
        pix.fill(QColor(0, 0, 0, 0).rgba())
        paint = QPainter()
        paint.begin(pix)
        paint.drawPicture(rect.topLeft()*-1, picture)
        paint.end()
        pix.save(file_name, file_format)
	def paint(self, painter, option, index):
	
		"""
		Draws the widget
		
		Arguments:
		painter -- a QPainter
		option -- a QStyleOptionView
		index -- a QModelIndex		
		"""
		
		# Retrieve the data
		model = index.model()
		record = model.data(index)
		text = record.toString()				
		zoteroItem = zoteroCache[unicode(text)]		
		l = zoteroItem.full_format().split("\n")
		if zoteroItem.fulltext == None:
			pixmap = self.noPdfPixmap
		else:
			pixmap = self.pdfPixmap
			
		# Choose the colors
		self.palette = self.qnotero.ui.listWidgetResults.palette()				
		if option.state & QStyle.State_MouseOver:
			background = self.palette.Highlight
			foreground = self.palette.HighlightedText
			_note = zoteroItem.get_note()			
			if _note != None:
				self.qnotero.showNoteHint()
			else:
				self.qnotero.hideNoteHint()
			
		elif option.state & QStyle.State_Selected:
			background = self.palette.Dark
			foreground = self.palette.WindowText
		else:
			background = self.palette.Base
			foreground = self.palette.WindowText
							
		# Draw the frame		
		_rect = option.rect.adjusted(self._margin, self._margin, \
			-2*self._margin, -self._margin)		
		pen = painter.pen()	
		pen.setColor(self.palette.color(background))
		painter.setPen(pen)
		painter.setBrush(self.palette.brush(background))
		painter.drawRoundedRect(_rect, self.roundness, self.roundness)
		font = painter.font
		pen = painter.pen()
		pen.setColor(self.palette.color(foreground))
		painter.setPen(pen)		
		
		# Draw icon		
		_rect = QRect(option.rect)
		_rect.moveBottom(_rect.bottom() + 0.5*self.dy)
		_rect.moveLeft(_rect.left() + 0.5*self.dy)
		_rect.setHeight(self.pixmapSize)
		_rect.setWidth(self.pixmapSize)
		painter.drawPixmap(_rect, pixmap)
					
		# Draw the text
		_rect = option.rect.adjusted(self.pixmapSize+self.dy, 0.5*self.dy, \
			-self.dy, 0)
		
		f = [self.tagFont, self.italicFont, self.regularFont, \
			self.boldFont]
		l.reverse()		
		while len(l) > 0:
			s = l.pop()
			if len(f) > 0:
				painter.setFont(f.pop())
			painter.drawText(_rect, Qt.AlignLeft, s)
			_rect = _rect.adjusted(0, self.dy, 0, 0)				
예제 #6
0
class AbstractScrollTela(TelaConsole):
    def __init__(self, altura, parent=None):
        super().__init__(parent=parent)

        self._rectTela = QRect(0,0,0,altura)
        self._mostrarHorizontal = False
        self._mostrarVertical = False

        self._scrollHorizontal = ScrollBarConsole(3,0,orientacao=ScrollBarConsole.HORIZONTAL,parent=self)
        self._scrollVertical = ScrollBarConsole(self._rectTela.height(),0,orientacao=ScrollBarConsole.VERTICAL,parent=self)

        self._scrollHorizontal.valorScrollModificado.connect(self._moverHorizontal)
        self._scrollVertical.valorScrollModificado.connect(self._moverVertical)

        self._scrollBarFocus = ScrollBarConsole(3,0,parent=self)
        self._scrollBarFocus.installEventFilter(self)

    def eventFilter(self, obj, event):
        if obj == self._scrollBarFocus and event.type() != EventoTecladoConsole.TabType:
            self._scrollVertical.customEvent(event)
            self._scrollHorizontal.customEvent(event)
            return True
        else:
            return False

    def acceptFocus(self):
        return True

    def focusNextChild(self):
        if self._scrollBarFocus.hasFocus():
            return False

        if self.hasFocus():
            if not (self._mostrarVertical or self._mostrarHorizontal):
                return False
            self._scrollBarFocus.setFocus()
        else:
            if not self.acceptFocus():
                return False
            self.setFocus()

        return True

    def focusPrevChild(self):
        if self.hasFocus():
            return False

        if self._scrollBarFocus.hasFocus():
            if self.acceptFocus():
                self.setFocus()
            else:
                return False
        else:
            self._scrollBarFocus.setFocus()
        return True
    
    def indexChildActive(self):
        if self._scrollBarFocus.hasFocus():
            return 0
        
        return -1

    def getRectTela(self):
        return self._rectTela

    def _moverVertical(self, valor):
        self._scrollVertical.setValorAtual(valor)
        self._rectTela.moveTop(valor)

    def _moverHorizontal(self, valor):
        self._scrollHorizontal.setValorAtual(valor)
        self._rectTela.moveLeft(valor)

    def deixarVisivelVertical(self, valor):
        top = self.getRectTela().top()
        height = self.getRectTela().height() - self._numLinhasFixas() - 1
        bottom = top + height

        if valor < top:
            self._moverVertical(valor)
        elif valor > bottom:
            self._moverVertical(valor - height)

    def deixarVisivelHorizontal(self, valor):
        left = self.getRectTela().left()
        width = self.getRectTela().width()-1
        right = left + width

        if valor < left:
            self._moverHorizontal(valor)
        elif valor > right:
            self._moverHorizontal(valor - width)

    def scrollContentsBy(self, dx, dy):
        self._rectTela.translate(dx,dy)

    def getDesenhoTela(self):
        raise NotImplemented("Metodo abstrato")

    def _adicionarScrollBar(self, tela):
        if self._mostrarVertical:
            tela = self._adicionarScrollVertical(tela)

        if self._mostrarHorizontal:
            tela = self._adicionarScrollHorizontal(tela)

        return tela

    def _adicionarScrollVertical(self, texto):
        scroll = ''
        for i in self._scrollVertical.desenhoTelaConsole(self._rectTela.width()).split('\n'):
            scroll += "{0}|\n".format(i)
        scroll = "-|\n{0}-|".format(scroll).split('\n')

        s = ''
        texto = texto.split('\n')
        for i in range(len(texto)):
            s += "{0:{1}}{2}\n".format(texto[i], self._rectTela.width()+2, scroll[i])

        if s.endswith('\n'):
            s = s[:len(s)-1]

        return s

    def _adicionarScrollHorizontal(self, texto):
        texto += '\n|{0}|{1}\n'.format(self._scrollHorizontal.desenhoTelaConsole(self._rectTela.width()), 'X|' if self._mostrarVertical else '')
        texto += '|{0:-<{1}}|{2}'.format('', self._rectTela.width(), '-|' if self._mostrarVertical else '')
        return texto

    def _ajustarScroll(self, tela):
        linhas = tela.split('\n')
        numColunas = max(map(len, linhas))
        numLinhasFixas = self._numLinhasFixas()
        numLinhas = len(linhas) + numLinhasFixas

        self._mostrarVertical = numLinhas > self._rectTela.height()
        self._mostrarHorizontal = numColunas > self._rectTela.width()

        self._scrollHorizontal.setAteValor(max(0, numColunas-self._rectTela.width()))
        self._scrollVertical.setAteValor(max(0, numLinhas-self._rectTela.height()))

    def _adicionarLinhasFixas(self, tela):
        """Esse método deve ser sobrescrito pela classe filha para adicionar as linhas fixas na tela"""
        return tela

    def _numLinhasFixas(self):
        return self._adicionarLinhasFixas('').count('\n')

    def _linhasVisiveis(self, tela):
        linhas = tela.split('\n')
        numLinhasFixas = self._numLinhasFixas()
        numLinhas = len(linhas) + numLinhasFixas

        if numLinhas < self._rectTela.height():
            tela = self._adicionarLinhasFixas(tela)
            tela += '\n'*(self._rectTela.height()-numLinhas)
        else:
            top = self.getRectTela().top()
            bottom = self.getRectTela().bottom()+1
            return self._adicionarLinhasFixas('\n'.join(linhas[top:bottom - numLinhasFixas]))

        return tela

    def _colunasVisiveis(self, tela):
        linhas = tela.split('\n')
        numColunas = max(map(len, linhas))+1

        if numColunas > self._rectTela.width():
            tela = '\n'.join([linha[self._rectTela.left():self._rectTela.right()+1] for linha in linhas])

        return tela

    def _ajustarTela(self, tela):
        tela = self._linhasVisiveis(tela)
        tela = self._colunasVisiveis(tela)
        return tela

    def desenhoTela(self, tam):
        tela = self.getDesenhoTela()
        self._ajustarScroll(tela)

        if self._mostrarVertical:
            tam -= 2

        if tam-2 != self._rectTela.width():
            self._rectTela.setWidth(tam-2)
            self._scrollHorizontal.setTamanho(tam-2)
            self._ajustarScroll(tela)

        tela = self._ajustarTela(tela)
        tela = self._colocarBorda(tela, tam)
        return self._adicionarScrollBar(tela)
예제 #7
0
class PlottingThread(QThread):
    def __init__(self, parent):
        QThread.__init__(self)
        self.result = None
        self.parent = parent
        self._stopped = False
        self.mutex = QMutex()
        self.filePrefix = None
        self.fileFormat = None
        self.wallColoring = None
        self.cellColoring = None
        self.pointColoring = None
        self.extraDrawing = []
        self.pointSize = None
        self.pointLineColor = None
        self.pointLineThickness = None
        self.ellipsisDraw = None
        self.overSampling = None
        self.wallThickness = None
        self.bgColor = None
        self.loading = False
        self._crop = QRect(0, 0, 1, 1)
        self._pix = None
        self._end_image_plot = False
        self._loading_arguments = {}
        self.retryObject = None

    def end_step(self):
        return len(self.result) + 1

    def stop(self, value=True):
        self.mutex.lock()
        self._stopped = value
        self.mutex.unlock()

    def stopped(self):
        self.mutex.lock()
        val = self._stopped
        self.mutex.unlock()
        return val

    def nextImage(self):
        QCoreApplication.postEvent(self.parent, NextImageEvent())

    def abort(self, reason, **others):
        e = AbortPlottingEvent(reason)
        if others:
            e.others = others
        QCoreApplication.postEvent(self.parent, e)

    def finished(self):
        if self.loading:
            QCoreApplication.postEvent(self.parent, FinishLoadingEvent())
            self.loading = False
        else:
            QCoreApplication.postEvent(self.parent, FinishPlottingEvent())

    def image_ready(self):
        QCoreApplication.postEvent(self.parent, ImageReadyPlottingEvent())

    def update_nb_images(self, nb):
        QCoreApplication.postEvent(self.parent, UpdateNbImageEvent(nb))

    @property
    def crop_left(self):
        return self._crop.left()

    @crop_left.setter
    def crop_left(self, value):
        self._crop.moveLeft(int(value))

    @property
    def crop_top(self):
        return self._crop.top()

    @crop_top.setter
    def crop_top(self, value):
        self._crop.moveTop(int(value))

    @property
    def crop_width(self):
        return self._crop.width()

    @crop_width.setter
    def crop_width(self, value):
        self._crop.setWidth(int(value))

    @property
    def crop_height(self):
        return self._crop.height()

    @crop_height.setter
    def crop_height(self, value):
        self._crop.setHeight(int(value))

    def reset_crop(self):
        self._crop = QRect(QPoint(0, 0), self.img_size)

    @property
    def crop(self):
        return QRect(self._crop)

    @crop.deleter
    def crop(self):
        self.reset_crop()

    @property
    def end_image_plot(self):
        '''
        If true, plot the growth data on the end image rather than the start image of the growth calculation.
        '''
        return self._end_image_plot

    @end_image_plot.setter
    def end_image_plot(self, value):
        self._end_image_plot = bool(value)

    @property
    def pix(self):
        '''Thread-safe image storage.'''
        self.mutex.lock()
        pix = self._pix
        self.mutex.unlock()
        return pix

    @pix.setter
    def pix(self, value):
        self.mutex.lock()
        self._pix = value
        self.mutex.unlock()

    def render_valid(self):
        if self.result is None:
            log_debug("result is None")
            return False
        if self.parent is None:
            log_debug("parent is None")
            return False
        if self.ellipsisDraw is None:
            log_debug("ellipsisDraw is None")
            return False
        if self.cellColoring is None:
            log_debug("cellColoring is None")
            return False
        if self.wallColoring is None:
            log_debug("wallColoring is None")
            return False
        if self.pointColoring is None:
            log_debug("pointColoring is None")
            return False
        if self.pointSize is None:
            log_debug("pointSize is None")
            return False
        if self.pointLineThickness is None:
            log_debug("pointSize is None")
            return False
        if self.pointLineColor is None:
            log_debug("pointSize is None")
            return False
        if self.wallThickness is None:
            log_debug("wallThickness is None")
            return False
        if self.overSampling is None:
            log_debug("overSampling is None")
            return False
        if self.bgColor is None:
            log_debug("bgColor is None")
            return False
        return True

    def valid(self):
        if self.filePrefix is None:
            log_debug("filePrefix is None")
            return False
        if not self.filePrefix:
            log_debug("filePrefix is Empty")
            return False
        if self.fileFormat is None:
            log_debug("fileFormat is None")
            return False
        return self.render_valid()

    def drawImage(self, imageid):
        cache = image_cache.cache
        cellColoring = self.cellColoring
        wallColoring = self.wallColoring
        pointColoring = self.pointColoring
        ellipsisDraw = self.ellipsisDraw
        overSampling = self.overSampling
        extraDrawing = self.extraDrawing
        bgColor = self.bgColor.rgb()
        result = self.result
        if self.result_type == "Data":
            data = result
            img_name = result.images_name[imageid]
        else:
            data = result.data
            img_name = result.images[imageid]
        #scale = data.images_scale[img_name]
        min_scale = data.minScale()
        img = cache.image(data.image_path(img_name))
        img_data = data[img_name]
        size = self._crop.size()
        pix = QImage(size * overSampling, QImage.Format_ARGB32)
        pix.fill(bgColor)
        painter = QPainter()
        if not painter.begin(pix):
            self.abort("Cannot create painter on QImage")
            return None, None, None
        painter.setRenderHints(QPainter.SmoothPixmapTransform, True)
        painter.setRenderHints(QPainter.Antialiasing, True)
        if overSampling > 1:
            painter.scale(overSampling, overSampling)
        painter.translate(-self._crop.topLeft())
        painter.save()
        painter.translate(self.translate)
        log_debug("Translating: %gx%g" %
                  (self.translate.x(), self.translate.y()))
        painter.scale(1 / min_scale, 1 / min_scale)
        painter.save()
        matrix = img_data.matrix()
        painter.setWorldTransform(matrix, True)
        painter.drawImage(QPoint(0, 0), img)
        painter.restore()
        #pt_matrix = QTransform()
        #pt_matrix.scale(1/min_scale, 1/min_scale)
        #painter.setTransform(pt_matrix, True)
        cellColoring.startImage(painter, imageid)
        wallColoring.startImage(painter, imageid)
        for ed in extraDrawing:
            ed.startImage(painter, imageid)
        if self.result_type == "Growth":
            cells = result.cells[imageid]
            walls = result.walls[imageid]
        else:
            cells = img_data.cells
            walls = set()
            for cid in img_data.cells:
                pts = [pt for pt in data.cells[cid] if pt in img_data]
                if len(pts) > 1:
                    for i in range(len(pts)):
                        walls.add(data.wallId(pts[i - 1], pts[i]))
        # Now, draw the cells and the ellipsis
        for cid in cells:
            painter.setPen(Qt.NoPen)
            color = cellColoring(imageid, cid)
            painter.setBrush(color)
            pts = data.cellAtTime(cid, img_data.index)
            if pts:
                pts.append(pts[0])
                ppts = []
                for p1, p2 in zip(pts[:-1], pts[1:]):
                    ppts.append(img_data[p1])
                    ppts.extend(img_data.walls[p1, p2])
                ppts.append(ppts[0])
                poly = QPolygonF(ppts)
                painter.drawPolygon(poly)
        # And draw the walls
        wallThickness = self.wallThickness * min_scale
        for wid in walls:
            color = wallColoring(imageid, wid)
            if color.alpha() > 0:
                pen = QPen(color)
                pen.setWidthF(wallThickness)
                painter.setPen(pen)
                pts = [img_data[wid[0]]
                       ] + img_data.walls[wid[0], wid[1]] + [img_data[wid[1]]]
                #painter.drawLine(img_data[wid[0]], img_data[wid[1]])
                painter.drawPolyline(*pts)
        # Then, draw the points
        pointSize = self.pointSize * min_scale
        pointLineColor = self.pointLineColor
        pointLineThickness = self.pointLineThickness * min_scale
        log_debug("pointSize = %g" % pointSize)
        for pid in img_data:
            color = pointColoring(imageid, pid)
            if color.alpha() > 0:
                pen = QPen(pointLineColor)
                pen.setWidthF(pointLineThickness)
                brush = QBrush(color)
                painter.setPen(pen)
                painter.setBrush(brush)
                pos = img_data[pid]
                rect = QRectF(pos.x() - pointSize,
                              pos.y() - pointSize, 2 * pointSize,
                              2 * pointSize)
                painter.drawEllipse(rect)
        if ellipsisDraw.plot:
            for cid in cells:
                pts = data.cellAtTime(cid, img_data.index)
                if pts:
                    pts.append(pts[0])
                    ppts = []
                    for p1, p2 in zip(pts[:-1], pts[1:]):
                        ppts.append(img_data[p1])
                        ppts.extend(img_data.walls[p1, p2])
                    ppts.append(ppts[0])
                    #poly = QPolygonF(ppts)
                    #painter.drawPolygon(poly)
                    ellipsisDraw(painter, imageid, cid, ppts, min_scale)
        # At last, draw the extra data
        for ed in extraDrawing:
            ed(painter, imageid)
        tr = painter.worldTransform()
        painter.restore()
        pic_w = wallColoring.finalizeImage(painter, imageid, tr, self.crop)
        pic_c = cellColoring.finalizeImage(painter, imageid, tr, self.crop)
        for ed in extraDrawing:
            ed.finalizeImage(painter, imageid, tr, self.crop)
        painter.end()
        return pix, pic_w, pic_c

    def start(self):
        if self.isRunning():
            assert not self.rendering_all, "Cannot run twice the rendering of all images with the same object."
            return
        if parameters.instance.use_thread:
            log_debug("Starting rendering thread.")
            QThread.start(self)
            return False
        else:
            self.run()
            return True

    def render_all(self):
        self.rendering_all = True
        return self.start()

    def render_single(self, img_id, retry=False):
        if retry:
            while self.isRunning():
                self.wait(10000)
        elif self.isRunning():
            return
        self.rendering_all = False
        self.current_image = img_id
        return self.start()

    def load(self, filename):
        self.loading = True
        self.result = filename
        return self.start()

    def run(self):
        if self.loading:
            self.run_loader()
        elif self.rendering_all:
            self.run_full()
        else:
            self.run_single()

    def run_single(self):
        img = self.current_image
        self.cellColoring.init()
        self.wallColoring.init()
        self.pointColoring.init()
        log_debug("Rendering image %d" % img)
        self.pix, self.pic_w, self.pic_c = self.drawImage(img)
        if self.pic_w is not None:
            log_debug("Has wall image")
        if self.pic_c is not None:
            log_debug("Has cell image")
        if self.pix is not None:
            log_debug("Pix correctly rendered")
        log_debug("Rendered image %d  = %s" % (img, self.pix))
        self.image_ready()

    def reload(self):
        if self.retryObject is None:
            return
        self._loading_arguments.update(self.retryObject.method_args)
        self.load(self.retryObject.filename)

    def run_loader(self):
        filename = self.result
        try:
            self.retryObject = None
            # First, prepare the data by getting the images and computing how big they
            # should be
            f = open(filename)
            first_line = f.readline()
            f.close()
            if first_line.startswith("TRKR_VERSION"):
                result = Result(None)
                result.load(self.result, **self._loading_arguments)
                result_type = "Growth"
            else:
                result = TrackingData()
                result.load(self.result, **self._loading_arguments)
                result_type = "Data"
            self.result = result
            self.result_type = result_type
            if result_type == "Data":
                data = result
                images = data.images_name
                if data.cells:
                    self.has_cells = True
                    self.has_walls = True
                else:
                    self.has_cells = False
                    self.has_walls = False
                self.has_points = bool(data.cell_points)
            else:
                data = result.data
                images = result.images
                self.has_cells = False
                self.has_walls = False
                self.has_points = False
            self.images = images
            cache = image_cache.cache
            self.update_nb_images(len(result))
            bbox = QRectF()
            ms = data.minScale()
            for i in range(len(result)):
                img_name = images[i]
                img_data = data[img_name]
                img = cache.image(data.image_path(img_name))
                matrix = QTransform()
                matrix = img_data.matrix()
                sc = QTransform()
                sc.scale(1.0 / ms, 1.0 / ms)
                matrix *= sc
                r = QRectF(img.rect())
                rbox = matrix.map(QPolygonF(r)).boundingRect()
                bbox |= rbox
                log_debug(
                    "Image '%s':\n\tSize = %gx%g\n\tTransformed = %gx%g %+g %+g\n\tGlobal bbox = %gx%g %+g %+g\n"
                    % (img_name, r.width(), r.height(), rbox.width(),
                       rbox.height(), rbox.left(), rbox.top(), bbox.width(),
                       bbox.height(), bbox.left(), bbox.top()))
                log_debug("Matrix:\n%g\t%g\t%g\n%g\t%g\t%g\n" %
                          (matrix.m11(), matrix.m12(), matrix.dx(),
                           matrix.m21(), matrix.m22(), matrix.dy()))
                if result_type == "Growth":
                    if result.cells[i]:
                        self.has_cells = True
                    if result.walls[i]:
                        self.has_walls = True
                    self.has_points = bool(result.data.cell_points)
                self.nextImage()
            translate = bbox.topLeft()
            translate *= -1
            self.translate = translate
            size = bbox.size().toSize()
            self.img_size = size
            self._crop = QRect(QPoint(0, 0), size)
            self.finished()
            self._loading_arguments = {
            }  # All done, we don't need that anymore
        except RetryTrackingDataException as ex:
            ex.filename = filename
            self.retryObject = ex
            self.finished()
            return
        except Exception as ex:
            _, _, exceptionTraceback = sys.exc_info()
            self.abort(ex, traceback=exceptionTraceback)
            raise

    def run_full(self):
        if not self.valid():
            self.abort("Object was not correctly initialized")
            return
        self.stop(False)
        painter = None
        try:
            result = self.result
            self.update_nb_images(len(result))
            #            if self.result_type == "Data":
            #                data = result
            #                images = result.images_name
            #            else:
            #                data = result.data
            #                images = result.images
            #            cache = image_cache.cache
            cellColoring = self.cellColoring
            wallColoring = self.wallColoring
            pointColoring = self.pointColoring
            file_format = self.fileFormat
            file_pattern = "%s%%0%dd.%s" % (self.filePrefix,
                                            len(str(len(result))), file_format)
            wall_file_pattern = "%s%%0%dd_wall.%s" % (
                self.filePrefix, len(str(len(result))), file_format)
            cell_file_pattern = "%s%%0%dd_cell.%s" % (
                self.filePrefix, len(str(len(result))), file_format)
            cellColoring.init()
            wallColoring.init()
            pointColoring.init()
            self.nextImage()
            for i in range(len(result)):
                if self.stopped():
                    self.abort("User interruption")
                    return
                pix, pic_w, pic_c = self.drawImage(i)
                pix.save(file_pattern % (i + 1), file_format)
                if pic_w is not None:
                    self.saveExtra(pic_w, wall_file_pattern % (i + 1),
                                   file_format)
                if pic_c is not None:
                    self.saveExtra(pic_c, cell_file_pattern % (i + 1),
                                   file_format)
                self.nextImage()
            self.finished()
        except Exception as ex:
            if painter is not None:
                painter.end()
            _, _, exceptionTraceback = sys.exc_info()
            self.abort(ex, traceback=exceptionTraceback)
            raise

    def saveExtra(self, picture, file_name, file_format):
        rect = picture.boundingRect()
        pix = QImage(rect.size(), QImage.Format_ARGB32)
        pix.fill(QColor(0, 0, 0, 0).rgba())
        paint = QPainter()
        paint.begin(pix)
        paint.drawPicture(rect.topLeft() * -1, picture)
        paint.end()
        pix.save(file_name, file_format)