Beispiel #1
0
class Video(QWidget):
    def __init__(self):
        # init the widget
        QWidget.__init__(self)

        # set up the scene
        self.scene=QGraphicsScene()
        self.scene.setSceneRect(0,0,800,600)

        # add a view of that scene
        self.view = QGraphicsView()
        self.view.setScene(self.scene)
        self.view.setRenderHint(QPainter.Antialiasing)
        self.view.setFixedSize(800,600)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # set the screen sync
        val = "1"
        # Set for nVidia linux
        os.environ["__GL_SYNC_TO_VBLANK"] = val
        # Set for recent linux Mesa DRI Radeon
        os.environ["LIBGL_SYNC_REFRESH"] = val

        qglf = QGLFormat()
        qglf.setSampleBuffers(True)
        #qglf.setSwapInterval(1)
        self.glw = QGLWidget(qglf)
        self.glw.setAutoBufferSwap(False)
        self.view.setViewport(self.glw)
        
        QTimer.singleShot(0,self.glw.swapBuffers)

    def swapBuffers(self):
        # first call the swap on the QGLWidget
        self.glw.swapBuffers()

        self.glw.makeCurrent()

        # The following is taken from the PsychToolbox
        # Draw a single pixel in left-top area of back-buffer. 
        # This will wait/stall the rendering pipeline
        # until the buffer flip has happened, aka immediately after the VBL has started.
        # We need the pixel as "synchronization token", so the following glFinish() really
        # waits for VBL instead of just "falling through" due to the asynchronous nature of
        # OpenGL:
        glDrawBuffer(GL_BACK)
        # We draw our single pixel with an alpha-value of zero - so effectively it doesn't
        # change the color buffer - just the z-buffer if z-writes are enabled...
        glColor4f(0.0,0.0,0.0,0.0)
        glBegin(GL_POINTS)
        glVertex2i(10,10)
        glEnd()
        # This glFinish() will wait until point drawing is finished, ergo backbuffer was ready
        # for drawing, ergo buffer swap in sync with start of VBL has happened.
        glFinish()

    def show(self):
        # shows the viewer widget
        self.view.show()
Beispiel #2
0
    def __init__(self, model, title = None):
        super(GraphWidget, self).__init__()

        self.timerId = 0
        
        scene = QGraphicsScene(self)
        scene.setItemIndexMethod(QtGui.QGraphicsScene.NoIndex)
        scene.setSceneRect(-200, -200, 640, 400)
        self.gscene = scene;
        self.setScene(scene)
        self.setCacheMode(QtGui.QGraphicsView.CacheBackground)
        self.setViewportUpdateMode(QtGui.QGraphicsView.BoundingRectViewportUpdate)
        self.setRenderHint(QtGui.QPainter.Antialiasing)
        self.setTransformationAnchor(QtGui.QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QtGui.QGraphicsView.AnchorViewCenter)
        self.model = model;
        self.whitebrush = QBrush(Qt.white);
        self.redbrush = QBrush(Qt.red)
        self.drawNetwork(self.gscene, self.model);
        
        #setttings of the window
        self.scale(1.2,1.2);
        self.setMinimumSize(640, 480);
        
        
        if title == None:
            self.setWindowTitle("Network Visualisation");
        else:
            self.setWindowTitle("Network Visualisation -" + title);
Beispiel #3
0
Datei: 6.py Projekt: wsonv/Wonjun
def main():

    app = QApplication(sys.argv)

    grview = QGraphicsView()
    scene = QGraphicsScene()
    scene.setSceneRect(0, 0, 680, 459)

    scene.addPixmap(QPixmap('01.png'))
    grview.setScene(scene)

    item = GraphicsRectItem(0, 0, 300, 150)
    scene.addItem(item)

    grview.fitInView(scene.sceneRect(), Qt.KeepAspectRatio)
    grview.show()
    sys.exit(app.exec_())
Beispiel #4
0
 def __init__(self, *args):
     scene = QGraphicsScene(args[0])
     scene.setSceneRect(0,0,600.0,SCENE_HEIGHT)
     QGraphicsView.__init__(self, scene, *args)
     
     scene = self.scene()
     self.yAxis = scene.addLine(PADDING, PADDING, PADDING, scene.height() - PADDING)
     self.xAxis = scene.addLine(PADDING, scene.height() - PADDING, scene.width() - PADDING, scene.height() - PADDING)
     
     self.bars = []
     self.barLabels = []
     self.xLabels = []
     self.yLabels = []
     self.values = []
     
     self.show()
     self.raise_()
Beispiel #5
0
def render_drop_shadow_frame(pixmap, shadow_rect, shadow_color,
                             offset, radius, rect_fill_color):
    pixmap.fill(QColor(0, 0, 0, 0))
    scene = QGraphicsScene()
    rect = QGraphicsRectItem(shadow_rect)
    rect.setBrush(QColor(rect_fill_color))
    rect.setPen(QPen(Qt.NoPen))
    scene.addItem(rect)
    effect = QGraphicsDropShadowEffect(color=shadow_color,
                                       blurRadius=radius,
                                       offset=offset)

    rect.setGraphicsEffect(effect)
    scene.setSceneRect(QRectF(QPointF(0, 0), QSizeF(pixmap.size())))
    painter = QPainter(pixmap)
    scene.render(painter)
    painter.end()
    scene.clear()
    scene.deleteLater()
    return pixmap
Beispiel #6
0
class PlotPreview(QDialog):
    def __init__(self, thread, parent):
        QDialog.__init__(self, parent)
        self.ui = Ui_PlotPreview()
        self.ui.setupUi(self)
        self.parent = parent
        icon = QIcon()
        icon.addPixmap(QPixmap(":/icons/reload.png"), QIcon.Normal, QIcon.Off)
        self.update_btn = QPushButton(icon, "Update")
        self.ui.buttonBox.addButton(self.update_btn, QDialogButtonBox.ApplyRole)
        self.update_btn.clicked.connect(self.render_image)
        self._pix = None
        self._image_list = None
        self._thread = thread
        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0,0,1,1)
        self.ui.imageView.setScene(self.scene)
        self.pix_item = None
        self.ui.imageView.setEnabled(False)
        self.ui.imageView.setInteractive(False)
        self.ui.imageView.setDragMode(QGraphicsView.ScrollHandDrag)
        self.pic_w = None
        self.pic_c = None
        self.show_pic_w = None
        self.show_pic_c = None
        timer = QTimer(self)
        timer.setSingleShot(True)
        timer.setInterval(500)
        self.timer = timer
        timer.timeout.connect(self.render_image)
        if parameters.instance.use_OpenGL:
            self.ui.imageView.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers)))

    def __del__(self):
        self.ui.imageView.setScene(None)
        cleanQObject(self)

    @property
    def thread(self):
        '''Thread object drawing the img'''
        return self._thread

    @thread.setter
    def thread(self, value):
        if self._thread != value:
            self._thread = value

    @property
    def pix(self):
        '''Image to be previewed.

        :returntype: `QImage`'''
        return self._pix

    @pix.setter
    def pix(self, pix):
        self.ui.imageView.setEnabled(True)
        self._pix = pix
        if self.pix_item is not None:
            self.scene.removeItem(self.pix_item)
        self.pix_item = self.scene.addPixmap(QPixmap.fromImage(pix))
        self.scene.setSceneRect(QRectF(self.pix.rect()))
        if self.show_pic_w:
            self.show_pic_w.close()
            self.show_pic_w = None
        if self.pic_w:
            self.show_pic_w = QLabel(self, Qt.Window)
            #self.show_pic_w.setAttribute(Qt.WA_DeleteOnClose)
            self.show_pic_w.setPicture(self.pic_w)
            self.show_pic_w.show()
            self.show_pic_w.raise_()
        if self.show_pic_c:
            self.show_pic_c.close()
            self.show_pic_c = None
        if self.pic_c:
            self.show_pic_c = QLabel(self, Qt.Window)
            #self.show_pic_c.setAttribute(Qt.WA_DeleteOnClose)
            self.show_pic_c.setPicture(self.pic_c)
            self.show_pic_c.show()
            self.show_pic_c.raise_()
        log_debug("Received image")

    @property
    def image_list(self):
        '''List of images to paint'''
        return tuple(self._image_list)

    @image_list.setter
    def image_list(self, value):
        value = list(value)
        if self._image_list != value:
            self._image_list = value
            self.ui.imageList.clear()
            for img in value:
                self.ui.imageList.addItem(img)
            self.ui.autoUpdate.setEnabled(True)
            self.ui.zoomIn.setEnabled(True)
            self.ui.zoomOut.setEnabled(True)
            self.ui.zoom1.setEnabled(True)
            self.ui.zoomFit.setEnabled(True)
            self.ui.imageList.setEnabled(True)

    @pyqtSignature("")
    def on_zoomIn_clicked(self):
        self.ui.imageView.scale(2,2)

    @pyqtSignature("")
    def on_zoomOut_clicked(self):
        self.ui.imageView.scale(.5,.5)

    @pyqtSignature("")
    def on_zoom1_clicked(self):
        self.ui.imageView.setTransform(QTransform())

    @pyqtSignature("")
    def on_zoomFit_clicked(self):
        self.ui.imageView.fitInView(QRectF(self.pix.rect()), Qt.KeepAspectRatio)

    @pyqtSignature("")
    def request_render_image(self):
        if self.isVisible():
            if parameters.instance.use_thread:
                self.timer.start()
            else:
                self.render_image()

    @pyqtSignature("")
    def render_image(self):
        if self.isVisible():
            i = self.ui.imageList.currentIndex()
            log_debug("Launch computing for image %d" % i)
            if self.thread.render_single(i) is None:
                QMessageBox.information(self, "Failed rendering image", "The renderer is busy and could not render the image.\nTry again later")
            else:
                self.ui.imageView.setEnabled(False)

    @pyqtSignature("int")
    def on_imageList_currentIndexChanged(self, value):
        self.render_image()

    @pyqtSignature("bool")
    def on_autoUpdate_toggled(self, value):
        self.parent.auto_update = value
        if value:
            self.request_render_image()

    def showEvent(self, event):
        self.render_image()

    def reject(self):
        self.close()

    def closeEvent(self, event):
        self.parent.preview_button.setChecked(False)
        if self.show_pic_w is not None:
            self.show_pic_w.close()
            self.show_pic_w = None
        if self.show_pic_c is not None:
            self.show_pic_c.close()
            self.show_pic_c = None
Beispiel #7
0
class DualImageView(QGraphicsView):
    VERTICAL = 0
    HORIZONTAL = 1
    IMAGE_A = 0
    IMAGE_B = 1

    # no argument signal
    images_changed = pyqtSignal()
    annotations_changed = pyqtSignal()
    annotation_selected = pyqtSignal(int)
    no_selection = pyqtSignal()

    # click/point signals
    image_a_click = pyqtSignal(int,int)
    image_b_click = pyqtSignal(int,int)    

    # keyboard
    key_event = pyqtSignal(int)

    def __init__(self, main_win):
        super(QGraphicsView,self).__init__(main_win)
        self.parent_ = main_win
        self.main_win_ = main_win
        self.setInteractive(True)

        self.setStyleSheet("QGraphicsView { border: none; }")
        
        self.scene_ = QGraphicsScene(0,0,0,0,self.parent_)
        self.image_item_ = self.scene_.addPixmap(QPixmap())
        self.image_item_.setPos(0,0)
        #self.ann_group_ = QGraphicsItemGroup()
        #self.ann_group_.setPos(0,0)
        #self.scene_.addItem(self.ann_group_)
        self.setScene(self.scene_)
        self.scene_.selectionChanged.connect(self.on_selection_changed)
        
        # TODO: handle orientation
        self.orientation_ = DualImageView.VERTICAL
        self.images_ = [None, None]
        self.composite_ = None
        self.annotations_ = []
        self.dim_ = 0
        self.offset_ = np.array([0,0])
        self.cancel_click_ = False
        
        self.images_changed.connect(self.on_images_changed)
        self.annotations_changed.connect(self.on_annotations_changed)

    def on_selection_changed(self):
        log.debug("on_selection_changed")
        selected = self.scene_.selectedItems()
        if len(selected) > 0:
            self.cancel_click_ = True
            selected = self.scene_.selectedItems()[0]
            idx = -1
            for a in self.annotations_:
                idx += 1
                if a.item == selected:
                    log.debug(" emitting selection {0}".format(idx))
                    self.annotation_selected.emit(idx)
        else:
            self.no_selection.emit()

    @property
    def image_b_offset(self):
        return np.array([0,self.dim_],dtype=np.int32)

    def point_in_image(self, p):
        if p[1] < self.dim_:
            return 0
        else:
            return 1

    def point_to_image(self, which, p):
        if which == DualImageView.IMAGE_B:
            return p - self.image_b_offset
        return p

    def image_to_view(self, which, p):
        if which == DualImageView.IMAGE_B:
            return p + self.image_b_offset
        return p

    def on_images_changed(self):
        imga = self.images_[0]
        imgb = self.images_[1]
        width = max(imga.shape[1],imgb.shape[1])
        heighta = imga.shape[0]
        heightb = imgb.shape[0]
        height = heighta + heightb
        self.dim_ = heighta
        self.offset_ = np.array([0,heighta])
        # this assumes rgb images :-(
        comp = np.empty((height,width,imga.shape[2]),dtype=imga.dtype)
        comp[0:heighta,:imga.shape[1],:] = imga
        comp[heighta:(heighta+heightb),:imgb.shape[1],:] = imgb
        self.composite_ = comp
        qimg = qn.array2qimage(self.composite_)
        pix = QPixmap.fromImage(qimg)
        self.image_item_.setPixmap(pix)
        self.scene_.setSceneRect(0,0, width, height)
        self.repaint()
        
    def on_annotations_changed(self):
        #log.debug("on_annotations_changed")
        # self.scene_.removeItem(self.ann_group_)
        # self.ann_group_ = QGraphicsItemGroup()
        # self.ann_group_.setHandlesChildEvents(False)
        # self.ann_group_.setPos(0,0)
        # for a in self.annotations_:
        #     log.debug(" adding item")
        #     self.ann_group_.addToGroup(a.get_item())
        # self.scene_.addItem(self.ann_group_)
        self.repaint()

    def transform_raw_pt(self, ev):
        pt = self.mapToScene(ev.x(), ev.y())
        return np.array([int(pt.x()), int(pt.y())], dtype=np.int32)

    def clear(self):
        self.images_ = [None,None]
        self.composite_ = None
        self.annotations_ = None
        self.images_changed.emit()
        self.annotations_changed.emit()
        
    def set_images(self, img_pair):
        self.images_ = img_pair
        self.images_changed.emit()

    # @property
    # def annotations(self):
    #     return self.annotations_
    
    # @annotations.setter
    # def annotations(self, anns):
    #     self.annotations_ = anns
    #     self.annotations_changed.emit()

    # def set_annotations(self, anns):
    #     self.annotations_ = anns
    #     self.annotations_changed.emit()

    def paintEvent(self, ev):
        painter = QPainter(self.viewport())
        painter.fillRect(0,0,self.viewport().width(),self.viewport().height(), QColor(0,0,0))
        painter.end()
        QGraphicsView.paintEvent(self, ev)

    def annotation(self, idx):
        return self.annotations_[idx]

    def clear_annotations(self):
        for a in self.annotations_:
            self.scene_.removeItem(a.item)
        self.annotations_ = []
        self.annotations_changed.emit()

    def add_annotation(self, ann):
        ann.changed.connect(self.on_annotations_changed)
        self.annotations_.append(ann)
        self.scene_.addItem(ann.item)
        self.annotations_changed.emit()
        return len(self.annotations_) - 1
        
    def remove_last_annotation(self):
        self.scene_.removeItem(self.annotations_[-1].item)
        del self.annotations_[-1]
        self.annotations_changed.emit()

    def remove_annotation(self, idx):
        self.scene_.removeItem(self.annotations_[idx].item)
        del self.annotations_[idx]
        self.annotations_changed.emit()

    def mousePressEvent(self, ev):
        super(DualImageView,self).mousePressEvent(ev)
        if self.cancel_click_:
            return
        log.debug("mouse pressed: " + str(ev))
        self.img_local_pt = self.transform_raw_pt(ev)

    def mouseReleaseEvent(self, ev):
        super(DualImageView,self).mouseReleaseEvent(ev)
        if self.cancel_click_:
            self.cancel_click_ = False
            return
        log.debug("mouse released: " + str(ev))
        rel_pt = self.transform_raw_pt(ev)
        delta = rel_pt - self.img_local_pt
        if abs(delta[0]) < 3 and abs(delta[1] < 3):
            # it was a successful click
            self.mouseClicked(self.img_local_pt)
        else: 
            # recognize this as a rectangle drag
            self.mouseDragged(self.img_local_pt, delta)

    def mouseDragged(self, pt, delta):
        log.debug("mouse dragged: {0}, {1}".format(pt,delta))

    def mouseClicked(self, pt):
        log.debug("mouse clicked: {0}".format(pt))
        if pt[1] < self.dim_:
            self.image_a_click.emit(pt[0],pt[1])
        else:
            self.image_b_click.emit(pt[0],pt[1] - self.dim_)

    # handle the keyboard events here!
    def keyPressEvent(self, ev):
        pass

    def keyReleaseEvent(self, ev):
        k = ev.key()
        self.key_event.emit(k)
Beispiel #8
0
class TakeDragGame(QWidget):
    def __init__(self, parent=None):
        super(TakeDragGame, self).__init__(parent)

        # This is always the same
        self.dot2 = QGraphicsTextItem(':')
        self.dot1 = QGraphicsTextItem(':')
        self.animations = []
        self.digits = []
        self.main_layout = QHBoxLayout()
        self.setLayout(self.main_layout)
        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 600, 400)
        self.view = QGraphicsView()
        self.view.setScene(self.scene)
        # TODO: Check if its better with opengl or not
        # self.view.setViewport(QtOpenGL.QGLWidget())
        self.main_layout.addWidget(self.view)
        # self.setWindowState(Qt.WindowMaximized)
        self.view.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        self.image_bank = None
        self.create_and_add_images()

        # self.scene.setBackgroundBrush(QBrush(Qt.red, Qt.SolidPattern))

        # self.populate()
        # self.animator = QTimer()
        # self.animator.timeout.connect(self.animate)
        # self.animate()

    def create_and_add_images(self):
        self.load_images_json_file()
        self.add_background_to_image()
        self.add_background_from_image()
        if self.image_bank is not None:
            for image_id in self.image_bank.keys():
                if "clothes" in self.image_bank[image_id]["categories"]:
                    image_path = self.image_bank[image_id]["path"]
                    new_image = DraggableItem(image_path, self.background_from_image)
                    new_image.moved_signal.moved.connect(self.item_moved)
                    self.image_bank[image_id]["widget"] = new_image
                    newpos_x = self.background_from_image.boundingRect().width() / 2 - new_image.boundingRect().width() / 2
                    newpos_y = self.background_from_image.boundingRect().height() / 2 - new_image.boundingRect().height() / 2
                    new_image.setPos(newpos_x, newpos_y)
                    # self.scene.addItem(new_image)
                    new_image.setZValue(30)

    def item_moved(self, pos):
        widget = self.sender().get_parent()
        print widget.zValue()
        print self.background_from_image.zValue()
        print self.background_to_image.zValue()
        item_br = widget.sceneBoundingRect()
        if self.background_from_image.sceneBoundingRect().contains(item_br):
            widget.setParentItem(self.background_from_image)
            newpos_x = self.background_from_image.boundingRect().width() / 2 - widget.boundingRect().width() / 2
            newpos_y = self.background_from_image.boundingRect().height() / 2 - widget.boundingRect().height() / 2
            # self.background_to_image.stackBefore(self.background_from_image)
            widget.setPos(newpos_x, newpos_y)
        elif self.background_to_image.sceneBoundingRect().contains(item_br):
            widget.setParentItem(self.background_to_image)
            newpos_x = self.background_to_image.boundingRect().width() / 2 - widget.boundingRect().width() / 2
            newpos_y = self.background_to_image.boundingRect().height() / 2 - widget.boundingRect().height() / 2
            # self.background_from_image.stackBefore(self.background_to_image)
            widget.setPos(newpos_x, newpos_y)



    def load_images_json_file(self):
        with open(os.path.join(CURRENT_PATH, './resources/images.json')) as f:
            self.image_bank = json.load(f)

    def add_background_from_image(self, ):
        assert self.image_bank is not None, "Images need to be loaded before calling this method (try load_images_json_file)"
        if "Background from" in self.image_bank:
            background_from_pixmap = QPixmap(self.image_bank["Background from"]["path"])
            self.background_from_image = QGraphicsPixmapItem(background_from_pixmap)
            self.scene.addItem(self.background_from_image)
            self.background_from_image.setZValue(2)

    def add_background_to_image(self, ):
        assert self.image_bank is not None, "Images need to be loaded before calling this method (try load_images_json_file)"
        if "Background to" in self.image_bank:
            background_to_pixmap = QPixmap(self.image_bank["Background to"]["path"])
            self.background_to_image = QGraphicsPixmapItem(background_to_pixmap)
            self.scene.addItem(self.background_to_image)
            self.background_to_image.setZValue(2)

    def resizeEvent(self, event):
        view_size = self.view.size()
        new_background_height = (1.5 / 4.) * view_size.height()
        background_to_pixmap = QPixmap(self.image_bank["Background to"]["path"])
        background_to_pixmap = background_to_pixmap.scaled(new_background_height, new_background_height,
                                                           Qt.KeepAspectRatio)
        if not self.background_to_image:
            self.background_to_image = QGraphicsPixmapItem(background_to_pixmap)
        else:
            self.background_to_image.setPixmap(background_to_pixmap)
        sugested_x_position = int(2 * (view_size.width() / 3.))
        if sugested_x_position < 0:
            sugested_x_position = 0
        sugested_y_position = int(view_size.height() / 2. - background_to_pixmap.size().height() / 2)
        if sugested_y_position < 0:
            sugested_y_position = 0
        self.background_to_image.setPos(sugested_x_position, sugested_y_position)

        #####################
        new_background_height = (2.2 / 4.) * view_size.height()
        background_from_pixmap = QPixmap(self.image_bank["Background from"]["path"])
        background_from_pixmap = background_from_pixmap.scaled(new_background_height, new_background_height,
                                                               Qt.KeepAspectRatio)
        if not self.background_to_image:
            self.background_from_image = QGraphicsPixmapItem(background_from_pixmap)
        else:
            self.background_from_image.setPixmap(background_from_pixmap)

        sugested_x_position = int(view_size.width() / 5. - background_from_pixmap.size().height() / 2)
        if sugested_x_position < 0:
            sugested_x_position = 0
        sugested_y_position = int(view_size.height() / 2. - background_from_pixmap.size().height() / 2)
        if sugested_y_position < 0:
            sugested_y_position = 0
        self.background_from_image.setPos(sugested_x_position, sugested_y_position)

        ####
        new_widget_height = (1 / 4.) * view_size.height()
        if self.image_bank is not None:
            for image_id in self.image_bank.keys():
                if "clothes" in self.image_bank[image_id]["categories"]:
                    widget = self.image_bank[image_id]["widget"]
                    pixmap = widget.pixmap
                    pixmap = pixmap.scaled(new_widget_height, new_widget_height,
                                           Qt.KeepAspectRatio)
                    widget.setPixmap(pixmap)
                    print widget.moved_flag
                    if not widget.moved_flag:
                        newpos_x = self.background_from_image.boundingRect().width() / 2 - widget.boundingRect().width() / 2
                        newpos_y = self.background_from_image.boundingRect().height() / 2 - widget.boundingRect().height() / 2
                        widget.setPos(newpos_x, newpos_y)

        super(TakeDragGame, self).resizeEvent(event)
Beispiel #9
0
class View(QGraphicsView):
    
    TEXT_COLOR = QColor(1,1,1)
    BOLDISH = QFont("Times", 30, QFont.Bold)
    NORMALISH = QFont("Times", 30, QFont.Normal)
    
    def __init__(self):
        QGraphicsView.__init__(self)
        self.resize(1024, 768) 
        self.qtscene = None
        self.references = []
    
    def display_question(self, question, answers, selected_index = None, correct = None):
        self._init_scene()
        x = 50
        y = 25
        item =  QGraphicsSimpleTextItem(question)
        item.setBrush(self.TEXT_COLOR)
        item.setFont(self.BOLDISH) 
        item.setX(x)
        item.setY(y)
        self.qtscene.addItem(item)
        self.references.append(item)
        y += 75
        
        for index, answer in enumerate(answers):
            index += 1
            item =  QGraphicsSimpleTextItem("%s) %s" % (index, answer))
            item.setBrush(self.TEXT_COLOR)
            item.setFont(self.NORMALISH) 
            item.setX(x)
            item.setY(y)
            item.setAcceptHoverEvents(True)
            self.qtscene.addItem(item)
            self.references.append(item)
            #TODO: do not register click but do show check or not
            if not selected_index:
                item.hoverEnterEvent = partial(self.on_hover_answer, item) 
                item.hoverLeaveEvent = partial(self.on_unhover_answer, item) 
                item.mousePressEvent = partial(self.on_click_answer, index) 
            elif selected_index == index:
                if correct:
                    item =  QGraphicsSimpleTextItem(u"\u2713")
                    item.setBrush(QBrush(QColor(0,150,0)))
                    item.setX(0)
                else:
                    item =  QGraphicsSimpleTextItem("X")
                    item.setBrush(QBrush(QColor(255,0,0)))
                    item.setX(3)
                item.setFont(self.BOLDISH)
                item.setY(y)
                self.qtscene.addItem(item)
                self.references.append(item)
                
            y += 50
        return x, y
    
    def display_answer(self, question, answers, correct_answer, description, selected_index, correct):
        x, y = self.display_question(question, answers, selected_index, correct) #TODO pass what to check and if right or wrong
        y += 50
        item =  QGraphicsSimpleTextItem("Correct Answer: %s" % correct_answer)
        item.setBrush(self.TEXT_COLOR)
        font = QFont(self.BOLDISH)
        font.setUnderline(True)
        item.setFont(font) 
        item.setX(x)
        item.setY(y)
        self.qtscene.addItem(item)
        self.references.append(item)
        
        y += 60
        item =  QGraphicsSimpleTextItem(make_pretty(description, 55))
        item.setBrush(self.TEXT_COLOR)
        item.setFont(self.NORMALISH) 
        item.setX(x)
        item.setY(y)
        self.qtscene.addItem(item)
        self.references.append(item)
        
        item = QPushButton('Next')
        item.clicked.connect(self.on_next)
        item.setFont(self.BOLDISH) 
        item.move(x+700, y)
        self.qtscene.addWidget(item)
        self.references.append(item)
        
    
    def _init_scene(self):
        self.qtscene = QGraphicsScene(self)
        self.qtscene.setSceneRect(QRectF(0, 0, 1000, 750))
        brush = QBrush(QColor(240,245,250))
        self.qtscene.setBackgroundBrush(brush)
        self.setScene(self.qtscene)
        self.references = []
    
    def on_next(self, event):
        self.next()
    
    def on_hover_answer(self, item, event):
        item.setBrush(QBrush(QColor(100,1,1)))
    
    def on_unhover_answer(self, item, event):
        item.setBrush(self.TEXT_COLOR)
        
    def on_click_answer(self, answer_index, event):
        self.select_answer(answer_index)
    
    def keyPressEvent(self, ev):
        if ev.key() == Qt.Key_Escape:
            self.quit()
        
    def quit(self):
        qApp.quit() 
class OWHierarchicalClustering(widget.OWWidget):
    name = "Hierarchical Clustering"
    description = ("Hierarchical clustering based on distance matrix, and "
                   "a dendrogram viewer.")
    icon = "icons/HierarchicalClustering.svg"
    priority = 2100

    inputs = [("Distances", Orange.misc.DistMatrix, "set_distances")]

    outputs = [("Selected Data", Orange.data.Table),
               ("Other Data", Orange.data.Table)]

    #: Selected linkage
    linkage = settings.Setting(1)
    #: Index of the selected annotation item (variable, ...)
    annotation_idx = settings.Setting(0)
    #: Selected tree pruning (none/max depth)
    pruning = settings.Setting(0)
    #: Maximum depth when max depth pruning is selected
    max_depth = settings.Setting(10)

    #: Selected cluster selection method (none, cut distance, top n)
    selection_method = settings.Setting(0)
    #: Cut height ratio wrt root height
    cut_ratio = settings.Setting(75.0)
    #: Number of top clusters to select
    top_n = settings.Setting(3)

    append_clusters = settings.Setting(True)
    cluster_role = settings.Setting(2)
    cluster_name = settings.Setting("Cluster")
    autocommit = settings.Setting(False)

    #: Cluster variable domain role
    AttributeRole, ClassRole, MetaRole = 0, 1, 2

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

        self.matrix = None
        self.items = None
        self.linkmatrix = None
        self.root = None
        self._displayed_root = None
        self.cutoff_height = 0.0

        gui.comboBox(gui.widgetBox(self.controlArea, "Linkage"),
                     self, "linkage", items=LINKAGE,
                     callback=self._invalidate_clustering)

        box = gui.widgetBox(self.controlArea, "Annotation")
        self.label_cb = gui.comboBox(
            box, self, "annotation_idx", callback=self._update_labels)

        self.label_cb.setModel(itemmodels.VariableListModel())
        self.label_cb.model()[:] = ["None", "Enumeration"]

        box = gui.radioButtons(
            self.controlArea, self, "pruning", box="Pruning",
            callback=self._invalidate_pruning
        )
        grid = QGridLayout()
        box.layout().addLayout(grid)
        grid.addWidget(
            gui.appendRadioButton(box, "None", addToLayout=False),
            0, 0
        )
        self.max_depth_spin = gui.spin(
            box, self, "max_depth", minv=1, maxv=100,
            callback=self._invalidate_pruning,
            keyboardTracking=False
        )

        grid.addWidget(
            gui.appendRadioButton(box, "Max depth", addToLayout=False),
            1, 0)
        grid.addWidget(self.max_depth_spin, 1, 1)

        box = gui.radioButtons(
            self.controlArea, self, "selection_method",
            box="Selection",
            callback=self._selection_method_changed)

        grid = QGridLayout()
        box.layout().addLayout(grid)
        grid.addWidget(
            gui.appendRadioButton(box, "Manual", addToLayout=False),
            0, 0
        )
        grid.addWidget(
            gui.appendRadioButton(box, "Height ratio", addToLayout=False),
            1, 0
        )
        self.cut_ratio_spin = gui.spin(
            box, self, "cut_ratio", 0, 100, step=1e-1, spinType=float,
            callback=self._selection_method_changed
        )
        self.cut_ratio_spin.setSuffix("%")

        grid.addWidget(self.cut_ratio_spin, 1, 1)

        grid.addWidget(
            gui.appendRadioButton(box, "Top N", addToLayout=False),
            2, 0
        )
        self.top_n_spin = gui.spin(box, self, "top_n", 1, 20,
                                   callback=self._selection_method_changed)
        grid.addWidget(self.top_n_spin, 2, 1)
        box.layout().addLayout(grid)

        self.controlArea.layout().addStretch()

        box = gui.widgetBox(self.controlArea, "Output")
        gui.checkBox(box, self, "append_clusters", "Append cluster IDs",
                     callback=self._invalidate_output)

        ibox = gui.indentedBox(box)
        name_edit = gui.lineEdit(ibox, self, "cluster_name")
        name_edit.editingFinished.connect(self._invalidate_output)

        cb = gui.comboBox(
            ibox, self, "cluster_role", callback=self._invalidate_output,
            items=["Attribute",
                   "Class variable",
                   "Meta variable"]
        )
        form = QFormLayout(
            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow,
            labelAlignment=Qt.AlignLeft,
            spacing=8
        )
        form.addRow("Name", name_edit)
        form.addRow("Place", cb)

        ibox.layout().addSpacing(5)
        ibox.layout().addLayout(form)
        ibox.layout().addSpacing(5)

        gui.auto_commit(box, self, "autocommit", "Send data", "Auto send is on",
                        box=False)

        self.scene = QGraphicsScene()
        self.view = QGraphicsView(
            self.scene,
            horizontalScrollBarPolicy=Qt.ScrollBarAlwaysOff,
            verticalScrollBarPolicy=Qt.ScrollBarAlwaysOn,
            alignment=Qt.AlignLeft | Qt.AlignVCenter
        )

        def axis_view(orientation):
            ax = pg.AxisItem(orientation=orientation, maxTickLength=7)
            scene = QGraphicsScene()
            scene.addItem(ax)
            view = QGraphicsView(
                scene,
                horizontalScrollBarPolicy=Qt.ScrollBarAlwaysOff,
                verticalScrollBarPolicy=Qt.ScrollBarAlwaysOn,
                alignment=Qt.AlignLeft | Qt.AlignVCenter
            )
            view.setFixedHeight(ax.size().height())
            ax.line = SliderLine(orientation=Qt.Horizontal,
                                 length=ax.size().height())
            scene.addItem(ax.line)
            return view, ax

        self.top_axis_view, self.top_axis = axis_view("top")
        self.mainArea.layout().setSpacing(1)
        self.mainArea.layout().addWidget(self.top_axis_view)
        self.mainArea.layout().addWidget(self.view)
        self.bottom_axis_view, self.bottom_axis = axis_view("bottom")
        self.mainArea.layout().addWidget(self.bottom_axis_view)

        self._main_graphics = QGraphicsWidget()
        self._main_layout = QGraphicsLinearLayout(Qt.Horizontal)
        self._main_layout.setSpacing(1)

        self._main_graphics.setLayout(self._main_layout)
        self.scene.addItem(self._main_graphics)

        self.dendrogram = DendrogramWidget()
        self.dendrogram.setSizePolicy(QSizePolicy.MinimumExpanding,
                                      QSizePolicy.MinimumExpanding)
        self.dendrogram.selectionChanged.connect(self._invalidate_output)
        self.dendrogram.selectionEdited.connect(self._selection_edited)

        fm = self.fontMetrics()
        self.dendrogram.setContentsMargins(
            5, fm.lineSpacing() / 2,
            5, fm.lineSpacing() / 2
        )
        self.labels = GraphicsSimpleTextList()
        self.labels.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        self.labels.setAlignment(Qt.AlignLeft)
        self.labels.setMaximumWidth(200)
        self.labels.layout().setSpacing(0)

        self._main_layout.addItem(self.dendrogram)
        self._main_layout.addItem(self.labels)

        self._main_layout.setAlignment(
            self.dendrogram, Qt.AlignLeft | Qt.AlignVCenter)
        self._main_layout.setAlignment(
            self.labels, Qt.AlignLeft | Qt.AlignVCenter)

        self.view.viewport().installEventFilter(self)
        self.top_axis_view.viewport().installEventFilter(self)
        self.bottom_axis_view.viewport().installEventFilter(self)
        self._main_graphics.installEventFilter(self)

        self.cut_line = SliderLine(self.dendrogram,
                                   orientation=Qt.Horizontal)
        self.cut_line.valueChanged.connect(self._dendrogram_slider_changed)
        self.cut_line.hide()

        self.bottom_axis.line.valueChanged.connect(self._axis_slider_changed)
        self.top_axis.line.valueChanged.connect(self._axis_slider_changed)
        self.dendrogram.geometryChanged.connect(self._dendrogram_geom_changed)
        self._set_cut_line_visible(self.selection_method == 1)

    def set_distances(self, matrix):
        self.matrix = matrix
        self._invalidate_clustering()
        self._set_items(matrix.row_items if matrix is not None else None)

    def _set_items(self, items):
        self.items = items
        if items is None:
            self.label_cb.model()[:] = ["None", "Enumeration"]
        elif isinstance(items, Orange.data.Table):
            vars = list(items.domain)
            self.label_cb.model()[:] = ["None", "Enumeration"] + vars
        elif isinstance(items, list) and \
                all(isinstance(var, Orange.data.Variable) for var in items):
            self.label_cb.model()[:] = ["None", "Enumeration", "Name"]
        else:
            self.label_cb.model()[:] = ["None", "Enumeration"]
        self.annotation_idx = min(self.annotation_idx,
                                  len(self.label_cb.model()) - 1)

    def handleNewSignals(self):
        self._update_labels()

    def _clear_plot(self):
        self.labels.set_labels([])
        self.dendrogram.set_root(None)

    def _set_displayed_root(self, root):
        self._clear_plot()
        self._displayed_root = root
        self.dendrogram.set_root(root)

        self._update_labels()

        self._main_graphics.resize(
            self._main_graphics.size().width(),
            self._main_graphics.sizeHint(Qt.PreferredSize).height()
        )
        self._main_graphics.layout().activate()

    def _update(self):
        self._clear_plot()

        distances = self.matrix

        if distances is not None:
            # Convert to flat upper triangular distances
            i, j = numpy.triu_indices(distances.X.shape[0], k=1)
            distances = distances.X[i, j]

            method = LINKAGE[self.linkage].lower()
            Z = scipy.cluster.hierarchy.linkage(
                distances, method=method
            )
            tree = tree_from_linkage(Z)
            self.linkmatrix = Z
            self.root = tree

            self.top_axis.setRange(tree.value.height, 0.0)
            self.bottom_axis.setRange(tree.value.height, 0.0)

            if self.pruning:
                self._set_displayed_root(prune(tree, level=self.max_depth))
            else:
                self._set_displayed_root(tree)
        else:
            self.linkmatrix = None
            self.root = None
            self._set_displayed_root(None)

        self._apply_selection()

    def _update_labels(self):
        labels = []
        if self.root and self._displayed_root:
            indices = [leaf.value.index for leaf in leaves(self.root)]

            if self.annotation_idx == 0:
                labels = []
            elif self.annotation_idx == 1:
                labels = [str(i) for i in indices]
            elif isinstance(self.items, Orange.data.Table):
                var = self.label_cb.model()[self.annotation_idx]
                col = self.items[:, var]
                labels = [var.repr_val(next(iter(row))) for row in col]
                labels = [labels[idx] for idx in indices]
            else:
                labels = []

            if labels and self._displayed_root is not self.root:
                joined = leaves(self._displayed_root)
                labels = [", ".join(labels[leaf.value.first: leaf.value.last])
                          for leaf in joined]

        self.labels.set_labels(labels)
        self.labels.setMinimumWidth(1 if labels else -1)

    def _invalidate_clustering(self):
        self._update()
        self._update_labels()

    def _invalidate_output(self):
        self.commit()

    def _invalidate_pruning(self):
        if self.root:
            selection = self.dendrogram.selected_nodes()
            ranges = [node.value.range for node in selection]
            if self.pruning:
                self._set_displayed_root(
                    prune(self.root, level=self.max_depth))
            else:
                self._set_displayed_root(self.root)
            selected = [node for node in preorder(self._displayed_root)
                        if node.value.range in ranges]

            self.dendrogram.set_selected_clusters(selected)

        self._apply_selection()

    def commit(self):
        items = getattr(self.matrix, "items", self.items)
        if not items:
            # nothing to commit
            return

        selection = self.dendrogram.selected_nodes()
        selection = sorted(selection, key=lambda c: c.value.first)

        indices = [leaf.value.index for leaf in leaves(self.root)]

        maps = [indices[node.value.first:node.value.last]
                for node in selection]

        selected_indices = list(chain(*maps))
        unselected_indices = sorted(set(range(self.root.value.last)) -
                                    set(selected_indices))

        selected = [items[k] for k in selected_indices]
        unselected = [items[k] for k in unselected_indices]

        if not selected:
            self.send("Selected Data", None)
            self.send("Other Data", None)
            return
        selected_data = unselected_data = None

        if isinstance(items, Orange.data.Table):
            c = numpy.zeros(len(items))

            for i, indices in enumerate(maps):
                c[indices] = i
            c[unselected_indices] = len(maps)

            mask = c != len(maps)

            if self.append_clusters:
                clust_var = Orange.data.DiscreteVariable(
                    str(self.cluster_name),
                    values=["Cluster {}".format(i + 1)
                            for i in range(len(maps))] +
                           ["Other"], ordered=True
                )
                data, domain = items, items.domain

                attrs = domain.attributes
                class_ = domain.class_vars
                metas = domain.metas

                if self.cluster_role == self.AttributeRole:
                    attrs = attrs + (clust_var,)
                elif self.cluster_role == self.ClassRole:
                    class_ = class_ + (clust_var,)
                elif self.cluster_role == self.MetaRole:
                    metas = metas + (clust_var,)

                domain = Orange.data.Domain(attrs, class_, metas)
                data = Orange.data.Table(domain, data)
                data.get_column_view(clust_var)[0][:] = c
            else:
                data = items

            if selected:
                selected_data = data[mask]
            if unselected:
                unselected_data = data[~mask]

        self.send("Selected Data", selected_data)
        self.send("Other Data", unselected_data)

    def sizeHint(self):
        return QSize(800, 500)

    def eventFilter(self, obj, event):
        if obj is self.view.viewport() and event.type() == QEvent.Resize:
            width = self.view.viewport().width() - 2
            self._main_graphics.setMaximumWidth(width)
            self._main_graphics.setMinimumWidth(width)
            self._main_graphics.layout().activate()
        elif event.type() == QEvent.MouseButtonPress and \
                (obj is self.top_axis_view.viewport() or
                 obj is self.bottom_axis_view.viewport()):
            self.selection_method = 1
            # Map click point to cut line local coordinates
            pos = self.top_axis_view.mapToScene(event.pos())
            cut = self.top_axis.line.mapFromScene(pos)
            self.top_axis.line.setValue(cut.x())
            # update the line visibility, output, ...
            self._selection_method_changed()

        return super().eventFilter(obj, event)

    def _dendrogram_geom_changed(self):
        pos = self.dendrogram.pos_at_height(self.cutoff_height)
        geom = self.dendrogram.geometry()
        crect = self.dendrogram.contentsRect()

        self._set_slider_value(pos.x(), geom.width())
        self.cut_line.setLength(geom.height())

        self.top_axis.resize(crect.width(), self.top_axis.height())
        self.top_axis.setPos(geom.left() + crect.left(), 0)
        self.top_axis.line.setPos(self.cut_line.scenePos().x(), 0)

        self.bottom_axis.resize(crect.width(), self.bottom_axis.height())
        self.bottom_axis.setPos(geom.left() + crect.left(), 0)
        self.bottom_axis.line.setPos(self.cut_line.scenePos().x(), 0)

        geom = self._main_graphics.geometry()
        assert geom.topLeft() == QPointF(0, 0)
        self.scene.setSceneRect(geom)

        geom.setHeight(self.top_axis.size().height())

        self.top_axis.scene().setSceneRect(geom)
        self.bottom_axis.scene().setSceneRect(geom)

    def _axis_slider_changed(self, value):
        self.cut_line.setValue(value)

    def _dendrogram_slider_changed(self, value):
        p = QPointF(value, 0)
        cl_height = self.dendrogram.height_at(p)

        self.set_cutoff_height(cl_height)

        # Sync the cut positions between the dendrogram and the axis.
        self._set_slider_value(value, self.dendrogram.size().width())

    def _set_slider_value(self, value, span):
        with blocked(self.cut_line):
            self.cut_line.setValue(value)
            self.cut_line.setRange(0, span)

        with blocked(self.top_axis.line):
            self.top_axis.line.setValue(value)
            self.top_axis.line.setRange(0, span)

        with blocked(self.bottom_axis.line):
            self.bottom_axis.line.setValue(value)
            self.bottom_axis.line.setRange(0, span)

    def set_cutoff_height(self, height):
        self.cutoff_height = height
        if self.root:
            self.cut_ratio = 100 * height / self.root.value.height
        self.select_max_height(height)

    def _set_cut_line_visible(self, visible):
        self.cut_line.setVisible(visible)
        self.top_axis.line.setVisible(visible)
        self.bottom_axis.line.setVisible(visible)

    def select_top_n(self, n):
        root = self._displayed_root
        if root:
            clusters = top_clusters(root, n)
            self.dendrogram.set_selected_clusters(clusters)

    def select_max_height(self, height):
        root = self._displayed_root
        if root:
            clusters = clusters_at_height(root, height)
            self.dendrogram.set_selected_clusters(clusters)

    def _selection_method_changed(self):
        self._set_cut_line_visible(self.selection_method == 1)
        if self.root:
            self._apply_selection()

    def _apply_selection(self):
        if not self.root:
            return

        if self.selection_method == 0:
            pass
        elif self.selection_method == 1:
            height = self.cut_ratio * self.root.value.height / 100
            self.set_cutoff_height(height)
            pos = self.dendrogram.pos_at_height(height)
            self._set_slider_value(pos.x(), self.dendrogram.size().width())
        elif self.selection_method == 2:
            self.select_top_n(self.top_n)

    def _selection_edited(self):
        # Selection was edited by clicking on a cluster in the
        # dendrogram view.
        self.selection_method = 0
        self._selection_method_changed()
class ImagesPreviewer(foundations.ui.common.QWidgetFactory(uiFile=UI_FILE)):
    """
	| This class provides the Application images previewer.
	| It defines methods to navigate through the list of given images ( List of images paths ),
		zoom in / out and fit the displayed image, etc...
	"""
    def __init__(self, parent, paths=None, *args, **kwargs):
        """
		This method initializes the class.

		:param parent: Object parent. ( QObject )
		:param paths: Images paths. ( Tuple / List )
		:param \*args: Arguments. ( \* )
		:param \*\*kwargs: Keywords arguments. ( \*\* )
		"""

        LOGGER.debug("> Initializing '{0}()' class.".format(
            self.__class__.__name__))

        super(ImagesPreviewer, self).__init__(parent, *args, **kwargs)

        # --- Setting class attributes. ---
        self.__container = parent
        self.__paths = None
        self.paths = paths

        self.__uiResourcesDirectory = "resources"
        self.__uiResourcesDirectory = os.path.join(os.path.dirname(__file__),
                                                   self.__uiResourcesDirectory)
        self.__uiPreviousImage = "Previous.png"
        self.__uiNextImage = "Next.png"
        self.__uiZoomOutImage = "Zoom_Out.png"
        self.__uiZoomInImage = "Zoom_In.png"

        # Ensure the ui object is destroyed on close to avoid memory leaks.
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.__graphicsSceneBackgroundColor = QColor(32, 32, 32)
        self.__minimumZoomFactor = 0.05
        self.__maximumZoomFactor = 25
        self.__displayGraphicsItemMargin = 32
        self.__graphicsSceneWidth = QApplication.desktop().screenGeometry(
            QApplication.desktop().primaryScreen()).width() * (
                1 / self.__minimumZoomFactor * 1.75)
        self.__graphicsSceneHeight = QApplication.desktop().screenGeometry(
            QApplication.desktop().primaryScreen()).height() * (
                1 / self.__minimumZoomFactor * 1.75)
        self.__wheelZoomFactor = 350.0
        self.__keyZoomFactor = 1.20

        self.__graphicsView = None
        self.__graphicsScene = None
        self.__displayGraphicsItem = None

        ImagesPreviewer.__initializeUi(self)

        self.loadImage()

    #******************************************************************************************************************
    #***	Attributes properties.
    #******************************************************************************************************************
    @property
    def container(self):
        """
		This method is the property for **self.__container** attribute.

		:return: self.__container. ( QObject )
		"""

        return self.__container

    @container.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def container(self, value):
        """
		This method is the setter method for **self.__container** attribute.

		:param value: Attribute value. ( QObject )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "container"))

    @container.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def container(self):
        """
		This method is the deleter method for **self.__container** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "container"))

    @property
    def paths(self):
        """
		This method is the property for **self.__paths** attribute.

		:return: self.__paths. ( Tuple / List )
		"""

        return self.__paths

    @paths.setter
    @foundations.exceptions.handleExceptions(AssertionError)
    def paths(self, value):
        """
		This method is the setter method for **self.__paths** attribute.

		:param value: Attribute value. ( Tuple / List )
		"""

        if value is not None:
            assert type(value) in (
                tuple, list
            ), "'{0}' attribute: '{1}' type is not 'tuple' or 'list'!".format(
                "paths", value)
            for element in value:
                assert type(
                    element
                ) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
                    "paths", element)
        self.__paths = value

    @paths.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def paths(self):
        """
		This method is the deleter method for **self.__paths** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "paths"))

    @property
    def uiResourcesDirectory(self):
        """
		This method is the property for **self.__uiResourcesDirectory** attribute.

		:return: self.__uiResourcesDirectory. ( String )
		"""

        return self.__uiResourcesDirectory

    @uiResourcesDirectory.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiResourcesDirectory(self, value):
        """
		This method is the setter method for **self.__uiResourcesDirectory** attribute.

		:param value: Attribute value. ( String )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "uiResourcesDirectory"))

    @uiResourcesDirectory.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiResourcesDirectory(self):
        """
		This method is the deleter method for **self.__uiResourcesDirectory** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "uiResourcesDirectory"))

    @property
    def uiPreviousImage(self):
        """
		This method is the property for **self.__uiPreviousImage** attribute.

		:return: self.__uiPreviousImage. ( String )
		"""

        return self.__uiPreviousImage

    @uiPreviousImage.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiPreviousImage(self, value):
        """
		This method is the setter method for **self.__uiPreviousImage** attribute.

		:param value: Attribute value. ( String )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "uiPreviousImage"))

    @uiPreviousImage.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiPreviousImage(self):
        """
		This method is the deleter method for **self.__uiPreviousImage** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "uiPreviousImage"))

    @property
    def uiNextImage(self):
        """
		This method is the property for **self.__uiNextImage** attribute.

		:return: self.__uiNextImage. ( String )
		"""

        return self.__uiNextImage

    @uiNextImage.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiNextImage(self, value):
        """
		This method is the setter method for **self.__uiNextImage** attribute.

		:param value: Attribute value. ( String )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "uiNextImage"))

    @uiNextImage.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiNextImage(self):
        """
		This method is the deleter method for **self.__uiNextImage** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "uiNextImage"))

    @property
    def uiZoomOutImage(self):
        """
		This method is the property for **self.__uiZoomOutImage** attribute.

		:return: self.__uiZoomOutImage. ( String )
		"""

        return self.__uiZoomOutImage

    @uiZoomOutImage.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiZoomOutImage(self, value):
        """
		This method is the setter method for **self.__uiZoomOutImage** attribute.

		:param value: Attribute value. ( String )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "uiZoomOutImage"))

    @uiZoomOutImage.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiZoomOutImage(self):
        """
		This method is the deleter method for **self.__uiZoomOutImage** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "uiZoomOutImage"))

    @property
    def uiZoomInImage(self):
        """
		This method is the property for **self.__uiZoomInImage** attribute.

		:return: self.__uiZoomInImage. ( String )
		"""

        return self.__uiZoomInImage

    @uiZoomInImage.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiZoomInImage(self, value):
        """
		This method is the setter method for **self.__uiZoomInImage** attribute.

		:param value: Attribute value. ( String )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "uiZoomInImage"))

    @uiZoomInImage.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiZoomInImage(self):
        """
		This method is the deleter method for **self.__uiZoomInImage** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "uiZoomInImage"))

    @property
    def graphicsSceneBackgroundColor(self):
        """
		This method is the property for **self.__graphicsSceneBackgroundColor** attribute.

		:return: self.__graphicsSceneBackgroundColor. ( QColors )
		"""

        return self.__graphicsSceneBackgroundColor

    @graphicsSceneBackgroundColor.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def graphicsSceneBackgroundColor(self, value):
        """
		This method is the setter method for **self.__graphicsSceneBackgroundColor** attribute.

		:param value: Attribute value. ( QColors )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "graphicsSceneBackgroundColor"))

    @graphicsSceneBackgroundColor.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def graphicsSceneBackgroundColor(self):
        """
		This method is the deleter method for **self.__graphicsSceneBackgroundColor** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "graphicsSceneBackgroundColor"))

    @property
    def graphicsSceneWidth(self):
        """
		This method is the property for **self.__graphicsSceneWidth** attribute.

		:return: self.__graphicsSceneWidth. ( Integer )
		"""

        return self.__graphicsSceneWidth

    @graphicsSceneWidth.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def graphicsSceneWidth(self, value):
        """
		This method is the setter method for **self.__graphicsSceneWidth** attribute.

		:param value: Attribute value. ( Integer )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "graphicsSceneWidth"))

    @graphicsSceneWidth.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def graphicsSceneWidth(self):
        """
		This method is the deleter method for **self.__graphicsSceneWidth** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "graphicsSceneWidth"))

    @property
    def graphicsSceneHeight(self):
        """
		This method is the property for **self.__graphicsSceneHeight** attribute.

		:return: self.__graphicsSceneHeight. ( Object )
		"""

        return self.__graphicsSceneHeight

    @graphicsSceneHeight.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def graphicsSceneHeight(self, value):
        """
		This method is the setter method for **self.__graphicsSceneHeight** attribute.

		:param value: Attribute value. ( Object )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "graphicsSceneHeight"))

    @graphicsSceneHeight.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def graphicsSceneHeight(self):
        """
		This method is the deleter method for **self.__graphicsSceneHeight** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "graphicsSceneHeight"))

    @property
    def minimumZoomFactor(self):
        """
		This method is the property for **self.__minimumZoomFactor** attribute.

		:return: self.__minimumZoomFactor. ( Float )
		"""

        return self.__minimumZoomFactor

    @minimumZoomFactor.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def minimumZoomFactor(self, value):
        """
		This method is the setter method for **self.__minimumZoomFactor** attribute.

		:param value: Attribute value. ( Float )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "minimumZoomFactor"))

    @minimumZoomFactor.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def minimumZoomFactor(self):
        """
		This method is the deleter method for **self.__minimumZoomFactor** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "minimumZoomFactor"))

    @property
    def maximumZoomFactor(self):
        """
		This method is the property for **self.__maximumZoomFactor** attribute.

		:return: self.__maximumZoomFactor. ( Float )
		"""

        return self.__maximumZoomFactor

    @maximumZoomFactor.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def maximumZoomFactor(self, value):
        """
		This method is the setter method for **self.__maximumZoomFactor** attribute.

		:param value: Attribute value. ( Float )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "maximumZoomFactor"))

    @maximumZoomFactor.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def maximumZoomFactor(self):
        """
		This method is the deleter method for **self.__maximumZoomFactor** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "maximumZoomFactor"))

    @property
    def wheelZoomFactor(self):
        """
		This method is the property for **self.__wheelZoomFactor** attribute.

		:return: self.__wheelZoomFactor. ( Float )
		"""

        return self.__wheelZoomFactor

    @wheelZoomFactor.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def wheelZoomFactor(self, value):
        """
		This method is the setter method for **self.__wheelZoomFactor** attribute.

		:param value: Attribute value. ( Float )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "wheelZoomFactor"))

    @wheelZoomFactor.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def wheelZoomFactor(self):
        """
		This method is the deleter method for **self.__wheelZoomFactor** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "wheelZoomFactor"))

    @property
    def keyZoomFactor(self):
        """
		This method is the property for **self.__keyZoomFactor** attribute.

		:return: self.__keyZoomFactor. ( Float )
		"""

        return self.__keyZoomFactor

    @keyZoomFactor.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def keyZoomFactor(self, value):
        """
		This method is the setter method for **self.__keyZoomFactor** attribute.

		:param value: Attribute value. ( Float )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "keyZoomFactor"))

    @keyZoomFactor.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def keyZoomFactor(self):
        """
		This method is the deleter method for **self.__keyZoomFactor** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "keyZoomFactor"))

    @property
    def graphicsView(self):
        """
		This method is the property for **self.__graphicsView** attribute.

		:return: self.__graphicsView. ( QGraphicsView )
		"""

        return self.__graphicsView

    @graphicsView.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def graphicsView(self, value):
        """
		This method is the setter method for **self.__graphicsView** attribute.

		:param value: Attribute value. ( QGraphicsView )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "graphicsView"))

    @graphicsView.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def graphicsView(self):
        """
		This method is the deleter method for **self.__graphicsView** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "graphicsView"))

    @property
    def graphicsScene(self):
        """
		This method is the property for **self.__graphicsScene** attribute.

		:return: self.__graphicsScene. ( QGraphicsScene )
		"""

        return self.__graphicsScene

    @graphicsScene.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def graphicsScene(self, value):
        """
		This method is the setter method for **self.__graphicsScene** attribute.

		:param value: Attribute value. ( QGraphicsScene )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "graphicsScene"))

    @graphicsScene.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def graphicsScene(self):
        """
		This method is the deleter method for **self.__graphicsScene** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "graphicsScene"))

    @property
    def displayGraphicsItem(self):
        """
		This method is the property for **self.__displayGraphicsItem** attribute.

		:return: self.__displayGraphicsItem. ( QGraphicsItem )
		"""

        return self.__displayGraphicsItem

    @displayGraphicsItem.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def displayGraphicsItem(self, value):
        """
		This method is the setter method for **self.__displayGraphicsItem** attribute.

		:param value: Attribute value. ( QGraphicsItem )
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "displayGraphicsItem"))

    @displayGraphicsItem.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def displayGraphicsItem(self):
        """
		This method is the deleter method for **self.__displayGraphicsItem** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "displayGraphicsItem"))

    #******************************************************************************************************************
    #***	Class methods.
    #******************************************************************************************************************
    def show(self):
        """
		This method reimplements the :meth:`QWidget.show` method.
		"""

        super(ImagesPreviewer, self).show()

        foundations.ui.common.centerWidgetOnScreen(self)

    def closeEvent(self, event):
        """
		This method reimplements the :meth:`QWidget.closeEvent` method.

		:param event: QEvent ( QEvent )
		"""

        LOGGER.debug(
            "> Removing '{0}' from Images Previewers list.".format(self))
        self.__container.imagesPreviewers.remove(self)

        event.accept()

    def wheelEvent(self, event):
        """
		This method reimplements the :meth:`QWidget.wheelEvent` method.

		:param event: QEvent ( QEvent )
		"""

        self.scaleView(pow(1.5, event.delta() / self.__wheelZoomFactor))

    def keyPressEvent(self, event):
        """
		This method reimplements the :meth:`QWidget.keyPressEvent` method.

		:param event: QEvent ( QEvent )
		"""

        key = event.key()
        if key == Qt.Key_Plus:
            self.scaleView(self.__keyZoomFactor)
        elif key == Qt.Key_Minus:
            self.scaleView(1 / self.__keyZoomFactor)
        else:
            super(ImagesPreviewer, self).keyPressEvent(event)

    def __initializeUi(self):
        """
		This method initializes the Widget ui.
		"""

        LOGGER.debug("> Initializing '{0}' ui.".format(
            self.__class__.__name__))

        self.Previous_Image_pushButton.setIcon(
            QIcon(
                os.path.join(self.__uiResourcesDirectory,
                             self.__uiPreviousImage)))
        self.Next_Image_pushButton.setIcon(
            QIcon(os.path.join(self.__uiResourcesDirectory,
                               self.__uiNextImage)))
        self.Zoom_In_pushButton.setIcon(
            QIcon(
                os.path.join(self.__uiResourcesDirectory,
                             self.__uiZoomInImage)))
        self.Zoom_Out_pushButton.setIcon(
            QIcon(
                os.path.join(self.__uiResourcesDirectory,
                             self.__uiZoomOutImage)))
        len(self.__paths) <= 1 and self.Navigation_frame.hide()

        LOGGER.debug("> Initializing graphics View.")
        self.__graphicsView = QGraphicsView()
        self.__graphicsView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.__graphicsView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.__graphicsView.setTransformationAnchor(
            QGraphicsView.AnchorUnderMouse)
        self.__graphicsView.setDragMode(QGraphicsView.ScrollHandDrag)
        # Reimplementing QGraphicsView wheelEvent method.
        self.__graphicsView.wheelEvent = self.wheelEvent

        LOGGER.debug("> Initializing graphics scene.")
        self.__graphicsScene = QGraphicsScene(self.__graphicsView)
        self.__graphicsScene.setItemIndexMethod(QGraphicsScene.NoIndex)
        self.__graphicsScene.setSceneRect(
            -(float(self.__graphicsSceneWidth)) / 2,
            -(float(self.__graphicsSceneHeight)) / 2,
            float(self.__graphicsSceneWidth),
            float(self.__graphicsSceneHeight))

        self.__graphicsView.setScene(self.__graphicsScene)
        self.__graphicsView.setBackgroundBrush(
            QBrush(self.__graphicsSceneBackgroundColor))

        self.Images_Previewer_frame_gridLayout.addWidget(self.__graphicsView)

        # Signals / Slots.
        self.__container.engine.imagesCaches.QImage.contentAdded.connect(
            self.__engine_imagesCaches_QImage__contentAdded)
        self.Previous_Image_pushButton.clicked.connect(
            self.__Previous_Image_pushButton__clicked)
        self.Next_Image_pushButton.clicked.connect(
            self.__Next_Image_pushButton__clicked)
        self.Zoom_Out_pushButton.clicked.connect(
            self.__Zoom_Out_pushButton__clicked)
        self.Zoom_In_pushButton.clicked.connect(
            self.__Zoom_In_pushButton__clicked)
        self.Zoom_Fit_pushButton.clicked.connect(
            self.__Zoom_Fit_pushButton__clicked)

    def __Images_Informations_label_setUi(self):
        """
		This method sets the **Images_Informations_label** Widget ui.
		"""

        if not self.__displayGraphicsItem:
            return

        image = self.__displayGraphicsItem.image
        self.Images_Informations_label.setText(
            "{0} - {1}x{2} px - {3} bit".format(
                os.path.basename(image.data.path), image.data.width,
                image.data.height, image.data.bpp / 4))

    def __engine_imagesCaches_QImage__contentAdded(self, content):
        """
		This method is triggered by the Application **QImage** images cache when content has been added.

		:param content: Cache added content. ( List )
		"""

        if not self.__paths:
            return

        path = foundations.common.getFirstItem(content)
        if not path in self.__paths:
            return

        image = self.__container.engine.imagesCaches.QImage.getContent(path)
        self.__setDisplayGraphicsItem(image)

    def __Previous_Image_pushButton__clicked(self, checked):
        """
		This method is triggered when **Previous_Image_pushButton** Widget is clicked.

		:param checked: Checked state. ( Boolean )
		"""

        self.loopThroughImages(True)

    def __Next_Image_pushButton__clicked(self, checked):
        """
		This method is triggered when **Next_Image_pushButton** Widget is clicked.

		:param checked: Checked state. ( Boolean )
		"""

        self.loopThroughImages()

    def __Zoom_In_pushButton__clicked(self, checked):
        """
		This method is triggered when **Zoom_In_pushButton** Widget is clicked.

		:param checked: Checked state. ( Boolean )
		"""

        self.scaleView(self.__keyZoomFactor)

    def __Zoom_Out_pushButton__clicked(self, checked):
        """
		This method is triggered when **Zoom_Out_pushButton** Widget is clicked.

		:param checked: Checked state. ( Boolean )
		"""

        self.scaleView(1 / self.__keyZoomFactor)

    def __Zoom_Fit_pushButton__clicked(self, checked):
        """
		This method is triggered when **Zoom_Fit_pushButton** Widget is clicked.

		:param checked: Checked state. ( Boolean )
		"""

        self.fitImage()

    def __clearGraphicsScene(self):
        """
		This method clears the View.
		"""

        for graphicsItem in self.__graphicsScene.items():
            self.__graphicsScene.removeItem(graphicsItem)

    def __setDisplayGraphicsItem(self, image):
        """
		This method sets the View using given image.

		:param image: Image to display. ( Qimage )
		"""

        self.__clearGraphicsScene()

        LOGGER.debug("> Initializing graphics item.")
        self.__displayGraphicsItem = Image_QGraphicsItem(image=image)
        self.__graphicsScene.addItem(self.__displayGraphicsItem)

        self.__Images_Informations_label_setUi()

    def loadImage(self, index=0):
        """
		This method loads the display image in the View.

		:param index: Index to load. ( Integer )
		:return: Method success. ( Boolean )
		"""

        if not self.__paths:
            return False

        image = sibl_gui.ui.common.getImage(self.__paths[index])
        self.__setDisplayGraphicsItem(image)

        return True

    def scaleView(self, scaleFactor):
        """
		This method scales the Previewer view.

		:param scaleFactor: Float ( Float )
		:return: Method success. ( Boolean )
		"""

        graphicsView = self.findChild(QGraphicsView)
        factor = graphicsView.matrix().scale(scaleFactor, scaleFactor).mapRect(
            QRectF(0, 0, 1, 1)).width()
        if factor < self.__minimumZoomFactor or factor > self.__maximumZoomFactor:
            return False

        graphicsView.scale(scaleFactor, scaleFactor)
        return True

    def fitWindow(self):
        """
		This method fits the View window.
		
		:return: Method success. ( Boolean )
		"""

        if not self.__displayGraphicsItem:
            return False

        desktopWidth = QApplication.desktop().screenGeometry(
            QApplication.desktop().primaryScreen()).width()
        desktopHeight = QApplication.desktop().screenGeometry(
            QApplication.desktop().primaryScreen()).height()
        width = min(desktopWidth * 0.80, self.__displayGraphicsItem.width)
        height = min(desktopHeight * 0.80, self.__displayGraphicsItem.height)
        self.resize(width, height)

        foundations.ui.common.centerWidgetOnScreen(self)

        return True

    def fitImage(self):
        """
		This method fits the image to the View.
		
		:return: Method success. ( Boolean )
		"""

        if not self.__displayGraphicsItem:
            return False

        self.__graphicsView.fitInView(
            QRectF(
                -(self.__displayGraphicsItem.width / 2) -
                (self.__displayGraphicsItemMargin / 2),
                -(self.__displayGraphicsItem.height / 2) -
                (self.__displayGraphicsItemMargin / 2),
                self.__displayGraphicsItem.width +
                self.__displayGraphicsItemMargin,
                self.__displayGraphicsItem.height +
                self.__displayGraphicsItemMargin), Qt.KeepAspectRatio)
        return True

    def loopThroughImages(self, backward=False):
        """
		This method loops through View images.

		:param backward: Looping backward. ( Boolean )
		:return: Method success. ( Boolean )
		"""

        index = self.__paths.index(self.__displayGraphicsItem.image.data.path)
        index += not backward and 1 or -1
        if index < 0:
            index = len(self.__paths) - 1
        elif index > len(self.__paths) - 1:
            index = 0
        self.loadImage(index)
        return True
Beispiel #12
0
class ClassDiagram(QWidget, itab_item.ITabItem):

    def __init__(self, actions, parent=None):
        QWidget.__init__(self, parent)
        itab_item.ITabItem.__init__(self)
        self.actions = actions
        self.graphicView = QGraphicsView(self)
        self.scene = QGraphicsScene()
        self.graphicView.setScene(self.scene)
        self.graphicView.setViewportUpdateMode(
            QGraphicsView.BoundingRectViewportUpdate)

        vLayout = QVBoxLayout(self)
        self.setLayout(vLayout)
        vLayout.addWidget(self.graphicView)
        self.scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        self.scene.setSceneRect(-200, -200, 400, 400)
        self.graphicView.setMinimumSize(400, 400)
        actualProject = self.actions.ide.explorer.get_actual_project()
        arrClasses = self.actions._locator.get_classes_from_project(
            actualProject)
        #FIXME:dirty need to fix
        self.mX = -400
        self.mY = -320
        self.hightestY = self.mY
        filesList = []
        for elem in arrClasses:
            #loking for paths
            filesList.append(elem[2])
        for path in set(filesList):
            self.create_class(path)

    def create_class(self, path):
        content = file_manager.read_file_content(path)
        items = introspection.obtain_symbols(content)
        mYPadding = 10
        mXPadding = 10
        for classname, classdetail in list(items["classes"].items()):
            cl = ClassModel(self.graphicView, self.scene)
            cl.set_class_name(classname)
            self.fill_clases(cl, classdetail[1])
            self.scene.addItem(cl)
            cl.setPos(self.mX, self.mY)
            self.mX += cl._get_width() + mXPadding
            if self.hightestY < self.mY + cl.get_height():
                self.hightestY = self.mY + cl.get_height()
            if self.mX > 2000:
                self.mX = -400
                self.mY += self.hightestY + mYPadding

    def fill_clases(self, classComponent, classContent):
        funct = classContent['functions']
        classComponent.set_functions_list(funct)
        attr = classContent['attributes']
        classComponent.set_attributes_list(attr)

    def scale_view(self, scaleFactor):
            factor = self.graphicView.transform().scale(
                scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width()

            if factor > 0.05 and factor < 15:
                self.graphicView.scale(scaleFactor, scaleFactor)

    def keyPressEvent(self, event):

        taskList = {
                  Qt.Key_Plus: lambda: self.scaleView(1.2),
                  Qt.Key_Minus: lambda: self.scaleView(1 / 1.2)}
        if(event.key() in taskList):
            taskList[event.key()]()
        else:
            QWidget.keyPressEvent(self, event)
class Canvas(QGraphicsView):
    def __init__(self, window, resultDict, imagePath):
        QGraphicsView.__init__(self)
        self.window = window
        self.pen = QPen(QColor("red"))
        self.pen.setWidth(0.5)
        self.canvasScene = QGraphicsScene()
        self.setScene(self.canvasScene)
        self.resultDict = resultDict
        self.imagePath = imagePath
        self.setBackgroundBrush(QBrush(Qt.black, Qt.SolidPattern))

    def drawImage(self, imageFile):
        """Draw an image on the canvas"""
        image = QPixmap(imageFile)
        self.canvasScene.addPixmap(image)
        return image

    def drawFeaturePoint(self, pointList):
        """Draw a feature point on the canvas"""
        radius = 0.5
        width, height = 2, 2

        x1, y1, x2, y2 = pointList

        #Draw ellipse and bounding rect. Is a hacked version!
        self.canvasScene.addEllipse(x1 - radius + 5, y1 - radius + 3, 2 * radius, 2 * radius, self.pen)
        self.canvasScene.addEllipse(x2 - radius + self.imageWidth + 10, y2 - radius + 3, 2 * radius, 2 * radius, self.pen)
        self.canvasScene.addRect(x1 - width / 2. + 5, y1 - height / 2. + 3, width, height, self.pen)
        self.canvasScene.addRect(x2 - width / 2. + self.imageWidth + 10, y2 - height / 2. + 3, width, height, self.pen)

    def drawFeatureImages(self, imageFile):
        """Draw two consecutive images on the screen"""
        #Load image files
        path, file_ = os.path.split(imageFile)
        image1 = QPixmap(os.path.join(path, 'first_' + file_))
        image2 = QPixmap(os.path.join(path, 'second_' + file_))
        self.imageWidth = image1.width()

        #Add pixmaps
        image1Map = self.canvasScene.addPixmap(image1)
        image2Map = self.canvasScene.addPixmap(image2)

        #Shift pixmaps to the right position
        image1Map.setOffset(QPointF(5, 3))
        image2Map.setOffset(QPointF(10 + image1.width(), 3))

    def drawPolygon(self, Polygon):
        """Draw a polygon on the canvas"""
        polygon = QPolygonF()
        for point in Polygon:
            polygon.append(QPointF(point[0], point[1]))
        self.canvasScene.addPolygon(polygon, self.pen)

    def getWorkerId(self):
        return self.resultDict.values()[self.index][0][0]

    def getAssignmentId(self):
        return self.resultDict.keys()[self.index]

    def nextImage(self):
        """Load next image"""
        self.index += 1
        self.canvasScene.clear()
        if self.index > len(self.resultDict) - 1 or len(self.resultDict) <= 0:
            self.canvasScene.addText("No annotations to review")
            self.window.reviewFlag = False
            self.window.updateTable()

        else:
            #Draw Image and Polygon
            assignmentId = self.resultDict.keys()[self.index]
            result = self.resultDict[assignmentId]
            image = result[0][1]
            pointList = result[0][2]
            if self.window.segmentation_mode:
                pointList = [round(float(point), 3) for point in pointList]
                pointList = zip(*[iter(pointList)] * 2)
                self.drawImage(os.path.join(self.imagePath, image))
                self.drawPolygon(pointList)
            else:
                pointList = [round(float(point), 3) for point in pointList]
                pointList = zip(*[iter(pointList)] * 4)
                self.drawFeatureImages(os.path.join(self.imagePath, image))
                for point in pointList:
                    self.drawFeaturePoint(point)

        #update scene
        self.window.setWindowTitle("MTurk Review Tool ({0}/{1})   Rejected: {2}   Approved: {3}".format(self.index + 1,
                                        len(self.resultDict), len(self.window.rejected), len(self.window.approved)))
        self.canvasScene.setSceneRect(self.canvasScene.itemsBoundingRect())
        self.fitInView(0, 0, self.canvasScene.width(), self.canvasScene.height(), 1)    
        self.canvasScene.update(0, 0, self.canvasScene.width(), self.canvasScene.height())
Beispiel #14
0
class GUI():
    def __init__(self):
        # init the widget
        #QWidget.__init__(self, parent)

        # set up the scene
        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 800, 600)

        # add a view of that scene
        self.view = QGraphicsView()
        self.view.setScene(self.scene)
        self.view.setRenderHint(QPainter.Antialiasing)
        self.view.setFixedSize(800, 600)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # set the screen sync to vertical retrace
        val = "1"
        # Set for nVidia linux
        os.environ["__GL_SYNC_TO_VBLANK"] = val
        # Set for recent linux Mesa DRI Radeon
        os.environ["LIBGL_SYNC_REFRESH"] = val

        qglf = QGLFormat()
        qglf.setSampleBuffers(True)
        self.glw = QGLWidget(qglf)
        self.glw.setAutoBufferSwap(False)
        self.view.setViewport(self.glw)

        #self.view.showFullScreen()
        self.view.show()

        self.last_finish = 0

        QTimer.singleShot(0, self.glw.swapBuffers)

    def swapBuffers(self):
        # first call the swap on the QGLWidget
        start = long(now() * 1000)

        self.glw.swapBuffers()

        #self.glw.makeCurrent()

        # The following is taken from the PsychToolbox
        # Draw a single pixel in left-top area of back-buffer.
        # This will wait/stall the rendering pipeline
        # until the buffer flip has happened, aka immediately after the VBL has started.
        # We need the pixel as "synchronization token", so the following glFinish() really
        # waits for VBL instead of just "falling through" due to the asynchronous nature of
        # OpenGL:
        glDrawBuffer(GL_BACK)
        # We draw our single pixel with an alpha-value of zero - so effectively it doesn't
        # change the color buffer - just the z-buffer if z-writes are enabled...
        glColor4f(0.0, 0.0, 0.0, 0.0)
        glBegin(GL_POINTS)
        glVertex2i(10, 10)
        glEnd()
        # This glFinish() will wait until point drawing is finished, ergo backbuffer was ready
        # for drawing, ergo buffer swap in sync with start of VBL has happened.
        glFinish()

        finish = long(now() * 1000)
        fdiff = finish - self.last_finish
        self.last_finish = finish
        return (start, finish - start, fdiff)
Beispiel #15
0
class ProfileGraphViewer( QWidget ):
    " Profiling results as a graph "

    escapePressed = pyqtSignal()

    def __init__( self, scriptName, params, reportTime,
                        dataFile, stats, parent = None ):
        QWidget.__init__( self, parent )

        self.__dataFile = dataFile
        self.__script = scriptName
        self.__reportTime = reportTime
        self.__params = params
        self.__stats = stats

        project = GlobalData().project
        if project.isLoaded():
            self.__projectPrefix = os.path.dirname( project.fileName )
        else:
            self.__projectPrefix = os.path.dirname( scriptName )
        if not self.__projectPrefix.endswith( os.path.sep ):
            self.__projectPrefix += os.path.sep

        self.__createLayout()
        self.__getDiagramLayout()

        self.__viewer.setScene( self.__scene )
        return

    def setFocus( self ):
        " Sets the focus properly "
        self.__viewer.setFocus()
        return

    def __isOutsideItem( self, fileName ):
        " Detects if the record should be shown as an outside one "
        return not fileName.startswith( self.__projectPrefix )

    def __createLayout( self ):
        " Creates the widget layout "
        totalCalls = self.__stats.total_calls
        totalPrimitiveCalls = self.__stats.prim_calls  # The calls were not induced via recursion
        totalTime = self.__stats.total_tt

        txt = "<b>Script:</b> " + self.__script + " " + self.__params.arguments + "<br>" \
              "<b>Run at:</b> " + self.__reportTime + "<br>" + \
              str( totalCalls ) + " function calls (" + \
              str( totalPrimitiveCalls ) + " primitive calls) in " + \
              FLOAT_FORMAT % totalTime + " CPU seconds"
        summary = QLabel( txt )
        summary.setToolTip( txt )
        summary.setSizePolicy( QSizePolicy.Ignored, QSizePolicy.Fixed )
        summary.setFrameStyle( QFrame.StyledPanel )
        summary.setAutoFillBackground( True )
        summaryPalette = summary.palette()
        summaryBackground = summaryPalette.color( QPalette.Background )
        summaryBackground.setRgb( min( summaryBackground.red() + 30, 255 ),
                                  min( summaryBackground.green() + 30, 255 ),
                                  min( summaryBackground.blue() + 30, 255 ) )
        summaryPalette.setColor( QPalette.Background, summaryBackground )
        summary.setPalette( summaryPalette )

        self.__scene = QGraphicsScene()
        self.__viewer = DiagramWidget()
        self.__viewer.escapePressed.connect( self.__onESC )

        vLayout = QVBoxLayout()
        vLayout.setContentsMargins( 0, 0, 0, 0 )
        vLayout.setSpacing( 0 )
        vLayout.addWidget( summary )
        vLayout.addWidget( self.__viewer )

        self.setLayout( vLayout )
        return


    def __getDiagramLayout( self ):
        " Runs external tools to get the diagram layout "

        # Preparation: build a map of func ID -> fileName + line
        funcMap = {}
        index = 0
        for func, props in self.__stats.stats.items():
            funcMap[ index ] = ( func[ 0 ], func[ 1 ] )
            index += 1

        # First step is to run grpof2dot
        gprof2dot = thirdpartyDir + "gprof2dot" + os.path.sep + "gprof2dot.py"
        outputFile = self.__dataFile + ".dot"
        nodeLimit = Settings().profileNodeLimit
        edgeLimit = Settings().profileEdgeLimit
        dotSpec = safeRun( [ gprof2dot, '-n', str( nodeLimit ),
                             '-e', str( edgeLimit ),
                             '-f', 'pstats', '-o', outputFile,
                             self.__dataFile ] )
        graphDescr = safeRun( [ "dot", "-Tplain", outputFile ] )
        graph = getGraphFromPlainDotData( graphDescr )
        graph.normalize( self.physicalDpiX(), self.physicalDpiY() )

        self.__scene.clear()
        self.__scene.setSceneRect( 0, 0, graph.width, graph.height )

        for edge in graph.edges:
            self.__scene.addItem( FuncConnection( edge ) )
            if edge.label != "":
                self.__scene.addItem( FuncConnectionLabel( edge ) )

        for node in graph.nodes:
            fileName = ""
            lineNumber = 0
            isOutside = True
            nodeID, newLabel = extractNodeID( node.label )
            if nodeID != -1:
                node.label = newLabel

                # Now, detect the file name/line number and
                # if it belongs to the project
                ( fileName, lineNumber ) = funcMap[ nodeID ]
            self.__scene.addItem( Function( node, fileName, lineNumber,
                                            self.__isOutsideItem( fileName ) ) )

        return

    def __onESC( self ):
        " Triggered when ESC is clicked "
        self.escapePressed.emit()
        return

    def onCopy( self ):
        " Copies the diagram to the exchange buffer "
        self.__viewer.onCopy()
        return

    def onSaveAs( self, fileName ):
        " Saves the diagram to a file "
        self.__viewer.onSaveAs( fileName )
        return

    def zoomIn( self ):
        " Triggered on the 'zoom in' button "
        self.__viewer.zoomIn()
        return

    def zoomOut( self ):
        " Triggered on the 'zoom out' button "
        self.__viewer.zoomOut()
        return

    def resetZoom( self ):
        " Triggered on the 'zoom reset' button "
        self.__viewer.resetZoom()
        return
Beispiel #16
0
class GeorefDialog(QDialog, Ui_GeorefDialogBase):
    def __init__(self, types, parent=None):
        super(GeorefDialog, self).__init__(parent)
        self.setupUi(self)

        # Internal variables
        self._closeOnDone = False
        self._types = {}
        self._georeferencer = None

        self._types = types
        self._scene = QGraphicsScene(self)
        self._georeferencer = Georeferencer(self)
        self._georeferencer.status.connect(self._updateStatus)
        self._georeferencer.error.connect(self._updateError)

        # Init the gui
        for group in self._types:
            self.typeCombo.addItem(self._types[group]['name'], group)
        self.typeCombo.setCurrentIndex(0)

        for scale in Scale.Scale:
            self.scaleCombo.addItem(Scale.Label[scale], scale)
        self.scaleCombo.setCurrentIndex(Scale.OneToTwenty)

        self.processButton.clicked.connect(self._process)
        self.saveButton.clicked.connect(self._save)
        self.runButton.clicked.connect(self._run)
        self.closeButton.clicked.connect(self._close)
        self.siteEdit.textChanged.connect(self._updateGeoreference)
        self.typeCombo.currentIndexChanged.connect(self._updateGeoreference)
        self.scaleCombo.currentIndexChanged.connect(self._updateGeoreference)
        self.numberSpin.valueChanged.connect(self._updateGeoreference)
        self.suffixEdit.textChanged.connect(self._updateGeoreference)
        self.eastSpin.valueChanged.connect(self._updateGeoreference)
        self.northSpin.valueChanged.connect(self._updateGeoreference)

    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

    def _loadGcp(self, path):
        gc = Georeferencer.loadGcpFile(path)
        gcTo = Transform()
        for index in gc.points():
            gcp = gc.point(index)
            if gcp.map() == self.gcpWidget1.gcp().map():
                gcTo.setPoint(1, gcp)
            elif gcp.map() == self.gcpWidget2.gcp().map():
                gcTo.setPoint(2, gcp)
            elif gcp.map() == self.gcpWidget3.gcp().map():
                gcTo.setPoint(3, gcp)
            elif gcp.map() == self.gcpWidget4.gcp().map():
                gcTo.setPoint(4, gcp)

        if gcTo.isValid() and len(gcTo.points()) == 4:
            self.gcpWidget1.setRaw(gcTo.point(1).raw())
            self.gcpWidget2.setRaw(gcTo.point(2).raw())
            self.gcpWidget3.setRaw(gcTo.point(3).raw())
            self.gcpWidget4.setRaw(gcTo.point(4).raw())

    def _updateGeoPoints(self):
        mapUnits = Scale.Factor[self.drawingScale()]
        local1 = QPointF(self.eastSpin.value(),
                         self.northSpin.value() + mapUnits)
        local2 = QPointF(self.eastSpin.value(), self.northSpin.value())
        local3 = QPointF(self.eastSpin.value() + mapUnits,
                         self.northSpin.value())
        local4 = QPointF(self.eastSpin.value() + mapUnits,
                         self.northSpin.value() + mapUnits)

        if self.drawingType() == 'sec':
            self.gcpWidget1.setGeo(local1, QgsPoint(local1))
            self.gcpWidget2.setGeo(local2, QgsPoint(local2))
            self.gcpWidget3.setGeo(local3, QgsPoint(local3))
            self.gcpWidget4.setGeo(local4, QgsPoint(local4))
            return

        typ = self._type()
        gridLayer = typ['grid']
        features = gridLayer.getFeatures()
        localX = gridLayer.fieldNameIndex(typ['local_x'])
        localY = gridLayer.fieldNameIndex(typ['local_y'])
        for feature in features:
            local = QPoint(feature.attributes()[localX],
                           feature.attributes()[localY])
            map = geometry.toPoint(feature.geometry().geometry())
            if local == local1:
                self.gcpWidget1.setGeo(local, map)
            elif local == local2:
                self.gcpWidget2.setGeo(local, map)
            elif local == local3:
                self.gcpWidget3.setGeo(local, map)
            elif local == local4:
                self.gcpWidget4.setGeo(local, map)

    def _updateGeoreference(self):
        self._updateFileNames(self.drawing())
        self._updateGeoPoints()

    def _updateFileNames(self, drawing):
        self.rawFileNameLabel.setText(drawing.baseName())
        self.geoFileNameLabel.setText(drawing.baseName() +
                                      self._type()['suffix'])

    def _toggleUi(self, status):
        self.processButton.setEnabled(status)
        self.saveButton.setEnabled(status)
        self.runButton.setEnabled(status)
        self.closeButton.setEnabled(status)
        self.siteEdit.setEnabled(status)
        self.typeCombo.setEnabled(status)
        self.numberSpin.setEnabled(status)
        self.suffixEdit.setEnabled(status)
        self.eastSpin.setEnabled(status)
        self.northSpin.setEnabled(status)
        self.cropCheck.setEnabled(status)
        self.addToMapCheck.setEnabled(status)
        self.gcpWidget1.setEnabled(status)
        self.gcpWidget2.setEnabled(status)
        self.gcpWidget3.setEnabled(status)
        self.gcpWidget4.setEnabled(status)
        self.planView.setEnabled(status)
        if (status):
            self.progressBar.setRange(0, 100)
        else:
            self.progressBar.setRange(0, 0)

    def drawing(self):
        return Drawing(self.item(), self.easting(), self.northing(),
                       self.suffix(), self.rawFileName())

    def item(self):
        return Item(self.siteCode(), self.classCode(), self.itemId())

    def siteCode(self):
        return self.siteEdit.text().strip()

    def classCode(self):
        return self.drawingType()

    def itemId(self):
        return unicode(self.numberSpin.value())

    def drawingType(self):
        return self.typeCombo.itemData(self.typeCombo.currentIndex())

    def drawingScale(self):
        return self.scaleCombo.itemData(self.scaleCombo.currentIndex())

    def easting(self):
        return self.eastSpin.value()

    def northing(self):
        return self.northSpin.value()

    def suffix(self):
        return self.suffixEdit.text().strip()

    def inputFileName(self):
        return self.inputFileNameLabel.text().strip()

    def rawFileName(self):
        return self.rawFileNameLabel.text().strip()

    def rawFileInfo(self):
        return QFileInfo(self._type()['raw'],
                         self.rawFileName() + '.' + self._inputFile.suffix())

    def pointFileInfo(self):
        return QFileInfo(
            self._type()['raw'],
            self.rawFileName() + '.' + self._inputFile.suffix() + '.points')

    def geoFileName(self):
        return self.geoFileNameLabel.text().strip()

    def geoFileInfo(self):
        return QFileInfo(self._type()['geo'], self.geoFileName() + '.tif')

    def _type(self):
        return self._types[self.drawingType()]

    def _updateStatus(self, step, status):
        self._setStatusLabel(step, status)
        self._showStatus(Georeferencer.Label[step] + ': ' +
                         ProcessStatus.Label[status])
        if step == Georeferencer.Stop and status == ProcessStatus.Success:
            if self._closeOnDone:
                self._close()
            else:
                self._toggleUi(True)

    def _updateError(self, step, msg):
        self._setStatusLabel(step, ProcessStatus.Failure)
        self._showStatus(msg)
        self._toggleUi(True)

    def _showStatus(self, text):
        self.statusBar.showMessage(text)

    def _save(self):
        self._copyInputFile()
        self._saveGcp()
        self._close()

    def _copyInputFile(self):
        if self.inputFileName() != self.rawFileName() or self._inputFile.dir(
        ) != self._type()['raw']:
            QFile.copy(self._inputFile.absoluteFilePath(),
                       self.rawFileInfo().absoluteFilePath())

    def _saveGcp(self):
        gc = self._gc()
        if (gc.isValid()):
            Georeferencer.writeGcpFile(gc,
                                       self.pointFileInfo().absoluteFilePath())

    def _run(self):
        self._runGeoreference(False)

    def _process(self):
        self._runGeoreference(True)

    def _close(self):
        if (self._georeferencer.step() == Georeferencer.Stop):
            self.accept()
        else:
            self.reject()

    def _gc(self):
        gc = Transform()
        gc.crs = self._type()['crs']
        gc.setPoint(1, self.gcpWidget1.gcp())
        gc.setPoint(2, self.gcpWidget2.gcp())
        gc.setPoint(3, self.gcpWidget3.gcp())
        gc.setPoint(4, self.gcpWidget4.gcp())
        return gc

    def _runGeoreference(self, closeOnDone):
        self._closeOnDone = closeOnDone
        gc = self._gc()
        if (not gc.isValid()):
            self._showStatus('ERROR: Please set all 4 Ground Control Points!')
            return
        self._toggleUi(False)
        self._copyInputFile()
        QCoreApplication.processEvents()
        self._georeferencer.run(gc, self.rawFileInfo(), self.pointFileInfo(),
                                self.geoFileInfo())

    def _finished(self, step, status):
        if step == Georeferencer.Stop and status == ProcessStatus.Success and self._closeOnDone:
            self._close()
        else:
            self._toggleUi(True)

    def _setStatusLabel(self, step, status):
        if step == 'load':
            label = self.loadStatusLabel
        elif step == Georeferencer.Crop:
            label = self.cropStatusLabel
        elif step == Georeferencer.Translate:
            label = self.translateStatusLabel
        elif step == Georeferencer.Warp:
            label = self.warpStatusLabel
        elif step == Georeferencer.Overview:
            label = self.overviewStatusLabel
        else:
            return

        if status == ProcessStatus.Success:
            label.setPixmap(QPixmap(':/plugins/ark/georef/success.png'))
        elif status == ProcessStatus.Failure:
            label.setPixmap(QPixmap(':/plugins/ark/georef/failure.png'))
        elif status == ProcessStatus.Running:
            label.setPixmap(QPixmap(':/plugins/ark/georef/running.png'))
        else:
            label.setPixmap(QPixmap(':/plugins/ark/georef/unknown.png'))
Beispiel #17
0
            self.bars.append(bar)
            
            if i + 1 == len(values):
                xLabel = scene.addText("X")
            else:
                xLabel = scene.addText("%d" % (i))
            xLabel.setPos(curX + BAR_WIDTH / 2 - xLabel.boundingRect().width() /2, h - xLabel.boundingRect().height())
            self.xLabels.append(xLabel)
            
            barLabel = scene.addText("%d" % (value))
            barLabel.setPos(curX + BAR_WIDTH / 2 - barLabel.boundingRect().width()/2, h - (bottomLine - top) - PADDING - barLabel.boundingRect().height())
            self.barLabels.append(barLabel)
            
            curX += BAR_WIDTH + BAR_PADDING
        
        scene.setSceneRect(0,0,curX + PADDING, SCENE_HEIGHT)
        self.updateGeometry()
    
    def sizeHint(self):
        #import pdb; pdb.set_trace()
        size = self.sceneRect().size()
        return QSize(int(size.width()), int(size.height() + PADDING))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    scene = QGraphicsScene()
    scene.setSceneRect(0,0,500.0,500.0)
    window = QBarGraph()
    window.setValues([50,20,75,205, 15, 400, 6000])
    result = app.exec_()
    sys.exit(result)
Beispiel #18
0
class ProfileGraphViewer(QWidget):
    " Profiling results as a graph "

    escapePressed = pyqtSignal()

    def __init__(self,
                 scriptName,
                 params,
                 reportTime,
                 dataFile,
                 stats,
                 parent=None):
        QWidget.__init__(self, parent)

        self.__dataFile = dataFile
        self.__script = scriptName
        self.__reportTime = reportTime
        self.__params = params
        self.__stats = stats

        project = GlobalData().project
        if project.isLoaded():
            self.__projectPrefix = os.path.dirname(project.fileName)
        else:
            self.__projectPrefix = os.path.dirname(scriptName)
        if not self.__projectPrefix.endswith(os.path.sep):
            self.__projectPrefix += os.path.sep

        self.__createLayout()
        self.__getDiagramLayout()

        self.__viewer.setScene(self.__scene)
        return

    def setFocus(self):
        " Sets the focus properly "
        self.__viewer.setFocus()
        return

    def __isOutsideItem(self, fileName):
        " Detects if the record should be shown as an outside one "
        return not fileName.startswith(self.__projectPrefix)

    def __createLayout(self):
        " Creates the widget layout "
        totalCalls = self.__stats.total_calls
        totalPrimitiveCalls = self.__stats.prim_calls  # The calls were not induced via recursion
        totalTime = self.__stats.total_tt

        txt = "<b>Script:</b> " + self.__script + " " + self.__params.arguments + "<br>" \
              "<b>Run at:</b> " + self.__reportTime + "<br>" + \
              str( totalCalls ) + " function calls (" + \
              str( totalPrimitiveCalls ) + " primitive calls) in " + \
              FLOAT_FORMAT % totalTime + " CPU seconds"
        summary = QLabel(txt)
        summary.setToolTip(txt)
        summary.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        summary.setFrameStyle(QFrame.StyledPanel)
        summary.setAutoFillBackground(True)
        summaryPalette = summary.palette()
        summaryBackground = summaryPalette.color(QPalette.Background)
        summaryBackground.setRgb(min(summaryBackground.red() + 30, 255),
                                 min(summaryBackground.green() + 30, 255),
                                 min(summaryBackground.blue() + 30, 255))
        summaryPalette.setColor(QPalette.Background, summaryBackground)
        summary.setPalette(summaryPalette)

        self.__scene = QGraphicsScene()
        self.__viewer = DiagramWidget()
        self.__viewer.escapePressed.connect(self.__onESC)

        vLayout = QVBoxLayout()
        vLayout.setContentsMargins(0, 0, 0, 0)
        vLayout.setSpacing(0)
        vLayout.addWidget(summary)
        vLayout.addWidget(self.__viewer)

        self.setLayout(vLayout)
        return

    def __getDiagramLayout(self):
        " Runs external tools to get the diagram layout "

        # Preparation: build a map of func ID -> fileName + line
        funcMap = {}
        index = 0
        for func, props in self.__stats.stats.items():
            funcMap[index] = (func[0], func[1])
            index += 1

        # First step is to run grpof2dot
        gprof2dot = thirdpartyDir + "gprof2dot" + os.path.sep + "gprof2dot.py"
        outputFile = self.__dataFile + ".dot"
        nodeLimit = Settings().profileNodeLimit
        edgeLimit = Settings().profileEdgeLimit
        dotSpec = safeRun([
            gprof2dot, '-n',
            str(nodeLimit), '-e',
            str(edgeLimit), '-f', 'pstats', '-o', outputFile, self.__dataFile
        ])
        graphDescr = safeRun(["dot", "-Tplain", outputFile])
        graph = getGraphFromPlainDotData(graphDescr)
        graph.normalize(self.physicalDpiX(), self.physicalDpiY())

        self.__scene.clear()
        self.__scene.setSceneRect(0, 0, graph.width, graph.height)

        for edge in graph.edges:
            self.__scene.addItem(FuncConnection(edge))
            if edge.label != "":
                self.__scene.addItem(FuncConnectionLabel(edge))

        for node in graph.nodes:
            fileName = ""
            lineNumber = 0
            isOutside = True
            nodeID, newLabel = extractNodeID(node.label)
            if nodeID != -1:
                node.label = newLabel

                # Now, detect the file name/line number and
                # if it belongs to the project
                (fileName, lineNumber) = funcMap[nodeID]
            self.__scene.addItem(
                Function(node, fileName, lineNumber,
                         self.__isOutsideItem(fileName)))

        return

    def __onESC(self):
        " Triggered when ESC is clicked "
        self.escapePressed.emit()
        return

    def onCopy(self):
        " Copies the diagram to the exchange buffer "
        self.__viewer.onCopy()
        return

    def onSaveAs(self, fileName):
        " Saves the diagram to a file "
        self.__viewer.onSaveAs(fileName)
        return

    def zoomIn(self):
        " Triggered on the 'zoom in' button "
        self.__viewer.zoomIn()
        return

    def zoomOut(self):
        " Triggered on the 'zoom out' button "
        self.__viewer.zoomOut()
        return

    def resetZoom(self):
        " Triggered on the 'zoom reset' button "
        self.__viewer.resetZoom()
        return
Beispiel #19
0
        
        # Hmm, obviously function needs an explicit add to the scene..
        self.scene.addItem( self.function ) 
        return self.function
    
if __name__ == '__main__':
    import sys

    # this is to be factored out into a general loader.
    app = QApplication(sys.argv)
    
    width = 520
    height = 520
    
    scene = QGraphicsScene()
    scene.setSceneRect(0, 0, width, height)
    
    view = QGraphicsView()
    view.setScene(scene)
    view.setRenderHint(QPainter.Antialiasing)
    
    ccs = CartesianCoordinateSystemWidget(scene, width, height, 10, -5,5,-1,10)
    
    # coordinates are always relative to coordinate system, as it should be
    #point1 = ccs.addPoint(3,3,10)
    #point2 = ccs.addPointDependent(point1,1,1,10)
    #point3 = ccs.addPointDependent(point2,-1,0,10,0,0,100)
    
    function = '2.71**x'
    
    # two points on a function
Beispiel #20
0
class Window(QWidget):
    ''' The MainWindow widget '''
    def __init__(self, game):
        super().__init__()

        self.game = game
        self.game.ui = self

        self.setWindowTitle('WordJuggler')
        self.resize(800, 600)
        self.setStyleSheet('QGroupBox { border:0; font:bold;' +
                           'padding:20px 10px; min-width:220px; }')

        self.board = BoardItem(game.width, game.height)
        self.rack = RackItem(game.rack_size, game.width, game.height)
        self.scene = QGraphicsScene()
        self.scene.setBackgroundBrush(QBrush(QColor('#f9ece0')))
        self.scene.addItem(self.board)
        self.scene.addItem(self.rack)
        self.scene.setSceneRect(self.scene.itemsBoundingRect())
        self.view = BoardView(self.scene, self)
        self.view.letterChanged.connect(self.letterChanged)

        self.ranking = QGroupBox('Rankings')
        self.rankings = QLabel()
        rankings = QVBoxLayout()
        rankings.addWidget(self.rankings)
        self.ranking.setLayout(rankings)

        self.statistic = QGroupBox('Statistics')
        self.statistics = QLabel()
        statistics = QVBoxLayout()
        statistics.addWidget(self.statistics)
        self.statistic.setLayout(statistics)

        self.move = QGroupBox('Last 10 Moves')
        self.moves = QLabel()
        moves = QVBoxLayout()
        moves.addWidget(self.moves)
        self.move.setLayout(moves)

        self.buttons = QVBoxLayout()
        self.buttons.setSpacing(3)
        self.continue_button = QPushButton('Place &Word')
        self.continue_button.setEnabled(False)
        self.continue_button.setFixedSize(130, 25)
        self.continue_button.clicked.connect(self.continueClicked)
        self.pass_button = QPushButton('&Pass')
        self.pass_button.setEnabled(False)
        self.pass_button.setFixedSize(130, 25)
        self.pass_button.clicked.connect(self.passClicked)
        self.exchange_button = QPushButton('&Exchange')
        self.exchange_button.setEnabled(False)
        self.exchange_button.setFixedSize(130, 25)
        self.exchange_button.clicked.connect(self.exchangeClicked)
        self.buttons.addWidget(self.exchange_button, alignment=Qt.AlignCenter)
        self.buttons.addWidget(self.pass_button, alignment=Qt.AlignCenter)
        self.buttons.addWidget(self.continue_button, alignment=Qt.AlignCenter)

        information = QVBoxLayout()
        information.setMargin(20)
        information.setSpacing(20)
        information.addWidget(self.ranking)
        information.addWidget(self.statistic)
        information.addWidget(self.move)
        information.addStretch()
        information.addLayout(self.buttons)

        layout = QHBoxLayout()
        layout.setSpacing(0)
        layout.setMargin(0)
        layout.addWidget(self.view)
        layout.addLayout(information)

        self.setLayout(layout)
        self.show()

        for player in self.game.players:
            player.played_cb = self.playerDone
        self.playerNext()

    def update(self, *args, **kwargs):
        self.rankings.setText(
            '<br>'.join('%i. <font color=%s>%s</font> (%i points)' %
                        (i + 1, player.color, player.name, player.score)
                        for i,player in
                        enumerate(sorted(self.game.players, reverse=True,
                                         key=attrgetter('score')))))
        self.statistics.setText(('Total Players: %i\n' +
                                 'Placed Words: %i\n' +
                                 'Remaining Letters: %i') %
                                (len(self.game.players),
                                 len(list(self.game.board.get_words())),
                                 self.game.letters.remaining_letters))
        moves = []
        for i,(player,move) in list(enumerate(self.game.moves))[-10:]:
            if move[0] == Player.PASS:
                desc = 'Pass'
            elif move[0] == Player.EXCHANGE_LETTERS:
                desc = 'Exchange (%s,%s)' % move[1:]
            else:
                desc = 'Word (%i,%i,%s,%s,%i)' % move[1:]
            moves.append('%i. <font color=%s>%s</font>' % (i + 1, player.color,
                                                           desc))
        self.moves.setText('<br>'.join(moves))

        super().update(*args, **kwargs)

    def letterChanged(self):
        ''' As soon as a letter changes we need to en/disable all controls '''
        self.exchange_button.setEnabled(False)
        self.exchange_button.setText('Exchange')
        if self.game.letters.remaining_letters >= self.game.rack_size:
            selected = ''.join(l.char for l in self.scene.items()
                               if type(l) is LetterItem and l.selected)
            if selected:
                self.exchange_button.setText('Exchange: %s' % selected)
                self.exchange_button.setEnabled(True)
        self.pass_button.setEnabled(True)
        self.continue_button.setEnabled(True if self.board.validNewWord() else
                                        False)

    def playerNext(self):
        player = self.game.next_player()

        self.letterChanged()
        self.update()
        player.update_letters()

        self.rack.name = self.game.current_player.name
        self.rack.color = self.game.current_player.color

        for i,letter in enumerate(player.letters):
            item = LetterItem(letter, self.game.letters.get_score(letter),
                              player.color)
            item.own(self.rack, i, move=False)
            self.scene.addItem(item)

        self.update()
        player.played_cb = self.playerDone
        player.play()

    def continueClicked(self):
        if type(self.game.current_player) is Human:
            self.game.current_player.continue_cb()

    def passClicked(self):
        if type(self.game.current_player) is Human:
            self.game.current_player.pass_cb()

    def exchangeClicked(self):
        if type(self.game.current_player) is Human:
            self.game.current_player.exchange_cb()

    def playerDone(self, player, move, *args):
        self.exchange_button.setEnabled(False)
        self.exchange_button.setText('Exchange')
        self.pass_button.setEnabled(False)
        self.continue_button.setEnabled(False)

        for item in self.scene.items():
            if type(item) is LetterItem and not item.is_safe and \
               not item.deleted:
                item.own(None)
                item.fade()

        for x,y,letter in self.game.board:
            if not self.board.getLetter(x, y):
                item = LetterItem(letter.char,
                                  self.game.letters.get_score(letter),
                                  letter.player.color, safe=True)
                item.own(self.board, x, y, move=False)
                self.scene.addItem(item)

        self.update()

        if self.game.state() == self.game.RUNNING:
            self.game.current_player.update_letters()
            self.playerNext()
        else:
            self.game.finish_score()
            self.update()
            self.gameOver()
        
    def getLetters(self, count, msg=''):
        print('random letters: %s' % self.game.get_letters_old(count))
        while True:
            text,ok = QInputDialog.getText(self, 'New Letters',
                'Player: <font color=%s>%s</font><br>' % (
                self.game.current_player.color, self.game.current_player.name)
                + msg + 'Tell me %i new letters in order to continue..' % count)

            text = ''.join(filter(lambda x: x in self.game.letters.letters,
                                  text.lower()))

            if len(text) == count and all(self.game.letters.available(c) for c
                                          in text):
                return text

    def gameOver(self):
        winner = sorted(self.game.players, reverse=True,
                        key=attrgetter('score'))[0]
        self.dialog = QMessageBox(QMessageBox.Information, 'Game Over',
            ('<b>Game Over!</b><br><br>The player ' +
             '<b><font color=%s>%s</font></b> has won!') %
            (winner.color, winner.name),
            QMessageBox.Ok, self)
        self.dialog.show()
Beispiel #21
0
class SelectByColorDlg(QDialog):
    def __init__(self, color, pieceItems):
        super().__init__()
        self._color = color
        self.resize(800, 800)

        self.scene = QGraphicsScene()
        layout = QVBoxLayout(self)
        self.view = _MyView(self)
        layout.addWidget(self.view)
        self.view.setScene(self.scene)
        self._view_widget = QGLWidget()
        self.view.setViewport(self._view_widget)
        self.view.setMouseTracking(True)

        gry = sum(color) / 3.0
        if (gry < 168):
            bg = [224,]*3
        else:
            bg = [128,]*3
        self.scene.setBackgroundBrush(QBrush(QColor(*bg)))

        self.setup_scene(self.scene, pieceItems)
        d = self.piece_diag
        self.view.scale(60./d, 60./d)

        self._hover_radius = 1.0
        self.selected_item_ids = []

    def setup_scene(self, scene, pieceItems):
        root = self._rootitem = _RootItem(self._color)
        scene.addItem(root)
        # order piece items by color distance of the most similar color
        pairs = [(self._distance(item), item) for item in pieceItems]
        pairs.sort(key = lambda pair: pair[0])

        phi_increment = 0.61803398874 * 2 * pi
        phi = 0.0

        gamma = 1.0
        # scale distance relative to average piece size
        if pairs:
            rect = pairs[0][1].boundingRect()
            diag = (rect.width()**2 + rect.height()**2) ** 0.5
            # take the median piece
            idx = len(pairs) // 2
            meddist = pairs[idx][0]
            meddist = max(meddist, .1)
            scale = 6*diag/(meddist) ** gamma
            self.piece_diag = diag
        else:
            scale = 1.0
            self.piece_diag = 1.0

        self.dist_and_id = []
        for distance, orig_item in pairs:
            item = orig_item.copy_to(root, rotate=False)
            rr = item.boundingRect()
            item.setTransformOriginPoint(rr.center())
            item.setRotation(item.angle_deg)


            item.setPos(
                scale * distance**gamma * cos(phi)-rr.width()*0.5,
                scale * distance**gamma * sin(phi)-rr.height()*0.5
            )
            self.dist_and_id.append((scale*distance**gamma, item.id))
            phi += phi_increment
        self.updateSceneRect()

    def set_hover_radius(self, r):
        self._hover_radius = r
        self.selected_item_ids = [pair[1] for pair in self.dist_and_id if pair[0] < r]
        self._rootitem.sel_size = r
        self._rootitem.update()

    def confirm_result(self):
        self.accept()

    def _distance(self, pieceItem):
        color = self._color
        def dst(c1, c2):
            c1 = rgb2Lab(c1)
            c2 = rgb2Lab(c2)
            return sum((c1i-c2i)**2 for c1i, c2i in zip(c1, c2)) ** 0.5
        if not pieceItem.dominant_colors:
            return 255.0
        return min(dst(color, piececolor) for piececolor in pieceItem.dominant_colors[:4])

    def updateSceneRect(self):
        r = self.scene.itemsBoundingRect()
        w, h = r.width(), r.height()
        a = .05
        r = r.adjusted(-w*a, -h*a, w*a, h*a)
        self.scene.setSceneRect(r)
Beispiel #22
0
class OWQualityControl(widget.OWWidget):
    name = "Quality Control"
    description = "Experiment quality control"
    icon = "../widgets/icons/QualityControl.svg"
    priority = 5000

    inputs = [("Experiment Data", Orange.data.Table, "set_data")]
    outputs = []

    DISTANCE_FUNCTIONS = [("Distance from Pearson correlation",
                           dist_pcorr),
                          ("Euclidean distance",
                           dist_eucl),
                          ("Distance from Spearman correlation",
                           dist_spearman)]

    settingsHandler = SetContextHandler()

    split_by_labels = settings.ContextSetting({})
    sort_by_labels = settings.ContextSetting({})

    selected_distance_index = settings.Setting(0)

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

        ## Attributes
        self.data = None
        self.distances = None
        self.groups = None
        self.unique_pos = None
        self.base_group_index = 0

        ## GUI
        box = gui.widgetBox(self.controlArea, "Info")
        self.info_box = gui.widgetLabel(box, "\n")

        ## Separate By box
        box = gui.widgetBox(self.controlArea, "Separate By")
        self.split_by_model = itemmodels.PyListModel(parent=self)
        self.split_by_view = QListView()
        self.split_by_view.setSelectionMode(QListView.ExtendedSelection)
        self.split_by_view.setModel(self.split_by_model)
        box.layout().addWidget(self.split_by_view)

        self.split_by_view.selectionModel().selectionChanged.connect(
            self.on_split_key_changed)

        ## Sort By box
        box = gui.widgetBox(self.controlArea, "Sort By")
        self.sort_by_model = itemmodels.PyListModel(parent=self)
        self.sort_by_view = QListView()
        self.sort_by_view.setSelectionMode(QListView.ExtendedSelection)
        self.sort_by_view.setModel(self.sort_by_model)
        box.layout().addWidget(self.sort_by_view)

        self.sort_by_view.selectionModel().selectionChanged.connect(
            self.on_sort_key_changed)

        ## Distance box
        box = gui.widgetBox(self.controlArea, "Distance Measure")
        gui.comboBox(box, self, "selected_distance_index",
                     items=[name for name, _ in self.DISTANCE_FUNCTIONS],
                     callback=self.on_distance_measure_changed)

        self.scene = QGraphicsScene()
        self.scene_view = QGraphicsView(self.scene)
        self.scene_view.setRenderHints(QPainter.Antialiasing)
        self.scene_view.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.mainArea.layout().addWidget(self.scene_view)

        self.scene_view.installEventFilter(self)

        self._disable_updates = False
        self._cached_distances = {}
        self._base_index_hints = {}
        self.main_widget = None

        self.resize(800, 600)

    def clear(self):
        """Clear the widget state."""
        self.data = None
        self.distances = None
        self.groups = None
        self.unique_pos = None

        with disable_updates(self):
            self.split_by_model[:] = []
            self.sort_by_model[:] = []

        self.main_widget = None
        self.scene.clear()
        self.info_box.setText("\n")
        self._cached_distances = {}

    def set_data(self, data=None):
        """Set input experiment data."""
        self.closeContext()
        self.clear()

        self.error(0)
        self.warning(0)

        if data is not None:
            keys = self.get_suitable_keys(data)
            if not keys:
                self.error(0, "Data has no suitable feature labels.")
                data = None

        self.data = data
        if data is not None:
            self.on_new_data()

    def update_label_candidates(self):
        """Update the label candidates selection GUI 
        (Group/Sort By views).

        """
        keys = self.get_suitable_keys(self.data)
        with disable_updates(self):
            self.split_by_model[:] = keys
            self.sort_by_model[:] = keys

    def get_suitable_keys(self, data):
        """ Return suitable attr label keys from the data where
        the key has at least two unique values in the data.

        """
        attrs = [attr.attributes.items() for attr in data.domain.attributes]
        attrs = reduce(operator.iadd, attrs, [])
        # in case someone put non string values in attributes dict
        attrs = [(str(key), str(value)) for key, value in attrs]
        attrs = set(attrs)
        values = defaultdict(set)
        for key, value in attrs:
            values[key].add(value)
        keys = [key for key in values if len(values[key]) > 1]
        return keys

    def selected_split_by_labels(self):
        """Return the current selected split labels.
        """
        sel_m = self.split_by_view.selectionModel()
        indices = [r.row() for r in sel_m.selectedRows()]
        return [self.sort_by_model[i] for i in indices]

    def selected_sort_by_labels(self):
        """Return the current selected sort labels
        """
        sel_m = self.sort_by_view.selectionModel()
        indices = [r.row() for r in sel_m.selectedRows()]
        return [self.sort_by_model[i] for i in indices]

    def selected_distance(self):
        """Return the selected distance function.
        """
        return self.DISTANCE_FUNCTIONS[self.selected_distance_index][1]

    def selected_base_group_index(self):
        """Return the selected base group index
        """
        return self.base_group_index

    def selected_base_indices(self, base_group_index=None):
        indices = []
        for g, ind in self.groups:
            if base_group_index is None:
                label = group_label(self.selected_split_by_labels(), g)
                ind = [i for i in ind if i is not None]
                i = self._base_index_hints.get(label, ind[0] if ind else None)
            else:
                i = ind[base_group_index]
            indices.append(i)
        return indices

    def on_new_data(self):
        """We have new data and need to recompute all.
        """
        self.closeContext()

        self.update_label_candidates()
        self.info_box.setText(
            "%s genes \n%s experiments" %
            (len(self.data),  len(self.data.domain.attributes))
        )

        self.base_group_index = 0

        keys = self.get_suitable_keys(self.data)
        self.openContext(keys)

        ## Restore saved context settings (split/sort selection)
        split_by_labels = self.split_by_labels
        sort_by_labels = self.sort_by_labels

        def select(model, selection_model, selected_items):
            """Select items in a Qt item model view
            """
            all_items = list(model)
            try:
                indices = [all_items.index(item) for item in selected_items]
            except:
                indices = []
            for ind in indices:
                selection_model.select(model.index(ind),
                                       QItemSelectionModel.Select)

        with disable_updates(self):
            select(self.split_by_view.model(),
                   self.split_by_view.selectionModel(),
                   split_by_labels)

            select(self.sort_by_view.model(),
                   self.sort_by_view.selectionModel(),
                   sort_by_labels)

        with widget_disable(self):
            self.split_and_update()

    def on_split_key_changed(self, *args):
        """Split key has changed
        """
        with widget_disable(self):
            if not self._disable_updates:
                self.base_group_index = 0
                self.split_by_labels = self.selected_split_by_labels()
                self.split_and_update()

    def on_sort_key_changed(self, *args):
        """Sort key has changed
        """
        with widget_disable(self):
            if not self._disable_updates:
                self.base_group_index = 0
                self.sort_by_labels = self.selected_sort_by_labels()
                self.split_and_update()

    def on_distance_measure_changed(self):
        """Distance measure has changed
        """
        if self.data is not None:
            with widget_disable(self):
                self.update_distances()
                self.replot_experiments()

    def on_view_resize(self, size):
        """The view with the quality plot has changed
        """
        if self.main_widget:
            current = self.main_widget.size()
            self.main_widget.resize(size.width() - 6,
                                    current.height())

            self.scene.setSceneRect(self.scene.itemsBoundingRect())

    def on_rug_item_clicked(self, item):
        """An ``item`` in the quality plot has been clicked.
        """
        update = False
        sort_by_labels = self.selected_sort_by_labels()
        if sort_by_labels and item.in_group:
            ## The item is part of the group
            if item.group_index != self.base_group_index:
                self.base_group_index = item.group_index
                update = True

        else:
            if sort_by_labels:
                # If the user clicked on an background item it
                # invalidates the sorted labels selection
                with disable_updates(self):
                    self.sort_by_view.selectionModel().clear()
                    update = True

            index = item.index
            group = item.group
            label = group_label(self.selected_split_by_labels(), group)

            if self._base_index_hints.get(label, 0) != index:
                self._base_index_hints[label] = index
                update = True

        if update:
            with widget_disable(self):
                self.split_and_update()

    def eventFilter(self, obj, event):
        if obj is self.scene_view and event.type() == QEvent.Resize:
            self.on_view_resize(event.size())
        return super().eventFilter(obj, event)

    def split_and_update(self):
        """
        Split the data based on the selected sort/split labels
        and update the quality plot.

        """
        split_labels = self.selected_split_by_labels()
        sort_labels = self.selected_sort_by_labels()

        self.warning(0)
        if not split_labels:
            self.warning(0, "No separate by label selected.")

        self.groups, self.unique_pos = \
                exp.separate_by(self.data, split_labels,
                                consider=sort_labels,
                                add_empty=True)

        self.groups = sorted(self.groups.items(),
                             key=lambda t: list(map(float_if_posible, t[0])))
        self.unique_pos = sorted(self.unique_pos.items(),
                                 key=lambda t: list(map(float_if_posible, t[0])))

        if self.groups:
            if sort_labels:
                group_base = self.selected_base_group_index()
                base_indices = self.selected_base_indices(group_base)
            else:
                base_indices = self.selected_base_indices()
            self.update_distances(base_indices)
            self.replot_experiments()

    def get_cached_distances(self, measure):
        if measure not in self._cached_distances:
            attrs = self.data.domain.attributes
            mat = numpy.zeros((len(attrs), len(attrs)))

            self._cached_distances[measure] = \
                (mat, set(zip(range(len(attrs)), range(len(attrs)))))

        return self._cached_distances[measure]

    def get_cached_distance(self, measure, i, j):
        matrix, computed = self.get_cached_distances(measure)
        key = (i, j) if i < j else (j, i)
        if key in computed:
            return matrix[i, j]
        else:
            return None

    def get_distance(self, measure, i, j):
        d = self.get_cached_distance(measure, i, j)
        if d is None:
            vec_i = take_columns(self.data, [i])
            vec_j = take_columns(self.data, [j])
            d = measure(vec_i, vec_j)

            mat, computed = self.get_cached_distances(measure)
            mat[i, j] = d
            key = key = (i, j) if i < j else (j, i)
            computed.add(key)
        return d

    def store_distance(self, measure, i, j, dist):
        matrix, computed = self.get_cached_distances(measure)
        key = (i, j) if i < j else (j, i)
        matrix[j, i] = matrix[i, j] = dist
        computed.add(key)

    def update_distances(self, base_indices=()):
        """Recompute the experiment distances.
        """
        distance = self.selected_distance()
        if base_indices == ():
            base_group_index = self.selected_base_group_index()
            base_indices = [ind[base_group_index] \
                            for _, ind in self.groups]

        assert(len(base_indices) == len(self.groups))

        base_distances = []
        attributes = self.data.domain.attributes
        pb = gui.ProgressBar(self, len(self.groups) * len(attributes))

        for (group, indices), base_index in zip(self.groups, base_indices):
            # Base column of the group
            if base_index is not None:
                base_vec = take_columns(self.data, [base_index])
                distances = []
                # Compute the distances between base column
                # and all the rest data columns.
                for i in range(len(attributes)):
                    if i == base_index:
                        distances.append(0.0)
                    elif self.get_cached_distance(distance, i, base_index) is not None:
                        distances.append(self.get_cached_distance(distance, i, base_index))
                    else:
                        vec_i = take_columns(self.data, [i])
                        dist = distance(base_vec, vec_i)
                        self.store_distance(distance, i, base_index, dist)
                        distances.append(dist)
                    pb.advance()

                base_distances.append(distances)
            else:
                base_distances.append(None)

        pb.finish()
        self.distances = base_distances

    def replot_experiments(self):
        """Replot the whole quality plot.
        """
        self.scene.clear()
        labels = []

        max_dist = numpy.nanmax(list(filter(None, self.distances)))
        rug_widgets = []

        group_pen = QPen(Qt.black)
        group_pen.setWidth(2)
        group_pen.setCapStyle(Qt.RoundCap)
        background_pen = QPen(QColor(0, 0, 250, 150))
        background_pen.setWidth(1)
        background_pen.setCapStyle(Qt.RoundCap)

        main_widget = QGraphicsWidget()
        layout = QGraphicsGridLayout()
        attributes = self.data.domain.attributes
        if self.data is not None:
            for (group, indices), dist_vec in zip(self.groups, self.distances):
                indices_set = set(indices)
                rug_items = []
                if dist_vec is not None:
                    for i, attr in enumerate(attributes):
                        # Is this a within group distance or background
                        in_group = i in indices_set
                        if in_group:
                            rug_item = ClickableRugItem(dist_vec[i] / max_dist,
                                           1.0, self.on_rug_item_clicked)
                            rug_item.setPen(group_pen)
                            tooltip = experiment_description(attr)
                            rug_item.setToolTip(tooltip)
                            rug_item.group_index = indices.index(i)
                            rug_item.setZValue(rug_item.zValue() + 1)
                        else:
                            rug_item = ClickableRugItem(dist_vec[i] / max_dist,
                                           0.85, self.on_rug_item_clicked)
                            rug_item.setPen(background_pen)
                            tooltip = experiment_description(attr)
                            rug_item.setToolTip(tooltip)

                        rug_item.group = group
                        rug_item.index = i
                        rug_item.in_group = in_group

                        rug_items.append(rug_item)

                rug_widget = RugGraphicsWidget(parent=main_widget)
                rug_widget.set_rug(rug_items)

                rug_widgets.append(rug_widget)

                label = group_label(self.selected_split_by_labels(), group)
                label_item = QGraphicsSimpleTextItem(label, main_widget)
                label_item = GraphicsSimpleTextLayoutItem(label_item, parent=layout)
                label_item.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
                labels.append(label_item)

        for i, (label, rug_w) in enumerate(zip(labels, rug_widgets)):
            layout.addItem(label, i, 0, Qt.AlignVCenter)
            layout.addItem(rug_w, i, 1)
            layout.setRowMaximumHeight(i, 30)

        main_widget.setLayout(layout)
        self.scene.addItem(main_widget)
        self.main_widget = main_widget
        self.rug_widgets = rug_widgets
        self.labels = labels
        self.on_view_resize(self.scene_view.size())
Beispiel #23
0
class Level(QFrame):
    def __init__(self, parent):
        QFrame.__init__(self,parent)

        self.filename = QString()
        self.copiedItem = QByteArray()
        self.pasteOffset = 5
        self.prevPoint = QPoint()
        self.addOffset = 5
        
        self.screenSize = (320, 240)
        self.bgColor = QColor(244,244,244)
        '''0.Portrait 1.Landscape'''
        self.orientation = 0
        self.currentItem = None
        

        self.printer = QPrinter(QPrinter.HighResolution)
        self.printer.setPageSize(QPrinter.Letter)


        '''1.Header'''
        self.levelBar = LevelBar(self)
        
        '''3.Tiler'''
        self.tiler = TileMapGrid(self)#Tiler(self)
        self.tiler.setMinimumHeight(100)
        #self.tiler.currentChanged.connect(self.closeDesigner)
        #self.tiler.setTabsClosable(True)
        #self.tiler.setTabShape(0)
        #self.tiler.hide()
        #self.levelLayout.addWidget(self.levelBar) 
        
        '''2.view'''
        viewLayoutWidget = QFrame()
        viewLayoutWidget.setFrameShape(QFrame.StyledPanel)
        viewLayout = QHBoxLayout(viewLayoutWidget)
        #viewLayout.setMargin(10)
        self.view = LevelView(viewLayoutWidget)
        '''scene'''
        self.scene = QGraphicsScene(self)
        #self.scene.selectionChanged.connect(self.setConnect)
        #self.view.setStyleSheet("border: 1px solid red;")
        
        self.setBackgroundColor(self.bgColor)
        self.setScreenSize(self.screenSize)
        
        self.view.setScene(self.scene)
        self.view.setAlignment(Qt.AlignCenter)
        self.scroll_off = 1
        self.setScrollBar()
        
        viewLayout.setMargin(0)
        viewLayout.addWidget(self.view)

        self.wrapped = [] # Needed to keep wrappers alive
        layout = QVBoxLayout(self)
        layout.addWidget(self.levelBar)
        layout.addWidget(viewLayoutWidget)
        layout.addWidget(self.tiler)
        layout.setMargin(0)
        self.setLayout(layout)
        
    def setScrollBar(self):
        if(self.scroll_off):
            self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.scroll_off = 0
        else:
            self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
            self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
            self.scroll_off = 1
        
    def setBackgroundColor(self,color):
        self.bgColor = color
        self.scene.setBackgroundBrush(QBrush(color))
        
    def setScreenSize(self,size):
        self.screenSize = size
        self.setOrientation(self.orientation)
        
    def setOrientation(self,idx):
        self.orientation = idx
        if(idx == 0):
            self.view.setMaximumSize(self.screenSize[1], self.screenSize[0])
            self.scene.setSceneRect(0, 0, self.screenSize[1], self.screenSize[0])
        else:
            self.view.setMaximumSize(self.screenSize[0], self.screenSize[1])
            self.scene.setSceneRect(0, 0, self.screenSize[0], self.screenSize[1])
        
    def offerSave(self):
        if (Dirty and QMessageBox.question(self,
                            "Designer - Unsaved Changes",
                            "Save unsaved changes?",
                            QMessageBox.Yes|QMessageBox.No) == 
           QMessageBox.Yes):
            self.save()


    def position(self):
        point = self.mapFromGlobal(QCursor.pos())
        if not self.view.geometry().contains(point):
            coord = random.randint(36, 144)
            point = QPoint(coord, coord)
        else:
            if point == self.prevPoint:
                point += QPoint(self.addOffset, self.addOffset)
                self.addOffset += 5
            else:
                self.addOffset = 5
                self.prevPoint = point
        return self.view.mapToScene(point)
    
    def selectedItem(self):
        items = self.scene.selectedItems()
        if len(items) == 1:
            return items[0]
        return None
    
    def current(self,item):
        self.scene.clearSelection()
        sceneItems = self.scene.items()
        for items in sceneItems:
            if(items != item):
                item.setSelected(False)
                if(item.isConnected()):
                    self.propertyBar.disconnectText(item)
                    item.setConnected(False)
        self.currentItem = item
        self.currentItem.setConnected(True)
        self.currentItem.setSelected(True)
        self.propertyBar.connectText(self.currentItem)
        self.propertyBar.initText(self.currentItem)


    def addText(self):
        item = TextItem("SomeText", self.position())
        self.connect(item, SIGNAL("current"),self.current)
        self.connect(item, SIGNAL("copy"),self.copy)
        self.connect(item, SIGNAL("cut"),self.cut)
        self.connect(item, SIGNAL("paste"),self.paste)
        self.connect(item, SIGNAL("delete"),self.delete)
        #self.current(item)
        self.scene.addItem(item)
        

    def copy(self):
        item = self.selectedItem()
        if item is None:
            return
        self.copiedItem.clear()
        self.pasteOffset = 5
        stream = QDataStream(self.copiedItem, QIODevice.WriteOnly)
        self.writeItemToStream(stream, item)


    def cut(self):
        item = self.selectedItem()
        if item is None:
            return
        self.copy()
        self.scene.removeItem(item)
        del item


    def paste(self):
        if self.copiedItem.isEmpty():
            return
        stream = QDataStream(self.copiedItem, QIODevice.ReadOnly)
        item = self.readItemFromStream(stream, self.pasteOffset)
        self.pasteOffset += 5
        #self.scene.addItem(item)
        
    def delete(self):
        items = self.scene.selectedItems()
        if (len(items) and QMessageBox.question(self,
                "Designer - Delete",
                "Delete {0} item{1}?".format(len(items),
                "s" if len(items) != 1 else ""),
                QMessageBox.Yes|QMessageBox.No) ==
                QMessageBox.Yes):
            while items:
                item = items.pop()
                self.scene.removeItem(item)
                del item
                
    def readItemFromStream(self, stream, offset=0):
        type = QString()
        position = QPointF()
        matrix = QMatrix()
        stream >> type >> position >> matrix
        if offset:
            position += QPointF(offset, offset)
        if type == "Text":
            text = QString()
            font = QFont()
            stream >> text >> font
            self.scene.addItem(TextItem(text, position, font, matrix))
        elif type == "Box":
            rect = QRectF()
            stream >> rect
            style = Qt.PenStyle(stream.readInt16())
            self.scene.addItem(BoxItem(position, style, matrix))
        elif type == "Pixmap":
            pixmap = QPixmap()
            stream >> pixmap
            self.scene.addItem(self.createPixmapItem(pixmap, position, matrix))


    def writeItemToStream(self, stream, item):
        if isinstance(item, QGraphicsTextItem):
            stream << QString("Text") << item.pos() \
                   << item.matrix() << item.toPlainText() << item.font()
        elif isinstance(item, QGraphicsPixmapItem):
            stream << QString("Pixmap") << item.pos() \
                   << item.matrix() << item.pixmap()
        elif isinstance(item, BoxItem):
            stream << QString("Box") << item.pos() \
                   << item.matrix() << item.rect
            stream.writeInt16(item.style)

    def rotate(self):
        for item in self.scene.selectedItems():
            item.rotate(30)


    def print_(self):
        dialog = QPrintDialog(self.printer)
        if dialog.exec_():
            painter = QPainter(self.printer)
            painter.setRenderHint(QPainter.Antialiasing)
            painter.setRenderHint(QPainter.TextAntialiasing)
            self.scene.clearSelection()
            #self.removeBorders()
            self.scene.render(painter)
            #self.addBorders()


    def open(self):
        self.offerSave()
        path = (QFileInfo(self.filename).path()
                if not self.filename.isEmpty() else ".")
        fname = QFileDialog.getOpenFileName(self,
                "Page Designer - Open", path,
                "Page Designer Files (*.pgd)")
        if fname.isEmpty():
            return
        self.filename = fname
        fh = None
        try:
            fh = QFile(self.filename)
            if not fh.open(QIODevice.ReadOnly):
                raise IOError, unicode(fh.errorString())
            items = self.scene.items()
            while items:
                item = items.pop()
                self.scene.removeItem(item)
                del item
            self.addBorders()
            stream = QDataStream(fh)
            stream.setVersion(QDataStream.Qt_4_2)
            magic = stream.readInt32()
            if magic != MagicNumber:
                raise IOError, "not a valid .pgd file"
            fileVersion = stream.readInt16()
            if fileVersion != FileVersion:
                raise IOError, "unrecognised .pgd file version"
            while not fh.atEnd():
                self.readItemFromStream(stream)
        except IOError, e:
            QMessageBox.warning(self, "Page Designer -- Open Error",
                    "Failed to open {0}: {1}".format(self.filename, e))
        finally:
Beispiel #24
0
class GeorefDialog(QDialog, Ui_GeorefDialogBase):

    def __init__(self, types, parent=None):
        super(GeorefDialog, self).__init__(parent)
        self.setupUi(self)

        # Internal variables
        self._closeOnDone = False
        self._types = {}
        self._georeferencer = None

        self._types = types
        self._scene = QGraphicsScene(self)
        self._georeferencer = Georeferencer(self)
        self._georeferencer.status.connect(self._updateStatus)
        self._georeferencer.error.connect(self._updateError)

        # Init the gui
        for group in self._types:
            self.typeCombo.addItem(self._types[group]['name'], group)
        self.typeCombo.setCurrentIndex(0)

        for scale in Scale.Scale:
            self.scaleCombo.addItem(Scale.Label[scale], scale)
        self.scaleCombo.setCurrentIndex(Scale.OneToTwenty)

        self.processButton.clicked.connect(self._process)
        self.saveButton.clicked.connect(self._save)
        self.runButton.clicked.connect(self._run)
        self.closeButton.clicked.connect(self._close)
        self.siteEdit.textChanged.connect(self._updateGeoreference)
        self.typeCombo.currentIndexChanged.connect(self._updateGeoreference)
        self.scaleCombo.currentIndexChanged.connect(self._updateGeoreference)
        self.numberSpin.valueChanged.connect(self._updateGeoreference)
        self.suffixEdit.textChanged.connect(self._updateGeoreference)
        self.eastSpin.valueChanged.connect(self._updateGeoreference)
        self.northSpin.valueChanged.connect(self._updateGeoreference)

    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

    def _loadGcp(self, path):
        gc = Georeferencer.loadGcpFile(path)
        gcTo = Transform()
        for index in gc.points():
            gcp = gc.point(index)
            if gcp.map() == self.gcpWidget1.gcp().map():
                gcTo.setPoint(1, gcp)
            elif gcp.map() == self.gcpWidget2.gcp().map():
                gcTo.setPoint(2, gcp)
            elif gcp.map() == self.gcpWidget3.gcp().map():
                gcTo.setPoint(3, gcp)
            elif gcp.map() == self.gcpWidget4.gcp().map():
                gcTo.setPoint(4, gcp)

        if gcTo.isValid() and len(gcTo.points()) == 4:
            self.gcpWidget1.setRaw(gcTo.point(1).raw())
            self.gcpWidget2.setRaw(gcTo.point(2).raw())
            self.gcpWidget3.setRaw(gcTo.point(3).raw())
            self.gcpWidget4.setRaw(gcTo.point(4).raw())

    def _updateGeoPoints(self):
        mapUnits = Scale.Factor[self.drawingScale()]
        local1 = QPointF(self.eastSpin.value(), self.northSpin.value() + mapUnits)
        local2 = QPointF(self.eastSpin.value(), self.northSpin.value())
        local3 = QPointF(self.eastSpin.value() + mapUnits, self.northSpin.value())
        local4 = QPointF(self.eastSpin.value() + mapUnits, self.northSpin.value() + mapUnits)

        if self.drawingType() == 'sec':
            self.gcpWidget1.setGeo(local1, QgsPoint(local1))
            self.gcpWidget2.setGeo(local2, QgsPoint(local2))
            self.gcpWidget3.setGeo(local3, QgsPoint(local3))
            self.gcpWidget4.setGeo(local4, QgsPoint(local4))
            return

        typ = self._type()
        gridLayer = typ['grid']
        features = gridLayer.getFeatures()
        localX = gridLayer.fieldNameIndex(typ['local_x'])
        localY = gridLayer.fieldNameIndex(typ['local_y'])
        for feature in features:
            local = QPoint(feature.attributes()[localX], feature.attributes()[localY])
            map = geometry.toPoint(feature.geometry().geometry())
            if local == local1:
                self.gcpWidget1.setGeo(local, map)
            elif local == local2:
                self.gcpWidget2.setGeo(local, map)
            elif local == local3:
                self.gcpWidget3.setGeo(local, map)
            elif local == local4:
                self.gcpWidget4.setGeo(local, map)

    def _updateGeoreference(self):
        self._updateFileNames(self.drawing())
        self._updateGeoPoints()

    def _updateFileNames(self, drawing):
        self.rawFileNameLabel.setText(drawing.baseName())
        self.geoFileNameLabel.setText(drawing.baseName() + self._type()['suffix'])

    def _toggleUi(self, status):
        self.processButton.setEnabled(status)
        self.saveButton.setEnabled(status)
        self.runButton.setEnabled(status)
        self.closeButton.setEnabled(status)
        self.siteEdit.setEnabled(status)
        self.typeCombo.setEnabled(status)
        self.numberSpin.setEnabled(status)
        self.suffixEdit.setEnabled(status)
        self.eastSpin.setEnabled(status)
        self.northSpin.setEnabled(status)
        self.cropCheck.setEnabled(status)
        self.addToMapCheck.setEnabled(status)
        self.gcpWidget1.setEnabled(status)
        self.gcpWidget2.setEnabled(status)
        self.gcpWidget3.setEnabled(status)
        self.gcpWidget4.setEnabled(status)
        self.planView.setEnabled(status)
        if (status):
            self.progressBar.setRange(0, 100)
        else:
            self.progressBar.setRange(0, 0)

    def drawing(self):
        return Drawing(self.item(), self.easting(), self.northing(), self.suffix(), self.rawFileName())

    def item(self):
        return Item(self.siteCode(), self.classCode(), self.itemId())

    def siteCode(self):
        return self.siteEdit.text().strip()

    def classCode(self):
        return self.drawingType()

    def itemId(self):
        return unicode(self.numberSpin.value())

    def drawingType(self):
        return self.typeCombo.itemData(self.typeCombo.currentIndex())

    def drawingScale(self):
        return self.scaleCombo.itemData(self.scaleCombo.currentIndex())

    def easting(self):
        return self.eastSpin.value()

    def northing(self):
        return self.northSpin.value()

    def suffix(self):
        return self.suffixEdit.text().strip()

    def inputFileName(self):
        return self.inputFileNameLabel.text().strip()

    def rawFileName(self):
        return self.rawFileNameLabel.text().strip()

    def rawFileInfo(self):
        return QFileInfo(self._type()['raw'], self.rawFileName() + '.' + self._inputFile.suffix())

    def pointFileInfo(self):
        return QFileInfo(self._type()['raw'], self.rawFileName() + '.' + self._inputFile.suffix() + '.points')

    def geoFileName(self):
        return self.geoFileNameLabel.text().strip()

    def geoFileInfo(self):
        return QFileInfo(self._type()['geo'], self.geoFileName() + '.tif')

    def _type(self):
        return self._types[self.drawingType()]

    def _updateStatus(self, step, status):
        self._setStatusLabel(step, status)
        self._showStatus(Georeferencer.Label[step] + ': ' + ProcessStatus.Label[status])
        if step == Georeferencer.Stop and status == ProcessStatus.Success:
            if self._closeOnDone:
                self._close()
            else:
                self._toggleUi(True)

    def _updateError(self, step, msg):
        self._setStatusLabel(step, ProcessStatus.Failure)
        self._showStatus(msg)
        self._toggleUi(True)

    def _showStatus(self, text):
        self.statusBar.showMessage(text)

    def _save(self):
        self._copyInputFile()
        self._saveGcp()
        self._close()

    def _copyInputFile(self):
        if self.inputFileName() != self.rawFileName() or self._inputFile.dir() != self._type()['raw']:
            QFile.copy(self._inputFile.absoluteFilePath(), self.rawFileInfo().absoluteFilePath())

    def _saveGcp(self):
        gc = self._gc()
        if (gc.isValid()):
            Georeferencer.writeGcpFile(gc, self.pointFileInfo().absoluteFilePath())

    def _run(self):
        self._runGeoreference(False)

    def _process(self):
        self._runGeoreference(True)

    def _close(self):
        if (self._georeferencer.step() == Georeferencer.Stop):
            self.accept()
        else:
            self.reject()

    def _gc(self):
        gc = Transform()
        gc.crs = self._type()['crs']
        gc.setPoint(1, self.gcpWidget1.gcp())
        gc.setPoint(2, self.gcpWidget2.gcp())
        gc.setPoint(3, self.gcpWidget3.gcp())
        gc.setPoint(4, self.gcpWidget4.gcp())
        return gc

    def _runGeoreference(self, closeOnDone):
        self._closeOnDone = closeOnDone
        gc = self._gc()
        if (not gc.isValid()):
            self._showStatus('ERROR: Please set all 4 Ground Control Points!')
            return
        self._toggleUi(False)
        self._copyInputFile()
        QCoreApplication.processEvents()
        self._georeferencer.run(gc, self.rawFileInfo(), self.pointFileInfo(), self.geoFileInfo())

    def _finished(self, step, status):
        if step == Georeferencer.Stop and status == ProcessStatus.Success and self._closeOnDone:
            self._close()
        else:
            self._toggleUi(True)

    def _setStatusLabel(self, step, status):
        if step == 'load':
            label = self.loadStatusLabel
        elif step == Georeferencer.Crop:
            label = self.cropStatusLabel
        elif step == Georeferencer.Translate:
            label = self.translateStatusLabel
        elif step == Georeferencer.Warp:
            label = self.warpStatusLabel
        elif step == Georeferencer.Overview:
            label = self.overviewStatusLabel
        else:
            return

        if status == ProcessStatus.Success:
            label.setPixmap(QPixmap(':/plugins/ark/georef/success.png'))
        elif status == ProcessStatus.Failure:
            label.setPixmap(QPixmap(':/plugins/ark/georef/failure.png'))
        elif status == ProcessStatus.Running:
            label.setPixmap(QPixmap(':/plugins/ark/georef/running.png'))
        else:
            label.setPixmap(QPixmap(':/plugins/ark/georef/unknown.png'))
Beispiel #25
0
class MainForm(QDialog):
    def __init__(self, parent=None):
        super(MainForm, self).__init__(parent)
        self.Running = False
        self.scene = QGraphicsScene(self)
        self.scene.setSceneRect(0, 0, SCENESIZEX, SCENESIZEY)
        self.view = QGraphicsView()
        self.view.setRenderHint(QPainter.Antialiasing)
        self.view.setScene(self.scene)
        self.view.setFocusPolicy(Qt.NoFocus)
        #self.zoomSlider = QSlider(Qt.Horizontal)
        #self.zoomSlider.setRange(5, 200)
        #self.zoomSlider.setValue(100)
        self.pauseButton = QPushButton("Pa&use")
        self.quitButton = QPushButton("&Quit")

        layout = QVBoxLayout()
        layout.addWidget(self.view)
        #layout.addWidget(self.zoomSlider)
        layout.addWidget(self.pauseButton)
        layout.addWidget(self.quitButton)
        self.setLayout(layout)

        #self.connect(self.zoomSlider, SIGNAL("valueChanged(int))"),
        #             self.zoom)
        self.connect(self.pauseButton, SIGNAL("clicked()"),
                     self.pauseOrResume)
        self.connect(self.quitButton, SIGNAL("clicked()"), self.accept)
        
        self.readNodes()
        self.zoom(1.0)
        self.populate()
        #self.startTimer(INTERVAL)
        self.setWindowTitle("TdPaleo")
        
    def pauseOrResume(self):
        self.Running = not self.Running
        self.pauseButton.setText("Pa&use" if self.Running else "Res&ume")
        items = self.scene.items()
        for item in items:
            item.setRunning()
    
    def zoom(self, value):
        factor =1/ 1.5
        matrix = self.view.matrix()
        matrix.reset()
        matrix.scale(factor, factor)
        self.view.setMatrix(matrix)
    
    def readNodes(self):
        file = open("tdp_geometry.dat")
        file.readline()
        while True:
            line = file.readline()
            if not line:
                break
            param = line.split(" ")
            if (line != "\n"):
                n = node()
                n.x = float(param[0])
                n.y = 956 - float(param[1])
                n.angle = float(param[2])
                n.d = int(param[3])
                n.type = int(param[4])
                nodes.append(n)

    def populate(self):
        color = QColor(0, 150, 0)
        head = TdPCavallo(color, nodes[0].angle, QPointF(nodes[0].x, nodes[0].y))
        #FIXME AGGIUNGERE POI IL FANTINO AL CAVALLO
        #segment = Segment(color, offset, head)
        self.scene.addItem(head)
        #Running = False
        
    def timerEvent(self, event):
        if not self.Running:
            return
Beispiel #26
0
class ConductorGraph(Plugin):

    _deferred_fit_in_view=Signal()
    _client_list_update_signal=Signal()
    
    def __init__(self, context):
        self._context=context
        super(ConductorGraph, self).__init__(context)
        self.initialised=False
        self.setObjectName('Conductor Graph')
        self._current_dotcode=None
        self._node_items=None
        self._edge_items=None
        self._node_item_events={}
        self._edge_item_events={}
        self._client_info_list={}
        self._widget=QWidget()
        self.cur_selected_client_name = ""
        self.pre_selected_client_name = ""
            
        # factory builds generic dotcode items
        self.dotcode_factory=PydotFactory()
        # self.dotcode_factory=PygraphvizFactory()
        self.dotcode_generator=RosGraphDotcodeGenerator()
        self.dot_to_qt=DotToQtGenerator()
        
        self._graph=ConductorGraphInfo()
        self._graph._reg_event_callback(self._update_client_list)
        self._graph._reg_period_callback(self._set_network_statisics)
        
        rospack=rospkg.RosPack()
        ui_file=os.path.join(rospack.get_path('concert_conductor_graph'), 'ui', 'conductor_graph.ui')
        loadUi(ui_file, self._widget, {'InteractiveGraphicsView': InteractiveGraphicsView})
        self._widget.setObjectName('ConductorGraphUi')

        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number()))

        self._scene=QGraphicsScene()
        self._scene.setBackgroundBrush(Qt.white)
        self._widget.graphics_view.setScene(self._scene)

        #self._widget.refresh_graph_push_button.setIcon(QIcon.fromTheme('view-refresh'))
        self._widget.refresh_graph_push_button.setIcon(QIcon.fromTheme('window-new'))
        self._widget.refresh_graph_push_button.pressed.connect(self._update_conductor_graph)

        self._widget.highlight_connections_check_box.toggled.connect(self._redraw_graph_view)
        self._widget.auto_fit_graph_check_box.toggled.connect(self._redraw_graph_view)
        self._widget.fit_in_view_push_button.setIcon(QIcon.fromTheme('zoom-original'))
        self._widget.fit_in_view_push_button.pressed.connect(self._fit_in_view)

        self._deferred_fit_in_view.connect(self._fit_in_view, Qt.QueuedConnection)
        self._deferred_fit_in_view.emit()
        
        self._widget.tabWidget.currentChanged.connect(self._change_client_tab)
        self._client_list_update_signal.connect(self._update_conductor_graph)
        
        #rospy.Subscriber(concert_msgs.Strings.CONCERT_CLIENT_CHANGES, ConcertClients, self._update_client_list)
        
        context.add_widget(self._widget)
    
    def restore_settings(self, plugin_settings, instance_settings):
        self.initialised=True
        self._refresh_rosgraph()
    def shutdown_plugin(self):
        pass
    
    def _update_conductor_graph(self):
        # re-enable controls customizing fetched ROS graph

        self._refresh_rosgraph()
        self._update_client_tab()

    def _refresh_rosgraph(self):
        if not self.initialised:
            return
        self._update_graph_view(self._generate_dotcode())
        
    def _generate_dotcode(self):
        return self.dotcode_generator.generate_dotcode(rosgraphinst=self._graph,
                                                       dotcode_factory=self.dotcode_factory,
                                                       orientation='LR'
                                                       )
    def _update_graph_view(self, dotcode): 
        #if dotcode==self._current_dotcode:
        #    return
        self._current_dotcode=dotcode
        self._redraw_graph_view()
   
    def _update_client_list(self):
        print "[conductor graph]: _update_client_list"       
        self._client_list_update_signal.emit()
        pass
    
    def _start_service(self,node_name,service_name):
        
        service=self._graph._client_info_list[node_name]['gateway_name']+"/"+service_name  
        info_text='' 
        
        if service_name=='status':
            service_handle=rospy.ServiceProxy(service, Status)
            call_result=service_handle()
            
            info_text="<html>"
            info_text +="<p>-------------------------------------------</p>"
            info_text +="<p><b>application_namespace: </b>" +call_result.application_namespace+"</p>"
            info_text +="<p><b>remote_controller: </b>" +call_result.remote_controller+"</p>"
            info_text +="<p><b>application_status: </b>" +call_result.application_status+"</p>"
            info_text +="</html>"
            self._client_list_update_signal.emit()

        elif service_name=='platform_info':
            service_handle=rospy.ServiceProxy(service, GetPlatformInfo)
            call_result=service_handle()

            info_text = "<html>"
            info_text += "<p>-------------------------------------------</p>"
            info_text += "<p><b>rocon_uri: </b>" + call_result.platform_info.uri + "</p>"
            info_text += "<p><b>concert_version: </b>" + call_result.platform_info.version + "</p>"
            info_text += "</html>"
            self._client_list_update_signal.emit()
            
        elif service_name=='invite':
            #sesrvice
            service_handle=rospy.ServiceProxy(service, Invite) 
            #dialog
            dlg=QDialog(self._widget) 
            dlg.setMinimumSize(400,0)
            dlg.setMaximumSize(400,0)
            dlg.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Expanding)
            #dialog layout
            ver_layout=QVBoxLayout(dlg)           
            ver_layout.setContentsMargins (0,0,0,0)

            dynamic_arg=[]
            dynamic_arg.append(DynamicArgumentLayer(ver_layout,'Remote Target Name',False,[('remote_target_name','string')]))
            dynamic_arg.append(DynamicArgumentLayer(ver_layout,'Application Namespace',False,[('application_namespace','string')]))
            dynamic_arg.append(DynamicArgumentLayer(ver_layout,'Cancel',False,[('cancel','bool')]))
            #button
            button_hor_sub_widget=QWidget()
            button_hor_layout=QHBoxLayout(button_hor_sub_widget)   
                   
            btn_call=QPushButton("Call")
            btn_cancel=QPushButton("cancel")
            
            btn_call.clicked.connect(lambda: dlg.done(0))
            btn_call.clicked.connect(lambda : self._call_invite_service(service,service_handle,dynamic_arg))

            btn_cancel.clicked.connect(lambda: dlg.done(0))
            #add button
            button_hor_layout.addWidget(btn_call)            
            button_hor_layout.addWidget(btn_cancel)
            #add button layout            
            ver_layout.addWidget(button_hor_sub_widget)

            dlg.setVisible(True)        

        elif service_name=='start_app':
            #sesrvice
            service_handle=rospy.ServiceProxy(service, StartApp) 
            #dialog
            dlg=QDialog(self._widget) 
            dlg.setMinimumSize(400,0)
            dlg.setMaximumSize(400,0)
            dlg.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Expanding)
            #dialog layout
            ver_layout=QVBoxLayout(dlg)           
            ver_layout.setContentsMargins (0,0,0,0)

            dynamic_arg=[]
            dynamic_arg.append(DynamicArgumentLayer(ver_layout,'Name',False,[('name','string')]))
            dynamic_arg.append(DynamicArgumentLayer(ver_layout,'Remappings',True,[('remap to','string'),('remap from','string')]))
            #button
            button_hor_sub_widget=QWidget()
            button_hor_layout=QHBoxLayout(button_hor_sub_widget)   
                   
            btn_call=QPushButton("Call")
            btn_cancel=QPushButton("cancel")
            
            btn_call.clicked.connect(lambda: dlg.done(0))
            btn_call.clicked.connect(lambda : self._call_start_app_service(service,service_handle,dynamic_arg))
            
            btn_cancel.clicked.connect(lambda: dlg.done(0))
            #add button
            button_hor_layout.addWidget(btn_call)            
            button_hor_layout.addWidget(btn_cancel)
            #add button layout            
            ver_layout.addWidget(button_hor_sub_widget)

            dlg.setVisible(True)        

        elif service_name=='stop_app':
            service_handle=rospy.ServiceProxy(service, StopApp)
            call_result=service_handle()

            info_text="<html>"
            info_text +="<p>-------------------------------------------</p>"
            info_text +="<p><b>stopped: </b>" +str(call_result.stopped)+"</p>"
            info_text +="<p><b>error_code: </b>" +str(call_result.error_code)+"</p>"
            info_text +="<p><b>message: </b>" +call_result.message+"</p>"
            info_text +="</html>"

            self._update_client_tab()
        else:
            print 'has no service'
            return
        
        # display the result of calling service  
        # get tab widget handle
        service_text_widget=None
        cur_tab_widget=self._widget.tabWidget.currentWidget()        
        
        if cur_tab_widget==None:
            return
            
        object_name='services_text_widget'
        for k in cur_tab_widget.children():
            if k.objectName().count(object_name) >=1 :
                service_text_widget=k
                break
        if service_text_widget==None:
            return
            
        service_text_widget.clear()
        service_text_widget.appendHtml(info_text)

    def _call_invite_service(self,service,service_handle,dynamic_arg):        
        remote_target_name=""
        application_namespace=""
        cancel=False

        for k in dynamic_arg:
            if k.name=='Remote Target Name':
                item_widget=k._get_param_list()[0][0][1]
                remote_target_name=item_widget.toPlainText()
            
            elif k.name=='Application Namespace':
                item_widgetwidget=k._get_param_list()[0][0][1]
                application_namespace=item_widget.toPlainText()
            
            elif k.name=='Cancel':
                item_widget=k._get_param_list()[0][0][1]    
                cancel=item_widget.itemData(item_widget.currentIndex())
        #calling service
        call_result=service_handle(remote_target_name,application_namespace,cancel)
        #status update
        self._client_list_update_signal.emit()
        # display the result of calling service  

        info_text="<html>"
        info_text +="<p>-------------------------------------------</p>"
        info_text +="<p><b>result: </b>" +str(call_result.result)+"</p>"
        info_text +="<p><b>error_code: </b>" +str(call_result.error_code)+"</p>"
        info_text +="<p><b>message: </b>" +call_result.message+"</p>"
        info_text +="</html>"        
        # get tab widget handle
        service_text_widget=None
        cur_tab_widget=self._widget.tabWidget.currentWidget()        
        if cur_tab_widget==None:
            return

        object_name='services_text_widget'
        for k in cur_tab_widget.children():
            if k.objectName().count(object_name) >=1 :
                service_text_widget=k
                break
        if service_text_widget==None:
            return
            
        service_text_widget.clear()
        service_text_widget.appendHtml(info_text)

        pass
    
    def _call_start_app_service(self,service,service_handle,dynamic_arg):
        name=""
        remappings=[]
        for k in dynamic_arg:
            if k.name=='Name':
                name=k._get_param_list()[0][0][1].toPlainText()
            elif k.name=='Remappings':    
                for l in k._get_param_list():
                    remap_to=l[0][1].toPlainText()
                    remap_from=l[1][1].toPlainText()
                    remappings.append(Remapping(remap_to,remap_from))
        #calling service
        call_result=service_handle(name,remappings)
        #status update
        self._client_list_update_signal.emit()

        # display the result of calling service          
        info_text = ''
        info_text="<html>"
        info_text +="<p>-------------------------------------------</p>"
        info_text +="<p><b>started: </b>" +str(call_result.started)+"</p>"
        info_text +="<p><b>error_code: </b>" +str(call_result.error_code)+"</p>"
        info_text +="<p><b>message: </b>" +call_result.message+"</p>"
        info_text +="<p><b>app_namespace: </b>" +call_result.app_namespace+"</p>"
        info_text +="</html>"
        # get tab widget handle
        service_text_widget=None
        cur_tab_widget=self._widget.tabWidget.currentWidget()        
        if cur_tab_widget==None:
            return
        object_name='services_text_widget'
        for k in cur_tab_widget.children():
            if k.objectName().count(object_name) >=1 :
                service_text_widget=k
                break
        if service_text_widget==None:
            return
            
        service_text_widget.clear()
        service_text_widget.appendHtml(info_text)

        pass

    def _update_client_tab(self):
        print '[_update_client_tab]'
        self.pre_selected_client_name = self.cur_selected_client_name
        self._widget.tabWidget.clear()   
        
        for k in self._graph._client_info_list.values(): 
            main_widget=QWidget()
           
            ver_layout=QVBoxLayout(main_widget)
           
            ver_layout.setContentsMargins (9,9,9,9)
            ver_layout.setSizeConstraint (ver_layout.SetDefaultConstraint)
            
            #button layout
            sub_widget=QWidget()
            sub_widget.setAccessibleName('sub_widget')
            btn_grid_layout=QGridLayout(sub_widget)

            btn_grid_layout.setContentsMargins (9,9,9,9)

            btn_grid_layout.setColumnStretch (1, 0)
            btn_grid_layout.setRowStretch (2, 0)

            invite_btn=QPushButton("Invite")
            platform_info_btn=QPushButton("Get Platform Info")
            status_btn=QPushButton("Get Status")
            start_app_btn=QPushButton("Start App")
            stop_app_btn=QPushButton("Stop App")              

            invite_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"invite"))
            platform_info_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"platform_info"))  
            status_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"status"))  
            start_app_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"start_app"))  
            stop_app_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"stop_app"))
                    
            btn_grid_layout.addWidget(invite_btn)
            btn_grid_layout.addWidget(platform_info_btn)
            btn_grid_layout.addWidget(status_btn)
            btn_grid_layout.addWidget(start_app_btn)
            btn_grid_layout.addWidget(stop_app_btn)             
            ver_layout.addWidget(sub_widget)            

            #client information layout
            context_label = QLabel()
            context_label.setText("Client information")
            ver_layout.addWidget(context_label)
            
            app_context_widget=QPlainTextEdit()
            app_context_widget.setObjectName(k["name"]+'_'+'app_context_widget')
            app_context_widget.setAccessibleName('app_context_widget')
            app_context_widget.appendHtml(k["app_context"])
            app_context_widget.setReadOnly(True) 
            
            cursor = app_context_widget.textCursor()
            cursor.movePosition(QTextCursor.Start,QTextCursor.MoveAnchor,0)
            app_context_widget.setTextCursor(cursor)
            ver_layout.addWidget(app_context_widget)
            
            #service layout
            context_label = QLabel()
            context_label.setText("Service result")
            ver_layout.addWidget(context_label)
            
            services_text_widget=QPlainTextEdit()
            services_text_widget.setObjectName(k["name"]+'_'+'services_text_widget')
            services_text_widget.setReadOnly(True) 
            cursor = services_text_widget.textCursor()
            cursor.movePosition(QTextCursor.Start,QTextCursor.MoveAnchor,0)
            services_text_widget.setTextCursor(cursor)            
            ver_layout.addWidget(services_text_widget)
            
            # new icon
            path=""
            if k["is_new"]==True:
                path=os.path.join(os.path.dirname(os.path.abspath(__file__)),"../../resources/images/new.gif")            

            #add tab
            self._widget.tabWidget.addTab(main_widget,QIcon(path), k["name"]);

        #set previous selected tab
        for k in range(self._widget.tabWidget.count()):
            tab_text=self._widget.tabWidget.tabText(k)
            if tab_text == self.pre_selected_client_name:
                self._widget.tabWidget.setCurrentIndex(k)

    def _change_client_tab(self,index):
        self.cur_selected_client_name = self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex())
        if self._widget.tabWidget.widget(index) !=None:
            for k in  self._widget.tabWidget.widget(index).children():
                if k.objectName().count("services_text_widget"):
                    k.clear()
        pass    
        
    def _set_network_statisics(self):
        if self._edge_items == None:
            return
        else:
            for edge_items in self._edge_items.itervalues():
                for edge_item in edge_items:
                     edge_dst_name=edge_item.to_node._label.text()
                     edge_item.setToolTip(str(self._graph._client_info_list[edge_dst_name]['conn_stats']))
                     
    def _redraw_graph_view(self):
        self._scene.clear()
        self._node_item_events={}
        self._edge_item_events={}
        self._node_items=None
        self._edge_items=None

        if self._widget.highlight_connections_check_box.isChecked():
            highlight_level=3
        else:
            highlight_level=1
            
        highlight_level=3 if self._widget.highlight_connections_check_box.isChecked() else 1

        # layout graph and create qt items
        (nodes, edges)=self.dot_to_qt.dotcode_to_qt_items(self._current_dotcode,
                                                            highlight_level=highlight_level,
                                                            same_label_siblings=True)
        self._node_items=nodes
        self._edge_items=edges

        # if we wish to make special nodes, do that here (maybe subclass GraphItem, just like NodeItem does)
        #node
        for node_item in nodes.itervalues():
            # set the color of conductor to orange           
            if node_item._label.text()==self._graph._concert_conductor_name:
                royal_blue=QColor(65, 105, 255)
                node_item._default_color=royal_blue
                node_item.set_color(royal_blue)

            # redefine mouse event
            self._node_item_events[node_item._label.text()]=GraphEventHandler(self._widget.tabWidget,node_item,node_item.mouseDoubleClickEvent);
            node_item.mouseDoubleClickEvent=self._node_item_events[node_item._label.text()].NodeEvent;
            
            self._scene.addItem(node_item)
            
        #edge
        for edge_items in edges.itervalues():
            for edge_item in edge_items:
                #redefine the edge hover event
                
                self._edge_item_events[edge_item._label.text()]=GraphEventHandler(self._widget.tabWidget,edge_item,edge_item._label.hoverEnterEvent);
                edge_item._label.hoverEnterEvent =self._edge_item_events[edge_item._label.text()].EdgeEvent;
                
                #self._edge_item_events[edge_item._label.text()]=GraphEventHandler(self._widget.tabWidget,edge_item,edge_item.mouseDoubleClickEvent);
                #edge_item.mouseDoubleClickEvent=self._edge_item_events[edge_item._label.text()].EdgeEvent;

                edge_item.add_to_scene(self._scene)

                #set the color of node as connection strength one of red, yellow, green
                edge_dst_name=edge_item.to_node._label.text()
                if edge_dst_name in self._graph._client_info_list.keys():
                  connection_strength=self._graph._client_info_list[edge_dst_name]['connection_strength']
                  if connection_strength=='very_strong':
                      green=QColor(0, 255, 0)
                      edge_item._default_color=green
                      edge_item.set_color(green)

                  elif connection_strength=='strong':
                      green_yellow=QColor(125, 255,0)
                      edge_item._default_color=green_yellow
                      edge_item.set_color(green_yellow)
                        
                  elif connection_strength=='normal':
                      yellow=QColor(238, 238,0)
                      edge_item._default_color=yellow
                      edge_item.set_color(yellow)

                  elif connection_strength=='weak':
                      yellow_red=QColor(255, 125,0)
                      edge_item._default_color=yellow_red
                      edge_item.set_color(yellow_red)
                      
                  elif connection_strength=='very_weak':
                      red=QColor(255, 0,0)
                      edge_item._default_color=red
                      edge_item.set_color(red)
                #set the tooltip about network information
                edge_item.setToolTip(str(self._graph._client_info_list[edge_dst_name]['conn_stats']))    

        self._scene.setSceneRect(self._scene.itemsBoundingRect())
  
        if self._widget.auto_fit_graph_check_box.isChecked():
            self._fit_in_view()

    def _fit_in_view(self):
        self._widget.graphics_view.fitInView(self._scene.itemsBoundingRect(), Qt.KeepAspectRatio)
Beispiel #27
0
class MainWindow(QMainWindow, Ui_MainWindow):
    """
    Class documentation goes here.
    """
    def __init__(self, parent=None):
        """
        Constructor
        """
        QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.countBattle = 0
        self.timer = QTimer()
        self.tableWidget.horizontalHeader().setResizeMode(
            QtGui.QHeaderView.Stretch)
        self.tableWidget.hide()

    @pyqtSignature("")
    def on_pushButton_clicked(self):
        """
        Start the last battle
        """

        with open(os.getcwd() + "/.datas/lastArena", 'rb') as file:
            unpickler = pickle.Unpickler(file)
            dico = unpickler.load()
        file.close()

        self.setUpBattle(dico["width"], dico["height"], dico["botList"])

    def setUpBattle(self, width, height, botList):
        self.tableWidget.clearContents()
        self.tableWidget.hide()
        self.graphicsView.show()
        self.width = width
        self.height = height
        self.botList = botList
        self.statisticDico = {}
        for bot in botList:
            self.statisticDico[self.repres(bot)] = statistic()
        self.startBattle()

    def startBattle(self):

        try:
            self.disconnect(self.timer, SIGNAL("timeout()"),
                            self.scene.advance)
            del self.timer
            del self.scene
            del self.sceneMenu
        except:
            pass

        self.timer = QTimer()
        self.countBattle += 1
        self.sceneMenu = QGraphicsScene()
        self.graphicsView_2.setScene(self.sceneMenu)
        self.scene = Graph(self, self.width, self.height)
        self.graphicsView.setScene(self.scene)
        self.scene.AddRobots(self.botList)
        self.connect(self.timer, SIGNAL("timeout()"), self.scene.advance)
        self.timer.start((self.horizontalSlider.value()**2) / 100.0)
        self.resizeEvent()

    @pyqtSignature("int")
    def on_horizontalSlider_valueChanged(self, value):
        """
        Slot documentation goes here.
        """
        self.timer.setInterval((value**2) / 100.0)

    @pyqtSignature("")
    def on_actionNew_activated(self):
        """
        Battle Menu
        """
        self.battleMenu = Battle(self)
        self.battleMenu.show()

    @pyqtSignature("")
    def on_actionNew_2_activated(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        print("Not Implemented Yet")

    @pyqtSignature("")
    def on_actionOpen_activated(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        print("Not Implemented Yet")

    def resizeEvent(self, evt=None):
        try:
            self.graphicsView.fitInView(self.scene.sceneRect(), 4)
        except:
            pass

    def addRobotInfo(self, robot):
        self.sceneMenu.setSceneRect(0, 0, 170, 800)
        rb = RobotInfo()
        rb.pushButton.setText(str(robot))
        rb.progressBar.setValue(100)
        rb.robot = robot
        robot.info = rb
        robot.progressBar = rb.progressBar
        robot.icon = rb.toolButton
        robot.icon2 = rb.toolButton_2
        p = self.sceneMenu.addWidget(rb)
        l = (len(self.scene.aliveBots))
        self.sceneMenu.setSceneRect(0, 0, 170, l * 80)
        p.setPos(0, (l - 1) * 80)

    def chooseAction(self):
        if self.countBattle >= self.spinBox.value():
            "Menu Statistic"
            self.graphicsView.hide()
            self.tableWidget.show()
            self.tableWidget.setRowCount(len(self.statisticDico))
            i = 0
            for key, value in self.statisticDico.items():
                self.tableWidget.setItem(i, 0, QtGui.QTableWidgetItem(key))
                self.tableWidget.setItem(
                    i, 1, QtGui.QTableWidgetItem(str(value.first)))
                self.tableWidget.setItem(
                    i, 2, QtGui.QTableWidgetItem(str(value.second)))
                self.tableWidget.setItem(
                    i, 3, QtGui.QTableWidgetItem(str(value.third)))
                self.tableWidget.setItem(
                    i, 4, QtGui.QTableWidgetItem(str(value.points)))

                i += 1

            self.countBattle = 0
            self.timer.stop()
        else:
            self.startBattle()

    def repres(self, bot):
        repres = repr(bot).split(".")
        return repres[1].replace("'>", "")
class ImagesPreviewer(foundations.ui.common.QWidgetFactory(uiFile=UI_FILE)):
	"""
	| This class provides the Application images previewer.
	| It defines methods to navigate through the list of given images ( List of images paths ),
		zoom in / out and fit the displayed image, etc...
	"""

	def __init__(self, parent, paths=None, *args, **kwargs):
		"""
		This method initializes the class.

		:param parent: Object parent. ( QObject )
		:param paths: Images paths. ( Tuple / List )
		:param \*args: Arguments. ( \* )
		:param \*\*kwargs: Keywords arguments. ( \*\* )
		"""

		LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__))

		super(ImagesPreviewer, self).__init__(parent, *args, **kwargs)

		# --- Setting class attributes. ---
		self.__container = parent
		self.__paths = None
		self.paths = paths

		self.__uiResourcesDirectory = "resources"
		self.__uiResourcesDirectory = os.path.join(os.path.dirname(__file__), self.__uiResourcesDirectory)
		self.__uiPreviousImage = "Previous.png"
		self.__uiNextImage = "Next.png"
		self.__uiZoomOutImage = "Zoom_Out.png"
		self.__uiZoomInImage = "Zoom_In.png"

		# Ensure the ui object is destroyed on close to avoid memory leaks.
		self.setAttribute(Qt.WA_DeleteOnClose)

		self.__graphicsSceneBackgroundColor = QColor(32, 32, 32)
		self.__minimumZoomFactor = 0.05
		self.__maximumZoomFactor = 25
		self.__displayGraphicsItemMargin = 32
		self.__graphicsSceneWidth = QApplication.desktop().screenGeometry(
								QApplication.desktop().primaryScreen()).width() * (1 / self.__minimumZoomFactor * 1.75)
		self.__graphicsSceneHeight = QApplication.desktop().screenGeometry(
								QApplication.desktop().primaryScreen()).height() * (1 / self.__minimumZoomFactor * 1.75)
		self.__wheelZoomFactor = 350.0
		self.__keyZoomFactor = 1.20

		self.__graphicsView = None
		self.__graphicsScene = None
		self.__displayGraphicsItem = None

		ImagesPreviewer.__initializeUi(self)

		self.loadImage()

	#******************************************************************************************************************
	#***	Attributes properties.
	#******************************************************************************************************************
	@property
	def container(self):
		"""
		This method is the property for **self.__container** attribute.

		:return: self.__container. ( QObject )
		"""

		return self.__container

	@container.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def container(self, value):
		"""
		This method is the setter method for **self.__container** attribute.

		:param value: Attribute value. ( QObject )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "container"))

	@container.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def container(self):
		"""
		This method is the deleter method for **self.__container** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "container"))

	@property
	def paths(self):
		"""
		This method is the property for **self.__paths** attribute.

		:return: self.__paths. ( Tuple / List )
		"""

		return self.__paths

	@paths.setter
	@foundations.exceptions.handleExceptions(AssertionError)
	def paths(self, value):
		"""
		This method is the setter method for **self.__paths** attribute.

		:param value: Attribute value. ( Tuple / List )
		"""

		if value is not None:
			assert type(value) in (tuple, list), "'{0}' attribute: '{1}' type is not 'tuple' or 'list'!".format("paths", value)
			for element in value:
				assert type(element) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
				"paths", element)
		self.__paths = value

	@paths.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def paths(self):
		"""
		This method is the deleter method for **self.__paths** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "paths"))

	@property
	def uiResourcesDirectory(self):
		"""
		This method is the property for **self.__uiResourcesDirectory** attribute.

		:return: self.__uiResourcesDirectory. ( String )
		"""

		return self.__uiResourcesDirectory

	@uiResourcesDirectory.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def uiResourcesDirectory(self, value):
		"""
		This method is the setter method for **self.__uiResourcesDirectory** attribute.

		:param value: Attribute value. ( String )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "uiResourcesDirectory"))

	@uiResourcesDirectory.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def uiResourcesDirectory(self):
		"""
		This method is the deleter method for **self.__uiResourcesDirectory** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiResourcesDirectory"))

	@property
	def uiPreviousImage(self):
		"""
		This method is the property for **self.__uiPreviousImage** attribute.

		:return: self.__uiPreviousImage. ( String )
		"""

		return self.__uiPreviousImage

	@uiPreviousImage.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def uiPreviousImage(self, value):
		"""
		This method is the setter method for **self.__uiPreviousImage** attribute.

		:param value: Attribute value. ( String )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "uiPreviousImage"))

	@uiPreviousImage.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def uiPreviousImage(self):
		"""
		This method is the deleter method for **self.__uiPreviousImage** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiPreviousImage"))

	@property
	def uiNextImage(self):
		"""
		This method is the property for **self.__uiNextImage** attribute.

		:return: self.__uiNextImage. ( String )
		"""

		return self.__uiNextImage

	@uiNextImage.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def uiNextImage(self, value):
		"""
		This method is the setter method for **self.__uiNextImage** attribute.

		:param value: Attribute value. ( String )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "uiNextImage"))

	@uiNextImage.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def uiNextImage(self):
		"""
		This method is the deleter method for **self.__uiNextImage** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiNextImage"))

	@property
	def uiZoomOutImage(self):
		"""
		This method is the property for **self.__uiZoomOutImage** attribute.

		:return: self.__uiZoomOutImage. ( String )
		"""

		return self.__uiZoomOutImage

	@uiZoomOutImage.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def uiZoomOutImage(self, value):
		"""
		This method is the setter method for **self.__uiZoomOutImage** attribute.

		:param value: Attribute value. ( String )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "uiZoomOutImage"))

	@uiZoomOutImage.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def uiZoomOutImage(self):
		"""
		This method is the deleter method for **self.__uiZoomOutImage** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiZoomOutImage"))

	@property
	def uiZoomInImage(self):
		"""
		This method is the property for **self.__uiZoomInImage** attribute.

		:return: self.__uiZoomInImage. ( String )
		"""

		return self.__uiZoomInImage

	@uiZoomInImage.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def uiZoomInImage(self, value):
		"""
		This method is the setter method for **self.__uiZoomInImage** attribute.

		:param value: Attribute value. ( String )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "uiZoomInImage"))

	@uiZoomInImage.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def uiZoomInImage(self):
		"""
		This method is the deleter method for **self.__uiZoomInImage** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiZoomInImage"))

	@property
	def graphicsSceneBackgroundColor(self):
		"""
		This method is the property for **self.__graphicsSceneBackgroundColor** attribute.

		:return: self.__graphicsSceneBackgroundColor. ( QColors )
		"""

		return self.__graphicsSceneBackgroundColor

	@graphicsSceneBackgroundColor.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def graphicsSceneBackgroundColor(self, value):
		"""
		This method is the setter method for **self.__graphicsSceneBackgroundColor** attribute.

		:param value: Attribute value. ( QColors )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "graphicsSceneBackgroundColor"))

	@graphicsSceneBackgroundColor.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def graphicsSceneBackgroundColor(self):
		"""
		This method is the deleter method for **self.__graphicsSceneBackgroundColor** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "graphicsSceneBackgroundColor"))

	@property
	def graphicsSceneWidth(self):
		"""
		This method is the property for **self.__graphicsSceneWidth** attribute.

		:return: self.__graphicsSceneWidth. ( Integer )
		"""

		return self.__graphicsSceneWidth

	@graphicsSceneWidth.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def graphicsSceneWidth(self, value):
		"""
		This method is the setter method for **self.__graphicsSceneWidth** attribute.

		:param value: Attribute value. ( Integer )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "graphicsSceneWidth"))

	@graphicsSceneWidth.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def graphicsSceneWidth(self):
		"""
		This method is the deleter method for **self.__graphicsSceneWidth** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "graphicsSceneWidth"))

	@property
	def graphicsSceneHeight(self):
		"""
		This method is the property for **self.__graphicsSceneHeight** attribute.

		:return: self.__graphicsSceneHeight. ( Object )
		"""

		return self.__graphicsSceneHeight

	@graphicsSceneHeight.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def graphicsSceneHeight(self, value):
		"""
		This method is the setter method for **self.__graphicsSceneHeight** attribute.

		:param value: Attribute value. ( Object )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "graphicsSceneHeight"))

	@graphicsSceneHeight.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def graphicsSceneHeight(self):
		"""
		This method is the deleter method for **self.__graphicsSceneHeight** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "graphicsSceneHeight"))

	@property
	def minimumZoomFactor(self):
		"""
		This method is the property for **self.__minimumZoomFactor** attribute.

		:return: self.__minimumZoomFactor. ( Float )
		"""

		return self.__minimumZoomFactor

	@minimumZoomFactor.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def minimumZoomFactor(self, value):
		"""
		This method is the setter method for **self.__minimumZoomFactor** attribute.

		:param value: Attribute value. ( Float )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "minimumZoomFactor"))

	@minimumZoomFactor.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def minimumZoomFactor(self):
		"""
		This method is the deleter method for **self.__minimumZoomFactor** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "minimumZoomFactor"))

	@property
	def maximumZoomFactor(self):
		"""
		This method is the property for **self.__maximumZoomFactor** attribute.

		:return: self.__maximumZoomFactor. ( Float )
		"""

		return self.__maximumZoomFactor

	@maximumZoomFactor.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def maximumZoomFactor(self, value):
		"""
		This method is the setter method for **self.__maximumZoomFactor** attribute.

		:param value: Attribute value. ( Float )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "maximumZoomFactor"))

	@maximumZoomFactor.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def maximumZoomFactor(self):
		"""
		This method is the deleter method for **self.__maximumZoomFactor** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "maximumZoomFactor"))

	@property
	def wheelZoomFactor(self):
		"""
		This method is the property for **self.__wheelZoomFactor** attribute.

		:return: self.__wheelZoomFactor. ( Float )
		"""

		return self.__wheelZoomFactor

	@wheelZoomFactor.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def wheelZoomFactor(self, value):
		"""
		This method is the setter method for **self.__wheelZoomFactor** attribute.

		:param value: Attribute value. ( Float )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "wheelZoomFactor"))

	@wheelZoomFactor.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def wheelZoomFactor(self):
		"""
		This method is the deleter method for **self.__wheelZoomFactor** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "wheelZoomFactor"))

	@property
	def keyZoomFactor(self):
		"""
		This method is the property for **self.__keyZoomFactor** attribute.

		:return: self.__keyZoomFactor. ( Float )
		"""

		return self.__keyZoomFactor

	@keyZoomFactor.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def keyZoomFactor(self, value):
		"""
		This method is the setter method for **self.__keyZoomFactor** attribute.

		:param value: Attribute value. ( Float )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "keyZoomFactor"))

	@keyZoomFactor.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def keyZoomFactor(self):
		"""
		This method is the deleter method for **self.__keyZoomFactor** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "keyZoomFactor"))

	@property
	def graphicsView(self):
		"""
		This method is the property for **self.__graphicsView** attribute.

		:return: self.__graphicsView. ( QGraphicsView )
		"""

		return self.__graphicsView

	@graphicsView.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def graphicsView(self, value):
		"""
		This method is the setter method for **self.__graphicsView** attribute.

		:param value: Attribute value. ( QGraphicsView )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "graphicsView"))

	@graphicsView.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def graphicsView(self):
		"""
		This method is the deleter method for **self.__graphicsView** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "graphicsView"))

	@property
	def graphicsScene(self):
		"""
		This method is the property for **self.__graphicsScene** attribute.

		:return: self.__graphicsScene. ( QGraphicsScene )
		"""

		return self.__graphicsScene

	@graphicsScene.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def graphicsScene(self, value):
		"""
		This method is the setter method for **self.__graphicsScene** attribute.

		:param value: Attribute value. ( QGraphicsScene )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "graphicsScene"))

	@graphicsScene.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def graphicsScene(self):
		"""
		This method is the deleter method for **self.__graphicsScene** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "graphicsScene"))

	@property
	def displayGraphicsItem(self):
		"""
		This method is the property for **self.__displayGraphicsItem** attribute.

		:return: self.__displayGraphicsItem. ( QGraphicsItem )
		"""

		return self.__displayGraphicsItem

	@displayGraphicsItem.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def displayGraphicsItem(self, value):
		"""
		This method is the setter method for **self.__displayGraphicsItem** attribute.

		:param value: Attribute value. ( QGraphicsItem )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "displayGraphicsItem"))

	@displayGraphicsItem.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def displayGraphicsItem(self):
		"""
		This method is the deleter method for **self.__displayGraphicsItem** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "displayGraphicsItem"))

	#******************************************************************************************************************
	#***	Class methods.
	#******************************************************************************************************************
	def show(self):
		"""
		This method reimplements the :meth:`QWidget.show` method.
		"""

		super(ImagesPreviewer, self).show()

		foundations.ui.common.centerWidgetOnScreen(self)

	def closeEvent(self, event):
		"""
		This method reimplements the :meth:`QWidget.closeEvent` method.

		:param event: QEvent ( QEvent )
		"""

		LOGGER.debug("> Removing '{0}' from Images Previewers list.".format(self))
		self.__container.imagesPreviewers.remove(self)

		event.accept()

	def wheelEvent(self, event):
		"""
		This method reimplements the :meth:`QWidget.wheelEvent` method.

		:param event: QEvent ( QEvent )
		"""

		self.scaleView(pow(1.5, event.delta() / self.__wheelZoomFactor))

	def keyPressEvent(self, event):
		"""
		This method reimplements the :meth:`QWidget.keyPressEvent` method.

		:param event: QEvent ( QEvent )
		"""

		key = event.key()
		if key == Qt.Key_Plus:
			self.scaleView(self.__keyZoomFactor)
		elif key == Qt.Key_Minus:
			self.scaleView(1 / self.__keyZoomFactor)
		else:
			super(ImagesPreviewer, self).keyPressEvent(event)

	def __initializeUi(self):
		"""
		This method initializes the Widget ui.
		"""

		LOGGER.debug("> Initializing '{0}' ui.".format(self.__class__.__name__))

		self.Previous_Image_pushButton.setIcon(QIcon(os.path.join(self.__uiResourcesDirectory, self.__uiPreviousImage)))
		self.Next_Image_pushButton.setIcon(QIcon(os.path.join(self.__uiResourcesDirectory, self.__uiNextImage)))
		self.Zoom_In_pushButton.setIcon(QIcon(os.path.join(self.__uiResourcesDirectory, self.__uiZoomInImage)))
		self.Zoom_Out_pushButton.setIcon(QIcon(os.path.join(self.__uiResourcesDirectory, self.__uiZoomOutImage)))
		len(self.__paths) <= 1 and self.Navigation_frame.hide()

		LOGGER.debug("> Initializing graphics View.")
		self.__graphicsView = QGraphicsView()
		self.__graphicsView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
		self.__graphicsView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
		self.__graphicsView.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
		self.__graphicsView.setDragMode(QGraphicsView.ScrollHandDrag)
		# Reimplementing QGraphicsView wheelEvent method.
		self.__graphicsView.wheelEvent = self.wheelEvent

		LOGGER.debug("> Initializing graphics scene.")
		self.__graphicsScene = QGraphicsScene(self.__graphicsView)
		self.__graphicsScene.setItemIndexMethod(QGraphicsScene.NoIndex)
		self.__graphicsScene.setSceneRect(-(float(self.__graphicsSceneWidth)) / 2,
										- (float(self.__graphicsSceneHeight)) / 2,
										float(self.__graphicsSceneWidth),
										float(self.__graphicsSceneHeight))

		self.__graphicsView.setScene(self.__graphicsScene)
		self.__graphicsView.setBackgroundBrush(QBrush(self.__graphicsSceneBackgroundColor))

		self.Images_Previewer_frame_gridLayout.addWidget(self.__graphicsView)

		# Signals / Slots.
		self.__container.engine.imagesCaches.QImage.contentAdded.connect(self.__engine_imagesCaches_QImage__contentAdded)
		self.Previous_Image_pushButton.clicked.connect(self.__Previous_Image_pushButton__clicked)
		self.Next_Image_pushButton.clicked.connect(self.__Next_Image_pushButton__clicked)
		self.Zoom_Out_pushButton.clicked.connect(self.__Zoom_Out_pushButton__clicked)
		self.Zoom_In_pushButton.clicked.connect(self.__Zoom_In_pushButton__clicked)
		self.Zoom_Fit_pushButton.clicked.connect(self.__Zoom_Fit_pushButton__clicked)

	def __Images_Informations_label_setUi(self):
		"""
		This method sets the **Images_Informations_label** Widget ui.
		"""

		if not self.__displayGraphicsItem:
			return

		image = self.__displayGraphicsItem.image
		self.Images_Informations_label.setText("{0} - {1}x{2} px - {3} bit".format(os.path.basename(image.data.path),
		 																		image.data.width,
																				image.data.height,
																				image.data.bpp / 4))

	def __engine_imagesCaches_QImage__contentAdded(self, content):
		"""
		This method is triggered by the Application **QImage** images cache when content has been added.

		:param content: Cache added content. ( List )
		"""

		if not self.__paths:
			return

		path = foundations.common.getFirstItem(content)
		if not path in self.__paths:
			return

		image = self.__container.engine.imagesCaches.QImage.getContent(path)
		self.__setDisplayGraphicsItem(image)

	def __Previous_Image_pushButton__clicked(self, checked):
		"""
		This method is triggered when **Previous_Image_pushButton** Widget is clicked.

		:param checked: Checked state. ( Boolean )
		"""

		self.loopThroughImages(True)

	def __Next_Image_pushButton__clicked(self, checked):
		"""
		This method is triggered when **Next_Image_pushButton** Widget is clicked.

		:param checked: Checked state. ( Boolean )
		"""

		self.loopThroughImages()

	def __Zoom_In_pushButton__clicked(self, checked):
		"""
		This method is triggered when **Zoom_In_pushButton** Widget is clicked.

		:param checked: Checked state. ( Boolean )
		"""

		self.scaleView(self.__keyZoomFactor)

	def __Zoom_Out_pushButton__clicked(self, checked):
		"""
		This method is triggered when **Zoom_Out_pushButton** Widget is clicked.

		:param checked: Checked state. ( Boolean )
		"""

		self.scaleView(1 / self.__keyZoomFactor)

	def __Zoom_Fit_pushButton__clicked(self, checked):
		"""
		This method is triggered when **Zoom_Fit_pushButton** Widget is clicked.

		:param checked: Checked state. ( Boolean )
		"""

		self.fitImage()

	def __clearGraphicsScene(self):
		"""
		This method clears the View.
		"""

		for graphicsItem in self.__graphicsScene.items():
			self.__graphicsScene.removeItem(graphicsItem)

	def __setDisplayGraphicsItem(self, image):
		"""
		This method sets the View using given image.

		:param image: Image to display. ( Qimage )
		"""

		self.__clearGraphicsScene()

		LOGGER.debug("> Initializing graphics item.")
		self.__displayGraphicsItem = Image_QGraphicsItem(image=image)
		self.__graphicsScene.addItem(self.__displayGraphicsItem)

		self.__Images_Informations_label_setUi()

	def loadImage(self, index=0):
		"""
		This method loads the display image in the View.

		:param index: Index to load. ( Integer )
		:return: Method success. ( Boolean )
		"""

		if not self.__paths:
			return False

		image = sibl_gui.ui.common.getImage(self.__paths[index])
		self.__setDisplayGraphicsItem(image)

		return True

	def scaleView(self, scaleFactor):
		"""
		This method scales the Previewer view.

		:param scaleFactor: Float ( Float )
		:return: Method success. ( Boolean )
		"""

		graphicsView = self.findChild(QGraphicsView)
		factor = graphicsView.matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width()
		if factor < self.__minimumZoomFactor or factor > self.__maximumZoomFactor:
			return False

		graphicsView.scale(scaleFactor, scaleFactor)
		return True

	def fitWindow(self):
		"""
		This method fits the View window.
		
		:return: Method success. ( Boolean )
		"""

		if not self.__displayGraphicsItem:
			return False

		desktopWidth = QApplication.desktop().screenGeometry(QApplication.desktop().primaryScreen()).width()
		desktopHeight = QApplication.desktop().screenGeometry(QApplication.desktop().primaryScreen()).height()
		width = min(desktopWidth * 0.80, self.__displayGraphicsItem.width)
		height = min(desktopHeight * 0.80, self.__displayGraphicsItem.height)
		self.resize(width, height)

		foundations.ui.common.centerWidgetOnScreen(self)

		return True

	def fitImage(self):
		"""
		This method fits the image to the View.
		
		:return: Method success. ( Boolean )
		"""

		if not self.__displayGraphicsItem:
			return False

		self.__graphicsView.fitInView(
		QRectF(-(self.__displayGraphicsItem.width / 2) - (self.__displayGraphicsItemMargin / 2),
				- (self.__displayGraphicsItem.height / 2) - (self.__displayGraphicsItemMargin / 2),
				self.__displayGraphicsItem.width + self.__displayGraphicsItemMargin,
				self.__displayGraphicsItem.height + self.__displayGraphicsItemMargin),
				Qt.KeepAspectRatio)
		return True

	def loopThroughImages(self, backward=False):
		"""
		This method loops through View images.

		:param backward: Looping backward. ( Boolean )
		:return: Method success. ( Boolean )
		"""

		index = self.__paths.index(self.__displayGraphicsItem.image.data.path)
		index += not backward and 1 or -1
		if index < 0:
			index = len(self.__paths) - 1
		elif index > len(self.__paths) - 1:
			index = 0
		self.loadImage(index)
		return True
Beispiel #29
0
        diagram.set_anchors()

        layouter.apply(diagram)

        # edges must be updated after nodes are updated and layouted
        for edge in diagram.edges.values():
            edge.update()

        # this actually paints things, so must be invoked when everything is
        # ready
        for drawable in diagram.elements():
            scene.addItem(drawable)
            drawable.resize_scene_rect()
            
        adj_scene_rect = scene.sceneRect().adjusted(-margin, -margin, margin, margin)
        scene.setSceneRect(adj_scene_rect)
        
        diagramsize = adj_scene_rect.toRect().size()

        img = QImage(QSize(diagramsize.width() * scale, diagramsize.height() * scale), QImage.Format_ARGB32)
        painter = QPainter(img)
        print margin
        absoluteRect = QRectF(0, 0, scene.sceneRect().width() * scale, scene.sceneRect().height() * scale)
        painter.fillRect(absoluteRect, QBrush(QColor(255, 255, 255), Qt.SolidPattern))
        painter.resetMatrix()
        scene.render(painter)
        painter.end()
        ret = img.save(output)
        print("Saved to " + output)

    for e in logger.events:
Beispiel #30
0
    def reduce_speed(self, factor=0.9):
        for particle in self.particles:
            particle.reduce_speed(factor)

    def increase_speed(self, factor=1.1):
        for particle in self.particles:
            particle.increase_speed(factor)

    def set_color(self, color):
        for particle in self.particles:
            particle.set_color(color)

    def recalculate_new_pos(self):
        for particle in self.particles:
            particle.instant_pos_change()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    scene = QGraphicsScene()
    scene.setSceneRect(-400, -400.0, 800.0, 800.0)
    particle_background = ParticlesBackgroundDecoration(scene)
    view = QGraphicsView(scene)
    view.showMaximized()
    scene.setSceneRect(
        view.mapToScene(view.viewport().geometry()).boundingRect())
    particle_background.generate_particles(200)
    particle_background.reduce_speed(0.3)
    print scene.sceneRect()
    app.exec_()
class SpotguideShowImageDlg(QtGui.QDialog, FORM_CLASS):
    def __init__(self, theCanvas, theLayer, selFeatureIds, parent=None):
        super(SpotguideShowImageDlg, self).__init__(parent)
        self.setupUi(self)
        self.mTheCanvas = theCanvas
        self.mTheLayer = theLayer
        self.mSelFeatureIds = selFeatureIds
        self.mAllFeatureIds = []
        self.highlightList = []

        # members shown in graphic view.
        self.mScene = QGraphicsScene()
        self.graphicsViewShowImage.setScene(self.mScene)
        self.mPixmapList = []

        featureIter = self.mTheLayer.getFeatures(QgsFeatureRequest().setFlags(
            QgsFeatureRequest.NoGeometry))
        inti = 0
        theFeature = QgsFeature()
        while (featureIter.nextFeature(theFeature) and inti < 512):
            inti += 1
            self.mAllFeatureIds.append(theFeature.id())

        self.spinBoxFeatureIndex.setValue(1)
        self.spinBoxFeatureIndex.setMinimum(1)
        self.spinBoxFeatureIndex.setMaximum(inti)

        errMsg = ['']
        self.initComboBoxOutlinkid()
        self.selectFeatureById(errMsg,
                               self.mSelFeatureIds[0],
                               bZoomToSelected=False)
        self.comboBoxOutlinkid.setFocus()

        self.pushButtonPrev.clicked.connect(self.onPushButtonPrev)
        self.pushButtonNext.clicked.connect(self.onPushButtonNext)
        self.connect(self.comboBoxOutlinkid,
                     QtCore.SIGNAL('activated(QString)'),
                     self.comboBoxOutlinkidChanged)

    def resizeEvent(self, event):
        self.showImageInGraphicsView()
        return

    def disableAllControls(self):
        self.pushButtonPrev.setEnabled(False)
        self.pushButtonPrev.setEnabled(False)
        self.comboBoxOutlinkid.setEnabled(False)
        self.textEditFeatureInfo.setEnabled(False)
        return

    def initComboBoxOutlinkid(self):
        while (self.comboBoxOutlinkid.count() > 0):
            self.comboBoxOutlinkid.removeItem(0)
        for oneFeatureId in self.mSelFeatureIds:
            featureIter = self.mTheLayer.getFeatures(
                QgsFeatureRequest(oneFeatureId).setFlags(
                    QgsFeatureRequest.NoGeometry))
            theFeature = QgsFeature()
            if featureIter.nextFeature(theFeature) == False:
                return
            if self.mIsMyFeature(theFeature):
                self.comboBoxOutlinkid.addItem(
                    str(theFeature.attribute('out_link_id')))

    def showFeatureDetail(self, errMsg, theFeature):
        strFeatureInfo = self.getFeatureInfoString(theFeature)
        self.textEditFeatureInfo.setText(strFeatureInfo)
        if self.mIsMyFeature(theFeature) == False:
            return

        errMsg = ['']
        pattern_dat, arrow_dat = self.getSpotguidePictures(
            errMsg, self.mTheLayer, theFeature)
        if errMsg[0] != '':
            #QMessageBox.information(self, "Show Spotguide", errMsg[0])
            return

        self.mPixmapList = []
        if pattern_dat is not None:
            patternDatParser = DatParser()
            patternDatParser.initFromMemory(errMsg,
                                            pattern_dat)  # pattern picture
            patternPixmap = QPixmap()
            patternPixmap.loadFromData(
                patternDatParser.getDatContentByIndex(errMsg, 0))
            self.mPixmapList.append(patternPixmap)

        if arrow_dat is not None:
            arrowDatParser = DatParser()
            arrowDatParser.initFromMemory(errMsg, arrow_dat)  # arrow picture
            arrowPixmap = QPixmap()
            arrowPixmap.loadFromData(
                arrowDatParser.getDatContentByIndex(errMsg, 0))
            if arrowDatParser.hasPointlist():
                # draw the point list on the arrow picture
                vecCoors = arrowDatParser.getPointListCoordinatesByIndex(
                    errMsg, arrowDatParser.getPointlistIndex())
                if errMsg[0] != '':
                    QMessageBox.information(self, "Show Spotguide", errMsg[0])
                    return
                with QPainter(arrowPixmap) as thePainter:
                    for oneXYPair in vecCoors:
                        thePainter.setPen(QPen(QColor(255, 0, 0)))
                        thePainter.drawPoint(oneXYPair[0], oneXYPair[1])
                        thePainter.drawPoint(oneXYPair[0] - 1, oneXYPair[1])
                        thePainter.drawPoint(oneXYPair[0] + 1, oneXYPair[1])
                        thePainter.drawPoint(oneXYPair[0], oneXYPair[1] - 1)
                        thePainter.drawPoint(oneXYPair[0], oneXYPair[1] + 1)

                # append pointlist information to the text box.
                strPointList = arrowDatParser.getPointListStringByIndex(
                    errMsg, arrowDatParser.getPointlistIndex())
                if errMsg[0] != '':
                    QMessageBox.information(self, "Show Spotguide", errMsg[0])
                    return
                strTemp = self.textEditFeatureInfo.toPlainText()
                strTemp += """\n\npointlist:\n"""
                strTemp += strPointList
                self.textEditFeatureInfo.setText(strTemp)
            self.mPixmapList.append(arrowPixmap)

        self.showImageInGraphicsView()
        return

    def showImageInGraphicsView(self):
        # remove all items in member QGraphicsScene.
        for oneItem in self.mScene.items():
            self.mScene.removeItem(oneItem)

        for onePixmap in self.mPixmapList:
            self.mScene.addPixmap(
                self.getPixMapSizedByWidgt(onePixmap,
                                           self.graphicsViewShowImage))

        self.mScene.setSceneRect(0, 0,
                                 self.graphicsViewShowImage.width() - 5,
                                 self.graphicsViewShowImage.height() - 5)
        return

    def getFeatureInfoString(self, theFeature):
        fieldList = theFeature.fields()
        attrList = theFeature.attributes()
        strFeatureInfo = "field count: %d\n" % len(fieldList)
        for oneField, oneAttr in zip(fieldList, attrList):
            if isinstance(oneAttr, float):
                strFeatureInfo += "%s: %.0f\n" % (oneField.name(), oneAttr)
            else:
                strFeatureInfo += "%s: %s\n" % (oneField.name(), oneAttr)
        return strFeatureInfo

    # result[0] is pattern dat
    # result[1] is arrow dat
    def getSpotguidePictures(self, errMsg, layer, theFeature):
        try:
            uri = QgsDataSourceURI(layer.source())
            conn = psycopg2.connect('''host='%s' dbname='%s' user='******' password='******' ''' %\
                (uri.host(), uri.database(), uri.username(), uri.password()))
            pg = conn.cursor()

            # all these lane's keys must be found
            # if anyone is not found, a 'KeyError' exception will be thrown.
            in_link_id = theFeature.attribute('in_link_id')
            node_id = theFeature.attribute('node_id')
            out_link_id = theFeature.attribute('out_link_id')
            passlink_count = theFeature.attribute('passlink_count')
            pattern_id = theFeature.attribute('pattern_id')
            arrow_id = theFeature.attribute('arrow_id')

            # spotguide record filter.
            strFilter = '''in_link_id=%s and node_id=%s and out_link_id=%s and 
                           passlink_count=%s and pattern_id=%s and arrow_id=%s''' % \
                        (in_link_id, node_id, out_link_id, passlink_count, pattern_id, arrow_id)

            sqlcmd = \
"""SET bytea_output TO escape;
select pattern_dat, arrow_dat
from %s
where %s
""" % (uri.table(), strFilter)
            pg.execute(sqlcmd)
            row = pg.fetchone()
            return row[0], row[1]
        except KeyError, kErr:
            errMsg[0] = """Selected feature is not a rdb spotguide feature."""
            return None, None
        except Exception, ex:
            errMsg[0] = ex.message
            return None, None
Beispiel #32
0
class OWHierarchicalClustering(widget.OWWidget):
    name = "Hierarchical Clustering"
    description = ("Hierarchical clustering based on distance matrix, and "
                   "a dendrogram viewer.")
    icon = "icons/HierarchicalClustering.svg"
    priority = 2100

    inputs = [("Distances", Orange.misc.DistMatrix, "set_distances")]

    outputs = [("Selected Data", Orange.data.Table),
               ("Other Data", Orange.data.Table)]

    #: Selected linkage
    linkage = settings.Setting(1)
    #: Index of the selected annotation item (variable, ...)
    annotation_idx = settings.Setting(0)
    #: Selected tree pruning (none/max depth)
    pruning = settings.Setting(0)
    #: Maximum depth when max depth pruning is selected
    max_depth = settings.Setting(10)

    #: Selected cluster selection method (none, cut distance, top n)
    selection_method = settings.Setting(0)
    #: Cut height ratio wrt root height
    cut_ratio = settings.Setting(75.0)
    #: Number of top clusters to select
    top_n = settings.Setting(3)

    append_clusters = settings.Setting(True)
    cluster_role = settings.Setting(2)
    cluster_name = settings.Setting("Cluster")
    autocommit = settings.Setting(False)

    #: Cluster variable domain role
    AttributeRole, ClassRole, MetaRole = 0, 1, 2

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

        self.matrix = None
        self.items = None
        self.linkmatrix = None
        self.root = None
        self._displayed_root = None
        self.cutoff_height = 0.0
        self._invalidated = False

        gui.comboBox(gui.widgetBox(self.controlArea, "Linkage"),
                     self,
                     "linkage",
                     items=LINKAGE,
                     callback=self._invalidate_clustering)

        box = gui.widgetBox(self.controlArea, "Annotation")
        self.label_cb = gui.comboBox(box,
                                     self,
                                     "annotation_idx",
                                     callback=self._update_labels)

        self.label_cb.setModel(itemmodels.VariableListModel())
        self.label_cb.model()[:] = ["None", "Enumeration"]

        box = gui.radioButtons(self.controlArea,
                               self,
                               "pruning",
                               box="Pruning",
                               callback=self._invalidate_pruning)
        grid = QGridLayout()
        box.layout().addLayout(grid)
        grid.addWidget(gui.appendRadioButton(box, "None", addToLayout=False),
                       0, 0)
        self.max_depth_spin = gui.spin(box,
                                       self,
                                       "max_depth",
                                       minv=1,
                                       maxv=100,
                                       callback=self._invalidate_pruning,
                                       keyboardTracking=False)

        grid.addWidget(
            gui.appendRadioButton(box, "Max depth", addToLayout=False), 1, 0)
        grid.addWidget(self.max_depth_spin, 1, 1)

        box = gui.radioButtons(self.controlArea,
                               self,
                               "selection_method",
                               box="Selection",
                               callback=self._selection_method_changed)

        grid = QGridLayout()
        box.layout().addLayout(grid)
        grid.addWidget(gui.appendRadioButton(box, "Manual", addToLayout=False),
                       0, 0)
        grid.addWidget(
            gui.appendRadioButton(box, "Height ratio", addToLayout=False), 1,
            0)
        self.cut_ratio_spin = gui.spin(box,
                                       self,
                                       "cut_ratio",
                                       0,
                                       100,
                                       step=1e-1,
                                       spinType=float,
                                       callback=self._selection_method_changed)
        self.cut_ratio_spin.setSuffix("%")

        grid.addWidget(self.cut_ratio_spin, 1, 1)

        grid.addWidget(gui.appendRadioButton(box, "Top N", addToLayout=False),
                       2, 0)
        self.top_n_spin = gui.spin(box,
                                   self,
                                   "top_n",
                                   1,
                                   20,
                                   callback=self._selection_method_changed)
        grid.addWidget(self.top_n_spin, 2, 1)
        box.layout().addLayout(grid)

        self.controlArea.layout().addStretch()

        box = gui.widgetBox(self.controlArea, "Output")
        gui.checkBox(box,
                     self,
                     "append_clusters",
                     "Append cluster IDs",
                     callback=self._invalidate_output)

        ibox = gui.indentedBox(box)
        name_edit = gui.lineEdit(ibox, self, "cluster_name")
        name_edit.editingFinished.connect(self._invalidate_output)

        cb = gui.comboBox(
            ibox,
            self,
            "cluster_role",
            callback=self._invalidate_output,
            items=["Attribute", "Class variable", "Meta variable"])
        form = QFormLayout(fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow,
                           labelAlignment=Qt.AlignLeft,
                           spacing=8)
        form.addRow("Name", name_edit)
        form.addRow("Place", cb)

        ibox.layout().addSpacing(5)
        ibox.layout().addLayout(form)
        ibox.layout().addSpacing(5)

        cb = gui.checkBox(box, self, "autocommit", "Commit automatically")
        b = gui.button(box, self, "Commit", callback=self.commit, default=True)
        gui.setStopper(self, b, cb, "_invalidated", callback=self.commit)

        self.scene = QGraphicsScene()
        self.view = QGraphicsView(
            self.scene,
            horizontalScrollBarPolicy=Qt.ScrollBarAlwaysOff,
            verticalScrollBarPolicy=Qt.ScrollBarAlwaysOn,
            alignment=Qt.AlignLeft | Qt.AlignVCenter)

        def axis_view(orientation):
            ax = pg.AxisItem(orientation=orientation, maxTickLength=7)
            scene = QGraphicsScene()
            scene.addItem(ax)
            view = QGraphicsView(
                scene,
                horizontalScrollBarPolicy=Qt.ScrollBarAlwaysOff,
                verticalScrollBarPolicy=Qt.ScrollBarAlwaysOn,
                alignment=Qt.AlignLeft | Qt.AlignVCenter)
            view.setFixedHeight(ax.size().height())
            ax.line = SliderLine(orientation=Qt.Horizontal,
                                 length=ax.size().height())
            scene.addItem(ax.line)
            return view, ax

        self.top_axis_view, self.top_axis = axis_view("top")
        self.mainArea.layout().setSpacing(1)
        self.mainArea.layout().addWidget(self.top_axis_view)
        self.mainArea.layout().addWidget(self.view)
        self.bottom_axis_view, self.bottom_axis = axis_view("bottom")
        self.mainArea.layout().addWidget(self.bottom_axis_view)

        self._main_graphics = QGraphicsWidget()
        self._main_layout = QGraphicsLinearLayout(Qt.Horizontal)
        self._main_layout.setSpacing(1)

        self._main_graphics.setLayout(self._main_layout)
        self.scene.addItem(self._main_graphics)

        self.dendrogram = DendrogramWidget()
        self.dendrogram.setSizePolicy(QSizePolicy.MinimumExpanding,
                                      QSizePolicy.MinimumExpanding)
        self.dendrogram.selectionChanged.connect(self._invalidate_output)
        self.dendrogram.selectionEdited.connect(self._selection_edited)

        fm = self.fontMetrics()
        self.dendrogram.setContentsMargins(5,
                                           fm.lineSpacing() / 2, 5,
                                           fm.lineSpacing() / 2)
        self.labels = GraphicsSimpleTextList()
        self.labels.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        self.labels.setAlignment(Qt.AlignLeft)
        self.labels.setMaximumWidth(200)
        self.labels.layout().setSpacing(0)

        self._main_layout.addItem(self.dendrogram)
        self._main_layout.addItem(self.labels)

        self._main_layout.setAlignment(self.dendrogram,
                                       Qt.AlignLeft | Qt.AlignVCenter)
        self._main_layout.setAlignment(self.labels,
                                       Qt.AlignLeft | Qt.AlignVCenter)

        self.view.viewport().installEventFilter(self)
        self.top_axis_view.viewport().installEventFilter(self)
        self.bottom_axis_view.viewport().installEventFilter(self)
        self._main_graphics.installEventFilter(self)

        self.cut_line = SliderLine(self.dendrogram, orientation=Qt.Horizontal)
        self.cut_line.valueChanged.connect(self._dendrogram_slider_changed)
        self.cut_line.hide()

        self.bottom_axis.line.valueChanged.connect(self._axis_slider_changed)
        self.top_axis.line.valueChanged.connect(self._axis_slider_changed)
        self.dendrogram.geometryChanged.connect(self._dendrogram_geom_changed)
        self._set_cut_line_visible(self.selection_method == 1)

    def set_distances(self, matrix):
        self.matrix = matrix
        self._invalidate_clustering()
        self._set_items(matrix.row_items if matrix is not None else None)

    def _set_items(self, items):
        self.items = items
        if items is None:
            self.label_cb.model()[:] = ["None", "Enumeration"]
        elif isinstance(items, Orange.data.Table):
            vars = list(items.domain)
            self.label_cb.model()[:] = ["None", "Enumeration"] + vars
        elif isinstance(items, list) and \
                all(isinstance(var, Orange.data.Variable) for var in items):
            self.label_cb.model()[:] = ["None", "Enumeration", "Name"]
        else:
            self.label_cb.model()[:] = ["None", "Enumeration"]
        self.annotation_idx = min(self.annotation_idx,
                                  len(self.label_cb.model()) - 1)

    def handleNewSignals(self):
        self._update_labels()

    def _clear_plot(self):
        self.labels.set_labels([])
        self.dendrogram.set_root(None)

    def _set_displayed_root(self, root):
        self._clear_plot()
        self._displayed_root = root
        self.dendrogram.set_root(root)

        self._update_labels()

        self._main_graphics.resize(
            self._main_graphics.size().width(),
            self._main_graphics.sizeHint(Qt.PreferredSize).height())
        self._main_graphics.layout().activate()

    def _update(self):
        self._clear_plot()

        distances = self.matrix

        if distances is not None:
            # Convert to flat upper triangular distances
            i, j = numpy.triu_indices(distances.X.shape[0], k=1)
            distances = distances.X[i, j]

            method = LINKAGE[self.linkage].lower()
            Z = scipy.cluster.hierarchy.linkage(distances, method=method)
            tree = tree_from_linkage(Z)
            self.linkmatrix = Z
            self.root = tree

            self.top_axis.setRange(tree.value.height, 0.0)
            self.bottom_axis.setRange(tree.value.height, 0.0)

            if self.pruning:
                self._set_displayed_root(prune(tree, level=self.max_depth))
            else:
                self._set_displayed_root(tree)
        else:
            self.linkmatrix = None
            self.root = None
            self._set_displayed_root(None)

        self._apply_selection()

    def _update_labels(self):
        labels = []
        if self.root and self._displayed_root:
            indices = [leaf.value.index for leaf in leaves(self.root)]

            if self.annotation_idx == 0:
                labels = []
            elif self.annotation_idx == 1:
                labels = [str(i) for i in indices]
            elif isinstance(self.items, Orange.data.Table):
                var = self.label_cb.model()[self.annotation_idx]
                col = self.items[:, var]
                labels = [var.repr_val(next(iter(row))) for row in col]
                labels = [labels[idx] for idx in indices]
            else:
                labels = []

            if labels and self._displayed_root is not self.root:
                joined = leaves(self._displayed_root)
                labels = [
                    ", ".join(labels[leaf.value.first:leaf.value.last])
                    for leaf in joined
                ]

        self.labels.set_labels(labels)
        self.labels.setMinimumWidth(1 if labels else -1)

    def _invalidate_clustering(self):
        self._update()
        self._update_labels()

    def _invalidate_output(self):
        self._invalidated = True
        if self.autocommit:
            self.commit()

    def _invalidate_pruning(self):
        if self.root:
            selection = self.dendrogram.selected_nodes()
            ranges = [node.value.range for node in selection]
            if self.pruning:
                self._set_displayed_root(prune(self.root,
                                               level=self.max_depth))
            else:
                self._set_displayed_root(self.root)
            selected = [
                node for node in preorder(self._displayed_root)
                if node.value.range in ranges
            ]

            self.dendrogram.set_selected_clusters(selected)

        self._apply_selection()

    def commit(self):
        self._invalidated = False

        items = getattr(self.matrix, "items", self.items)
        if not items:
            # nothing to commit
            return

        selection = self.dendrogram.selected_nodes()
        selection = sorted(selection, key=lambda c: c.value.first)

        indices = [leaf.value.index for leaf in leaves(self.root)]

        maps = [
            indices[node.value.first:node.value.last] for node in selection
        ]

        selected_indices = list(chain(*maps))
        unselected_indices = sorted(
            set(range(self.root.value.last)) - set(selected_indices))

        selected = [items[k] for k in selected_indices]
        unselected = [items[k] for k in unselected_indices]

        if not selected:
            self.send("Selected Data", None)
            self.send("Other Data", None)
            return
        selected_data = unselected_data = None

        if isinstance(items, Orange.data.Table):
            c = numpy.zeros(len(items))

            for i, indices in enumerate(maps):
                c[indices] = i
            c[unselected_indices] = len(maps)

            mask = c != len(maps)

            if self.append_clusters:
                clust_var = Orange.data.DiscreteVariable(
                    str(self.cluster_name),
                    values=[
                        "Cluster {}".format(i + 1) for i in range(len(maps))
                    ] + ["Other"])
                data, domain = items, items.domain

                attrs = domain.attributes
                class_ = domain.class_vars
                metas = domain.metas

                X, Y, M = data.X, data.Y, data.metas
                if self.cluster_role == self.AttributeRole:
                    attrs = attrs + (clust_var, )
                    X = numpy.c_[X, c]
                elif self.cluster_role == self.ClassRole:
                    class_ = class_ + (clust_var, )
                    Y = numpy.c_[Y, c]
                elif self.cluster_role == self.MetaRole:
                    metas = metas + (clust_var, )
                    M = numpy.c_[M, c]

                domain = Orange.data.Domain(attrs, class_, metas)
                data = Orange.data.Table(domain, X, Y, M)
            else:
                data = items

            if selected:
                selected_data = data[mask]
            if unselected:
                unselected_data = data[~mask]

        self.send("Selected Data", selected_data)
        self.send("Other Data", unselected_data)

    def sizeHint(self):
        return QSize(800, 500)

    def eventFilter(self, obj, event):
        if obj is self.view.viewport() and event.type() == QEvent.Resize:
            width = self.view.viewport().width() - 2
            self._main_graphics.setMaximumWidth(width)
            self._main_graphics.setMinimumWidth(width)
            self._main_graphics.layout().activate()
        elif event.type() == QEvent.MouseButtonPress and \
                (obj is self.top_axis_view.viewport() or
                 obj is self.bottom_axis_view.viewport()):
            self.selection_method = 1
            # Map click point to cut line local coordinates
            pos = self.top_axis_view.mapToScene(event.pos())
            cut = self.top_axis.line.mapFromScene(pos)
            self.top_axis.line.setValue(cut.x())
            # update the line visibility, output, ...
            self._selection_method_changed()

        return super().eventFilter(obj, event)

    def _dendrogram_geom_changed(self):
        pos = self.dendrogram.pos_at_height(self.cutoff_height)
        geom = self.dendrogram.geometry()
        crect = self.dendrogram.contentsRect()

        self._set_slider_value(pos.x(), geom.width())
        self.cut_line.setLength(geom.height())

        self.top_axis.resize(crect.width(), self.top_axis.height())
        self.top_axis.setPos(geom.left() + crect.left(), 0)
        self.top_axis.line.setPos(self.cut_line.scenePos().x(), 0)

        self.bottom_axis.resize(crect.width(), self.bottom_axis.height())
        self.bottom_axis.setPos(geom.left() + crect.left(), 0)
        self.bottom_axis.line.setPos(self.cut_line.scenePos().x(), 0)

        geom = self._main_graphics.geometry()
        assert geom.topLeft() == QPointF(0, 0)
        self.scene.setSceneRect(geom)

        geom.setHeight(self.top_axis.size().height())

        self.top_axis.scene().setSceneRect(geom)
        self.bottom_axis.scene().setSceneRect(geom)

    def _axis_slider_changed(self, value):
        self.cut_line.setValue(value)

    def _dendrogram_slider_changed(self, value):
        p = QPointF(value, 0)
        cl_height = self.dendrogram.height_at(p)

        self.set_cutoff_height(cl_height)

        # Sync the cut positions between the dendrogram and the axis.
        self._set_slider_value(value, self.dendrogram.size().width())

    def _set_slider_value(self, value, span):
        with blocked(self.cut_line):
            self.cut_line.setValue(value)
            self.cut_line.setRange(0, span)

        with blocked(self.top_axis.line):
            self.top_axis.line.setValue(value)
            self.top_axis.line.setRange(0, span)

        with blocked(self.bottom_axis.line):
            self.bottom_axis.line.setValue(value)
            self.bottom_axis.line.setRange(0, span)

    def set_cutoff_height(self, height):
        self.cutoff_height = height
        if self.root:
            self.cut_ratio = 100 * height / self.root.value.height
        self.select_max_height(height)

    def _set_cut_line_visible(self, visible):
        self.cut_line.setVisible(visible)
        self.top_axis.line.setVisible(visible)
        self.bottom_axis.line.setVisible(visible)

    def select_top_n(self, n):
        root = self._displayed_root
        if root:
            clusters = top_clusters(root, n)
            self.dendrogram.set_selected_clusters(clusters)

    def select_max_height(self, height):
        root = self._displayed_root
        if root:
            clusters = clusters_at_height(root, height)
            self.dendrogram.set_selected_clusters(clusters)

    def _selection_method_changed(self):
        self._set_cut_line_visible(self.selection_method == 1)
        if self.root:
            self._apply_selection()

    def _apply_selection(self):
        if not self.root:
            return

        if self.selection_method == 0:
            pass
        elif self.selection_method == 1:
            height = self.cut_ratio * self.root.value.height / 100
            self.set_cutoff_height(height)
            pos = self.dendrogram.pos_at_height(height)
            self._set_slider_value(pos.x(), self.dendrogram.size().width())
        elif self.selection_method == 2:
            self.select_top_n(self.top_n)

    def _selection_edited(self):
        # Selection was edited by clicking on a cluster in the
        # dendrogram view.
        self.selection_method = 0
        self._selection_method_changed()
Beispiel #33
0
class MainForm(QDialog):

    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_()

    def reject(self):
        self.accept()

    def accept(self):
        self.offerSave()
        QDialog.accept(self)
        
    def offerSave(self):
        if (Dirty and QMessageBox.question(self, "%s - Unsaved Changes" % AppName, "Save unsaved changes?", 
                                           QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes):
            self.save()

    def position(self):
        return QPointF(self.view.mapFromGlobal(QCursor.pos()))
    
    def addTag(self, stamp=None, position=None, adjust_position=True):
        if not position: position = self.position()
        if stamp is not None:
            self.lastStamp = stamp
        else:
            self.lastStamp += 1
        item = StampItem(self.lastStamp, position, self.scene, adjust_position=adjust_position)
        item.update()
        global Dirty; Dirty = True

    def save(self):
        vals = sorted([(item.stamp, item.pos().x(), item.pos().y()) for item in self.scene.items() if isinstance(item, StampItem)])
        info_name = "%s-%s.txt" %(self.filename, TAG)
        f = open(info_name, "wt")
        for tag, x, y in vals:
            f.write("%s\t%d\t%d\n" % (tag, x, y))
        f.close()
        save_png(self.filename, [(x-5, y-5) for _, x, y in vals])
        global Dirty; Dirty = False
        
    def renumberTags(self):
        """Number the tags by skipping the missing values"""
        vals = sorted([(item.stamp, item) for item in self.scene.items() if isinstance(item, StampItem)])
        for i, (_, v) in enumerate(vals):
            v.setStamp(i)
        if not vals: i = -1
        self.lastStamp = i
        global Dirty; Dirty = True
        
    def alignBottom(self):
        """Align tags horizontally, use bottom margin as a reference"""
        items = [item for item in self.scene.selectedItems() if isinstance(item, StampItem)]
        if items:
            ref_y = max(item.pos().y() for item in items)
            for item in items:
                item.setY(ref_y)
            global Dirty; Dirty = True
                
    def alignLeft(self):
        """Align tags vertically, use left margin as a reference"""
        items = [item for item in self.scene.selectedItems() if isinstance(item, StampItem)]
        if items:
            ref_x = min(item.pos().x() for item in items)
            for item in items:
                item.setX(ref_x)
            global Dirty; Dirty = True
Beispiel #34
0
class Factura:
    def __init__(self,padre,num):
	self.padre=padre
	self.cursor=padre.cursor
	self.curser=padre.curser
	self.parent=padre
	self.num=num
	self.escena=QGraphicsScene()
	self.gvDocumento=QGraphicsView()
	#self.cfg=padre.cfg
	self.iniciar()

    def iniciar(self):
      if self.cargarPlantilla():
	iva=0
	subtotal=0
	total=0
	alto=int(self.cfg.get("documento", "alto"))
	ancho=int(self.cfg.get("documento", "ancho"))
	cfont=QFont("Droid Sans", int(self.cfg.get("cliente", "fuente")), int(self.cfg.get("cliente", "peso") ))
	pfont=QFont("Droid Sans", int(self.cfg.get("productos", "fuente")), int(self.cfg.get("productos", "peso") ))
	ffont=QFont("Droid Sans", int(self.cfg.get("fecha", "fuente")), int(self.cfg.get("fecha", "peso") ))
	tfont=QFont("Droid Sans", int(self.cfg.get("totales", "fuente")), int(self.cfg.get("totales", "peso") ))
	self.escena.setSceneRect(-int(self.cfg.get("documento", "x")),-int(self.cfg.get("documento", "y")),ancho,alto)
	fuente=QFont("Droid Sans", int(self.cfg.get("documento", "fuente")), int(self.cfg.get("documento", "peso") ))
	smallDroid=QFont("Droid Sans", 9)
	sql="""SELECT * FROM clientes as C, notas WHERE notas.id=%s and notas.cliente=C.id;"""%self.num
	self.curser.execute(sql)
	cliente=self.curser.fetchone()
	if cliente!=None:
	  cliente=dicursor(self.curser,cliente)
	datos=self.escena.addText("",cfont)
	datos.setHtml("<p><b>Nombre:</b> %s<br><b>Direccion:</b>  %s, C.P %s %s, %s.<br><b>RFC:</b>  %s</p>"%(cliente['nombre'],cliente['direccion'],cliente['correo'],cliente['poblacion'],cliente['estado'],cliente['rfc']))
	datos.setPos(int(self.cfg.get("cliente", "x")) ,int(self.cfg.get("cliente", "y")))
	datos.setTextWidth(int(self.cfg.get("cliente", "ancho")))
	self.curser.execute("SELECT cantidad, `descripcion`,total/cantidad as precio,total,porcentaje as imp,unidades.nombre as unidad, ' ' as espacio  from productos,vendidos, impuestos , unidades where ref=producto and venta="+str(self.num)+" and impuestos.id=impuesto and unidades.id=unidad group by ref")
	fecha=self.escena.addText("",ffont)
	if isinstance(cliente['fecha'],datetime.datetime):
	  fecha.setHtml(cliente['fecha'].strftime(self.cfg.get("fecha", "formato")))
	else:
	  fecha.setHtml(datetime.datetime.strptime(cliente['fecha'],'%Y-%m-%d %H:%M:%S').strftime(self.cfg.get("fecha", "formato")))
	fecha.setPos(int(self.cfg.get("fecha", "x")),int(self.cfg.get("fecha", "y")))
	fecha.setTextWidth(int(self.cfg.get("fecha", "ancho")))
	#print "SELECT cantidad, `descripcion`,precio,total from productos,vendidos where ref=producto and venta="+str(self.num)+" group by ref"
	arts=self.curser.fetchall()
	if arts!=None:
	  arts=dicursor(self.curser,arts)
	  col=[[],[],[],[],[]]
	  #dict(arts)
	  for item in arts:
	    imp=0;porc=0
	    imp=item['total']/float("1.%d"%item['imp'])
	    porc=imp*(int(item['imp'])*.01)
	    #imp=round(imp,2)
	    #porc=round(porc,2)
	    #porc+=item['total']-(imp+porc)
	    total+=item['total']
	    item['precio']=round(imp/item['cantidad'],2)
	    item['total']=round(imp,2) 
	    iva+=porc
	    subtotal+=imp
	  subtotal=round(subtotal,2)
	  iva=round(iva,2)
	  filas=[]
	  campos=self.cfg.get("productos", "campos").replace(" ","").split(",")
	  heads="{%s}"%"},{".join(campos)
	  anchos=self.cfg.get("productos", "anchos").replace(" ","").split(",")
	  #cabezas=heads.replace("{","").replace("}","").split(",")
	  for item in arts:
	      row=heads.format(**item)
	      filas.append(row.split(','))

	  heads=heads.replace("{","").replace("}","") 
	  tabla=self.escena.addText("",pfont)
	  tabla.setHtml(listaHtml(filas,cabezas=campos,color='#fff',fondo="#FFF", tfuente=11,opc="101",css="th{color:#FFF} .celda{margin:10px;padding:5px;}",anchos=anchos))
	  tabla.setPos(int(self.cfg.get("productos", "x")),int(self.cfg.get("productos", "y")))
	  tabla.setTextWidth(int(self.cfg.get("productos", "ancho")))

	cantidad=self.escena.addText("",pfont)
	cantidad.setHtml("<center>%s</center>"%nletra(total))
	cantidad.setPos(int(self.cfg.get("nletra", "x")),int(self.cfg.get("nletra", "y")))
	cantidad.setTextWidth(int(self.cfg.get("nletra", "ancho")))
	totales=self.escena.addText("",tfont)
	totales.setHtml("<p ALIGN=right>%.2f</p><p ALIGN=right>%.2f</p><p ALIGN=right>%.2f</p>"%(float(subtotal),float(iva),float(total)))
	totales.setPos(int(self.cfg.get("totales", "x")),int(self.cfg.get("totales", "y")))
	totales.setTextWidth(int(self.cfg.get("totales", "ancho")))
	#self.curser.execute("SELECT cantidad, `descripcion`,precio,total from productos,vendidos where ref=producto and venta="+str(self.num)+" group by ref")
	
	self.gvDocumento.setScene(self.escena)
      else:
	print "Error al cargar plantilla"
	
    def alinear(self,item):
      formato=QTextBlockFormat()
      formato.setAlignment(Qt.AlignRight)
      cursor = item.textCursor()
      cursor.select(QTextCursor.Document)
      cursor.mergeBlockFormat(formato)
      cursor.clearSelection()
      item.setTextCursor(cursor)

    def cargarPlantilla(self):
	self.cfg = Cp.ConfigParser()
	if self.cfg.read([os.path.join(home,"formas","factura.cfg")]):
	  if self.cfg.has_option("documento", "version"):
	    return True
	else:
	  return False
    
	
    def br(self,texto):
	 offset=1
	 font=texto.font()
	 pos=texto.pos()
	 return QPointF(pos.x(),float(pos.y())+float(font.pointSize())+offset)

    def imprimir(self):
      	printer=QPrinter(QPrinter.HighResolution)
	printer.setPaperSize(QPrinter.Letter)   
	printer.setOutputFormat(QPrinter.PdfFormat)
	ruta=os.path.join(self.parent.cfg.get("factura", "ruta"),'Factura-'+str(self.num)+'.pdf')
	printer.setOutputFileName(ruta)
	prev=QPrintDialog(printer,self.padre)
	if prev.exec_()==QDialog.Accepted:
	    paint=QPainter()
	    paint.begin(printer)
	    self.escena.render(paint)
	    paint.end()
	    print "Imprimiendo..."
	    
	if sys.platform == 'linux2':
	    os.system("gnome-open '%s' "%ruta)
	elif sys.platform == 'win32':
	    os.system("start '%s'"%ruta)
Beispiel #35
0
class MainMayaWindow (QObject):
    '''
    Base QObject for the JADE Maya scripted plugin.
    Notice the difference with the MainMWindow. This class is subclassing QObject while the Standalone one subclasses QWidget.
    
    This class handles the Maya way to deal with the contextual pop-up menu. Additionally, this class shares some of the responsibilities with graph.py.
    '''
    def __init__ (self, graph, parent=None):
        '''constructor
        
        @param graph the model
        @param parent a parent QObject, or None for root window.
        '''
        super (MainMayaWindow, self).__init__(parent)
        QObject.__init__(self) # initiation indispensable for sending and receiving signals!
        
        # define scene and constrain its workspace
        self.scene = QGraphicsScene ()
        self.scene.setSceneRect (QRectF (-1000, -1000, 2000, 2000))
        
        self.graph_model = graph
        self.helper = utility.Helper (self, self.scene, self.graph_model)
        self.graph_view  = grv.GraphView (self.graph_model, self.helper)
        self.helper.setGraphView (self.graph_view)
        
        # wirings
        self.comm = self.graph_model.getComm ()
        self.connect (self.comm, SIGNAL ('deleteNode_MSignal(int)'), self.graph_view.removeTag)
        self.connect (self.comm, SIGNAL ('addLink_MSignal(int,int)'), self.graph_view.addWire)
        self.connect (self.comm, SIGNAL ('deleteLink_MSignal(int,int)'), self.graph_view.checkIfEmpty)
        self.connect (self.comm, SIGNAL ('addNode_MSignal(int, float, float)'), self.graph_view.addTag)
        
        self.scene.addItem (self.helper.getHarpoon ())
        
        self.hovered_tag_id = None
        
        # register a new command that takes care of deleting selected items and bind it to the key 'd'.
        cmds.nameCommand ('delSelection', ann='deleteSelectedItems', c='python (\"ClientMaya.ui.graph_view.removeSelectedItems ()\");')
        cmds.hotkey (k='d', name='delSelection')
    
    def setupUi (self, MainWindow):
        '''sets up the Maya UI.
        
        @param MainWindow
        '''
        MainWindow.setObjectName ('MainWindow')
        MainWindow.resize (800, 1396)
        sizePolicy = QSizePolicy (QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch (0)
        sizePolicy.setVerticalStretch (0)
        sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
        MainWindow.setSizePolicy(sizePolicy)
        font = QFont ()
        font.setPointSize (11)
        MainWindow.setFont (font)
        MainWindow.setWindowTitle (QApplication.translate("MainWindow", "Location Tool", None, QApplication.UnicodeUTF8))
        MainWindow.setTabShape (QTabWidget.Rounded)
        MainWindow.setDockOptions (QMainWindow.AllowTabbedDocks|QMainWindow.AnimatedDocks)
        
        self.scrollAreaWidgetContents_3 = QWidget (MainWindow)
        self.scrollAreaWidgetContents_3.setGeometry (QRect(10, 10, 900, 940))
        self.scrollAreaWidgetContents_3.setObjectName ('scrollAreaWidgetContents_3')
        self._view = View0.View ("JADEview", self.graph_view, self.scene, self.scrollAreaWidgetContents_3)
        self._view.setObjectName ('JADEview')  # real ui name
        self._view.graphicsView.setObjectName ('JADEInnerView')
        self.connect (self.scene, SIGNAL("selectionChanged()"), self._view.selectionChanged)
        
        self._view.wireViewItemsUp ()
        self._view.getGraphicsView().setScene (self.scene)
        self._view.setToolboxCSSColorScheme ('background-color: rgb(68,68,68);color: rgb(200,200,200)') # this needs to be done since the toolbox's background didn't have a uniform colour otherwise.
        #self._view.setGraphicsViewCSSBackground () # the CSS background doesn't seem to work in Maya as there seems to be a problem with cleaning QGraphicsLineItems when they move, that doesn't happen when there's no CSS applied to the background.

        self.graphicsView = self._view.getGraphicsView ()
        self.node_coords = QPoint (0,0)
        
        layout = QHBoxLayout (self.scrollAreaWidgetContents_3)
        layout.setContentsMargins (QMargins(0,0,0,0));
        layout.addWidget (self._view)
        
        QMetaObject.connectSlotsByName (MainWindow)
        
        """
        cmds.control('JADEInnerView', edit=True, ebg=True, bgc=[.5,.5,.9])
        print cmds.control('JADEInnerView', query=True, p=True)
        """
        
        # wiring the Maya Contextual pop-up Menus - yes, in Maya we've split the pop-up menu definition in three pop-up menus although only one will be present at any time.
        self.menu        = cmds.popupMenu ('JADEmenu',        parent='JADEInnerView', button=3, pmc = 'ClientMaya.ui.ctxMenu()',        aob=True)
        self.menuAddOuts = cmds.popupMenu ('JADEmenuAddOuts', parent='JADEInnerView', button=3, pmc = 'ClientMaya.ui.ctxMenuAddOuts()', aob=True, alt=True)
        self.menuAddIns  = cmds.popupMenu ('JADEmenuAddIns',  parent='JADEInnerView', button=3, pmc = 'ClientMaya.ui.ctxMenuAddIns()',  aob=True, ctl=True)
        
        # this class property is used to keep track of the mouse position.
        self._mouse = QCursor
        
        # self._view's zoom slider (we need this to correct the bias added to sort the mouse position when the zoom changes - ONLY in Maya)
        self._zoom_slider = self._view.getZoomSlider()
    
    # - - -    context menus methods   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
    def ctxMenu (self):
        '''this method invokes the general Maya pop-up menu.
        '''
        self.hovered_tag_id = self.comm.getHoveredItemId()
        
        cmds.popupMenu ('JADEmenu', edit=True, dai=True) # clear all the menu items out.
        
        if self.hovered_tag_id==None:
            # ctx menu to establish what node is going to be retrieved
            tmp_ls = []
            [tmp_ls.append(key) for key in self.graph_model.getNodesDecription()]
            self.prepareGeneralCtxMenu (tmp_ls)
    
    def prepareGeneralCtxMenu (self, list0):
        '''populates the self.menu dynamically with available node infos.
        
        @param list0 list of menu items
        '''
        self.node_coords = self.graphicsView.mapToScene (self._mouse.pos())
        
        # populate the QMenu dynamically and pass the menu string name to the receiver
        for i in sorted (list0):
            cmds.menuItem (parent=self.menu, label=str(i), c='ClientMaya.ui.addTag ("'+str(i)+'")')
    
    def addTag (self, name0):
        '''adds a Tag0 instance by name. the constants added to the are needed to make the tag pop up near the mouse pointer.
        
        @param name0 string
        '''
        if self._view.getCurrentClusterIndex () != 0:
            
            # the piece-wise linear interpolation below is a workaround only present in the Maya JADE mapping tool since
            # the self.graphicsView.mapToScene() doesn't seem to work as the standalone's one.
            if self._zoom_slider.value() > 199 and self._zoom_slider.value() < 241:
                x_bias = -22.5*(self._zoom_slider.value()-200) + 2100
                y_bias = -3.75*(self._zoom_slider.value()-200) + 400
            elif self._zoom_slider.value() > 240 and self._zoom_slider.value() < 281:
                x_bias = -12.5*(self._zoom_slider.value()-240) + 1200
                y_bias = -2.5* (self._zoom_slider.value()-240) + 250
            
            new_node = self.graph_model.addNode (name0, self.node_coords.x() - x_bias, self.node_coords.y() - y_bias)
            self._view.updateCurrentClusterNodeList (new_node)
            
            self._view.setMessageBarText ('')
        else:
            self._view.setMessageBarText ('** Choose or create a cluster first. Node not created.')
    
    def ctxMenuAddOuts (self):
        '''this method invokes the Maya add-outs pop-up menu.
        '''
        self.hovered_tag_id = self.comm.getHoveredItemId()
        
        cmds.popupMenu ('JADEmenuAddOuts', edit=True, dai=True) # clear all the menu items out.
        
        if self.hovered_tag_id!=None:
            
            right_list = self.graph_model.getOutsTypesLeft (self.hovered_tag_id)
            if len(right_list)!=0:
                self.prepareNodeCtxMenuOnAddingOuts (right_list)
    
    def ctxMenuAddIns (self):
        '''this method invokes the Maya add-ins pop-up menu.
        '''
        self.hovered_tag_id = self.comm.getHoveredItemId()
        
        cmds.popupMenu ('JADEmenuAddIns', edit=True, dai=True) # clear all the menu items out.
        
        if self.hovered_tag_id!=None:
            
            left_list = self.graph_model.getInsTypesLeft (self.hovered_tag_id)
            if len(left_list)!=0:
                self.prepareNodeCtxMenuOnAddingIns (left_list)
    
    def prepareNodeCtxMenuOnAddingOuts (self, list0):
        '''populates the self.menuAddOuts dynamically with available node infos.
        
        @param list0 list of menu items
        '''
        for i in sorted(list0):
            cmds.menuItem (parent=self.menuAddOuts, label=str(i), c='ClientMaya.ui.addOutSocketAction ("'+str(i)+'")')
        
        self.helper.setMenu (self.menuAddOuts)
    
    def prepareNodeCtxMenuOnAddingIns (self, list0):
        '''populates the self.menuAddIns dynamically with available node infos.
        
        @param list0 list of menu items
        '''
        for i in sorted (list0):
            cmds.menuItem (parent=self.menuAddIns, label=str(i), c='ClientMaya.ui.addInSocketAction ("'+str(i)+'")')
        
        self.helper.setMenu (self.menuAddIns)
    
    def addOutSocketAction (self, value):
        '''adds an out-socket name based on the pressed key modifier.
        
        @param value
        '''
        self.graph_view.getTag (self.hovered_tag_id) # retrieve the tag the ctx menu was open above.
        
        # the event released by adding an InSocket signal will trigger the Tag0's method appendOutHook as a result.
        self.graph_model.addOutSocket (self.hovered_tag_id, value)
    
    def addInSocketAction (self, value):
        '''adds an in-socket name based on the pressed key modifier.
        
        @param value
        '''
        self.graph_view.getTag (self.hovered_tag_id) # retrieve the tag the ctx menu was open above.
        
        # the event released by adding an InSocket signal will trigger the Tag0's method appendInHook() as a result.
        self.graph_model.addInSocket (self.hovered_tag_id, value)
Beispiel #36
0
class FlowUIWidget( QWidget ):
    " The widget which goes along with the text editor "

    def __init__( self, editor, parent ):
        QWidget.__init__( self, parent )

        # It is always not visible at the beginning because there is no
        # editor content at the start
        self.setVisible( False )

        self.__editor = editor
        self.__parentWidget = parent
        self.__connected = False
        self.__needPathUpdate = False

        self.cflowSettings = getDefaultCflowSettings( self )

        hLayout = QHBoxLayout()
        hLayout.setContentsMargins( 0, 0, 0, 0 )
        hLayout.setSpacing( 0 )

        vLayout = QVBoxLayout()
        vLayout.setContentsMargins( 0, 0, 0, 0 )
        vLayout.setSpacing( 0 )

        # Make pylint happy
        self.__toolbar = None
        self.__navBar = None
        self.__cf = None

        # Create the update timer
        self.__updateTimer = QTimer( self )
        self.__updateTimer.setSingleShot( True )
        self.__updateTimer.timeout.connect( self.process )

        vLayout.addWidget( self.__createNavigationBar() )
        vLayout.addWidget( self.__createGraphicsView() )

        hLayout.addLayout( vLayout )
        hLayout.addWidget( self.__createToolbar() )
        self.setLayout( hLayout )

        self.updateSettings()

        # Connect to the change file type signal
        mainWindow = GlobalData().mainWindow
        editorsManager = mainWindow.editorsManagerWidget.editorsManager
        self.connect( editorsManager, SIGNAL( 'fileTypeChanged' ),
                      self.__onFileTypeChanged )
        return

    def __createToolbar( self ):
        " Creates the toolbar "
        self.__toolbar = QToolBar( self )
        self.__toolbar.setOrientation( Qt.Vertical )
        self.__toolbar.setMovable( False )
        self.__toolbar.setAllowedAreas( Qt.RightToolBarArea )
        self.__toolbar.setIconSize( QSize( 16, 16 ) )
        self.__toolbar.setFixedWidth( 28 )
        self.__toolbar.setContentsMargins( 0, 0, 0, 0 )

        return self.__toolbar

    def __createNavigationBar( self ):
        " Creates the navigation bar "
        self.__navBar = ControlFlowNavigationBar( self )
        return self.__navBar

    def __createGraphicsView( self ):
        """ Creates the graphics view """
        self.scene = QGraphicsScene( self )
        self.view = CFGraphicsView( self )
        self.view.setScene( self.scene )
        self.view.zoomTo( Settings().flowScale )
        return self.view

    def process( self ):
        """ Parses the content and displays the results """

        if not self.__connected:
            self.__connectEditorSignals()

        content = self.__editor.text()
        self.__cf = getControlFlowFromMemory( content )
        if len( self.__cf.errors ) != 0:
            self.__navBar.updateInfoIcon( self.__navBar.STATE_BROKEN_UTD )
            return

        self.__navBar.updateInfoIcon( self.__navBar.STATE_OK_UTD )

#        if len( self.__cf.warnings ) != 0:
#            self.logMessage( "Parser warnings: " )
#            for warn in self.__cf.warnings:
#                print str( warn[0] ) + ": " + warn[1]

        self.scene.clear()
        try:
            # Top level canvas has no adress and no parent canvas
            canvas = VirtualCanvas( self.cflowSettings, None, None, None )
            canvas.layout( self.__cf )
            canvas.setEditor( self.__editor )
            width, height = canvas.render()
            self.scene.setSceneRect( 0, 0, width, height )
            canvas.draw( self.scene, 0, 0 )
        except Exception, exc:
            print "Exception:\n" + str( exc )
        return
def paintBoundaries(tgslicesFile, zSlice, d, boundaryData, mask, filename, swapCoordinates=False, colortable=None, penWidth=4.0):
    print "* making boundary img '%s'" % filename
    
    #b = BoundariesLayerPy(tgslicesFile=tgslicesFile, normalAxis=2, data2scene=QTransform(), swapCoordinates=True)
    b = BoundariesLayer(None, 2, QTransform(), True)
    
    n  = b.normalAxis()
    axis = None
    if swapCoordinates:
        if   n == 0: axis = "z"
        elif n == 1: axis = "y"
        else:        axis = "x"
    else:
        if   n == 0: axis = "x"
        elif n == 1: axis = "y"
        else:        axis = "z"
    
    f = h5py.File(tgslicesFile, 'r')
    group = "%s/%d" % (axis, zSlice)
    serializedBoundaries = f[group].value
    f.close()
    
    assert d.ndim == 2
    
    scene = QGraphicsScene()
    
    b.setSliceNumber( zSlice )
    b.setBoundaries(serializedBoundaries)
    b.setColormap("tyr")
    assert boundaryData.dtype == numpy.float32
    assert mask.dtype == numpy.float32
    b.setBoundaryData(boundaryData, boundaryData.size, boundaryData)
    b.setBoundaryMask(mask, mask.size)
    if colortable is not None:
        b.setColormap(colortable)
    print "setting pen width to be %f" % penWidth
    b.setPenWidth(float(penWidth))
    print "...done"
   
    mag = 4
    shape = d.shape
    
    dBig = vigra.sampling.resizeImageNoInterpolation(d.astype(numpy.float32), (mag*shape[0], mag*shape[1]))
    #dBig = dBig.swapaxes(0,1)
    qimg = qimage2ndarray.gray2qimage(dBig)
    #qimg = qimg.mirrored(True, False)
    imgItm = QGraphicsPixmapItem(QPixmap(qimg))
    imgItm.setScale(1.0/mag)
    scene.addItem(imgItm)
    
    sourceRect = QRectF(0,0,shape[1], shape[0])
    targetRect = QRectF(0,0,mag*shape[1], mag*shape[0])
    scene.setSceneRect(sourceRect)
    scene.addItem(b)
    
    img = QImage(targetRect.width(), targetRect.height(), QImage.Format_ARGB32);
    painter = QPainter(img);
    painter.setRenderHint(QPainter.Antialiasing);
    scene.render(painter, targetRect, sourceRect );
    img.save(filename)
    painter.end()
    #print "img has size ", img.width(), img.height()
    img = None
    painter = None
    scene = None
Beispiel #38
0
class ClassDiagram(QWidget, itab_item.ITabItem):
    def __init__(self, actions, parent=None):
        QWidget.__init__(self, parent)
        itab_item.ITabItem.__init__(self)
        self.actions = actions
        self.graphicView = QGraphicsView(self)
        self.scene = QGraphicsScene()
        self.graphicView.setScene(self.scene)
        self.graphicView.setViewportUpdateMode(
            QGraphicsView.BoundingRectViewportUpdate)

        vLayout = QVBoxLayout(self)
        self.setLayout(vLayout)
        vLayout.addWidget(self.graphicView)
        self.scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        self.scene.setSceneRect(-200, -200, 400, 400)
        self.graphicView.setMinimumSize(400, 400)
        actualProject = self.actions.ide.explorer.get_actual_project()
        arrClasses = self.actions._locator.get_classes_from_project(
            actualProject)
        #FIXME:dirty need to fix
        self.mX = -400
        self.mY = -320
        self.hightestY = self.mY
        filesList = []
        for elem in arrClasses:
            #loking for paths
            filesList.append(elem[2])
        for path in set(filesList):
            self.create_class(path)

    def create_class(self, path):
        content = file_manager.read_file_content(path)
        items = introspection.obtain_symbols(content)
        mYPadding = 10
        mXPadding = 10
        for classname, classdetail in list(items["classes"].items()):
            cl = ClassModel(self.graphicView, self.scene)
            cl.set_class_name(classname)
            self.fill_clases(cl, classdetail[1])
            self.scene.addItem(cl)
            cl.setPos(self.mX, self.mY)
            self.mX += cl._get_width() + mXPadding
            if self.hightestY < self.mY + cl.get_height():
                self.hightestY = self.mY + cl.get_height()
            if self.mX > 2000:
                self.mX = -400
                self.mY += self.hightestY + mYPadding

    def fill_clases(self, classComponent, classContent):
        funct = classContent['functions']
        classComponent.set_functions_list(funct)
        attr = classContent['attributes']
        classComponent.set_attributes_list(attr)

    def scale_view(self, scaleFactor):
        factor = self.graphicView.transform().scale(
            scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width()

        if factor > 0.05 and factor < 15:
            self.graphicView.scale(scaleFactor, scaleFactor)

    def keyPressEvent(self, event):

        taskList = {
            Qt.Key_Plus: lambda: self.scaleView(1.2),
            Qt.Key_Minus: lambda: self.scaleView(1 / 1.2)
        }
        if (event.key() in taskList):
            taskList[event.key()]()
        else:
            QWidget.keyPressEvent(self, event)
Beispiel #39
0
class MainForm(QDialog):
    def __init__(self, parent=None):
        super(MainForm, self).__init__(parent)
        self.Running = False
        self.scene = QGraphicsScene(self)
        self.scene.setSceneRect(0, 0, SCENESIZEX, SCENESIZEY)
        self.view = QGraphicsView()
        self.view.setRenderHint(QPainter.Antialiasing)
        self.view.setScene(self.scene)
        self.view.setFocusPolicy(Qt.NoFocus)
        #self.zoomSlider = QSlider(Qt.Horizontal)
        #self.zoomSlider.setRange(5, 200)
        #self.zoomSlider.setValue(100)
        self.pauseButton = QPushButton("Pa&use")
        self.quitButton = QPushButton("&Quit")

        layout = QVBoxLayout()
        layout.addWidget(self.view)
        #layout.addWidget(self.zoomSlider)
        layout.addWidget(self.pauseButton)
        layout.addWidget(self.quitButton)
        self.setLayout(layout)

        #self.connect(self.zoomSlider, SIGNAL("valueChanged(int))"),
        #             self.zoom)
        self.connect(self.pauseButton, SIGNAL("clicked()"), self.pauseOrResume)
        self.connect(self.quitButton, SIGNAL("clicked()"), self.accept)

        self.readNodes()
        self.zoom(1.0)
        self.populate()
        #self.startTimer(INTERVAL)
        self.setWindowTitle("TdPaleo")

    def pauseOrResume(self):
        self.Running = not self.Running
        self.pauseButton.setText("Pa&use" if self.Running else "Res&ume")
        items = self.scene.items()
        for item in items:
            item.setRunning()

    def zoom(self, value):
        factor = 1 / 1.5
        matrix = self.view.matrix()
        matrix.reset()
        matrix.scale(factor, factor)
        self.view.setMatrix(matrix)

    def readNodes(self):
        file = open("tdp_geometry.dat")
        file.readline()
        while True:
            line = file.readline()
            if not line:
                break
            param = line.split(" ")
            if (line != "\n"):
                n = node()
                n.x = float(param[0])
                n.y = 956 - float(param[1])
                n.angle = float(param[2])
                n.d = int(param[3])
                n.type = int(param[4])
                nodes.append(n)

    def populate(self):
        color = QColor(0, 150, 0)
        head = TdPCavallo(color, nodes[0].angle,
                          QPointF(nodes[0].x, nodes[0].y))
        #FIXME AGGIUNGERE POI IL FANTINO AL CAVALLO
        #segment = Segment(color, offset, head)
        self.scene.addItem(head)
        #Running = False

    def timerEvent(self, event):
        if not self.Running:
            return
class NostraIllustCheckDlg(QtGui.QDialog, FORM_CLASS):
    def __init__(self, theCanvas, theLayer, selFeatureIds, parent=None):
        super(NostraIllustCheckDlg, self).__init__(parent)
        self.setupUi(self)
        self.mTheCanvas = theCanvas
        self.mTheLayer = theLayer
        self.mSelFeatureIds = selFeatureIds
        self.mAllFeatureIds = []
        self.highlightList = []
        uri = QgsDataSourceURI(self.mTheLayer.source())
        self.conn = psycopg2.connect('''host='%s' dbname='%s' user='******' password='******' ''' %\
            (uri.host(), uri.database(), uri.username(), uri.password()))
        self.pg = self.conn.cursor()

        # members shown in graphic view.
        self.mScene = QGraphicsScene()
        self.graphicsViewShowImage.setScene(self.mScene)
        self.mPixmapList = []

        featureIter = self.mTheLayer.getFeatures(QgsFeatureRequest().setFlags(
            QgsFeatureRequest.NoGeometry))
        inti = 0
        theFeature = QgsFeature()
        while (featureIter.nextFeature(theFeature)):
            inti += 1
            self.mAllFeatureIds.append(theFeature.id())

        self.spinBoxFeatureIndex.setValue(1)
        self.spinBoxFeatureIndex.setMinimum(1)
        self.spinBoxFeatureIndex.setMaximum(inti)

        errMsg = ['']
        self.initComboBoxOutlinkid()
        self.selectFeatureById(errMsg,
                               self.mSelFeatureIds[0],
                               bZoomToSelected=False)
        self.comboBoxOutlinkid.setFocus()

        self.pushButtonPrev.clicked.connect(self.onPushButtonPrev)
        self.pushButtonNext.clicked.connect(self.onPushButtonNext)
        self.connect(self.comboBoxOutlinkid,
                     QtCore.SIGNAL('activated(QString)'),
                     self.comboBoxOutlinkidChanged)

    def resizeEvent(self, event):
        self.showImageInGraphicsView()
        return

    def disableAllControls(self):
        self.pushButtonPrev.setEnabled(False)
        self.pushButtonPrev.setEnabled(False)
        self.comboBoxOutlinkid.setEnabled(False)
        self.textEditFeatureInfo.setEnabled(False)
        return

    def initComboBoxOutlinkid(self):
        while (self.comboBoxOutlinkid.count() > 0):
            self.comboBoxOutlinkid.removeItem(0)
        for oneFeatureId in self.mSelFeatureIds:
            featureIter = self.mTheLayer.getFeatures(
                QgsFeatureRequest(oneFeatureId).setFlags(
                    QgsFeatureRequest.NoGeometry))
            theFeature = QgsFeature()
            if featureIter.nextFeature(theFeature) == False:
                return
            if self.mIsMyFeature(theFeature):
                strTemp = "%.0f, %.0f" % (theFeature.attribute('arc1'),
                                          theFeature.attribute('arc2'))
                self.comboBoxOutlinkid.addItem(strTemp)

    def showFeatureDetail(self, errMsg, theFeature):
        strFeatureInfo = self.getFeatureInfoString(theFeature)
        self.textEditFeatureInfo.setText(strFeatureInfo)
        if self.mIsMyFeature(theFeature) == False:
            return

        errMsg = ['']
        day_pic = theFeature.attribute('day_pic')
        arrowimg = theFeature.attribute('arrowimg')
        basePath = r"\\tangpinghui\20151010_nostra_junctionview\output_jpg_and_png"
        day_pic_path = os.path.join(basePath, day_pic + ".psd\Main_Day.jpg")
        arrowimg_path = ''
        tempPath = os.path.join(basePath, day_pic + ".psd")
        for curDir, subDirs, fileNames in os.walk(tempPath):
            for oneFile in fileNames:
                if oneFile.find(arrowimg) != -1 and oneFile.find('_en') != -1:
                    arrowimg_path = os.path.join(curDir, oneFile)

        self.mPixmapList = []
        patternPixmap = QPixmap()
        patternPixmap.load(day_pic_path)
        self.mPixmapList.append(patternPixmap)
        arrowPixmap = QPixmap()
        arrowPixmap.load(arrowimg_path)
        self.mPixmapList.append(arrowPixmap)
        self.showImageInGraphicsView()
        return

    def showImageInGraphicsView(self):
        # remove all items in member QGraphicsScene.
        for oneItem in self.mScene.items():
            self.mScene.removeItem(oneItem)

        for onePixmap in self.mPixmapList:
            self.mScene.addPixmap(
                self.getPixMapSizedByWidgt(onePixmap,
                                           self.graphicsViewShowImage))

        self.mScene.setSceneRect(0, 0,
                                 self.graphicsViewShowImage.width() - 5,
                                 self.graphicsViewShowImage.height() - 5)
        return

    def getFeatureInfoString(self, theFeature):
        fieldList = theFeature.fields()
        attrList = theFeature.attributes()
        strFeatureInfo = "field count: %d\n" % len(fieldList)
        for oneField, oneAttr in zip(fieldList, attrList):
            if isinstance(oneAttr, float):
                strFeatureInfo += "%s: %.0f\n" % (oneField.name(), oneAttr)
            else:
                strFeatureInfo += "%s: %s\n" % (oneField.name(), oneAttr)
        return strFeatureInfo

    def comboBoxOutlinkidChanged(self, txt):
        errMsg = ['']
        inti = self.comboBoxOutlinkid.currentIndex()
        self.selectFeatureById(errMsg,
                               self.mSelFeatureIds[inti],
                               bZoomToSelected=False)
        if errMsg[0] <> '':
            QMessageBox.information(self, "Nostra Illust Check",
                                    """error:\n%s""" % errMsg[0])
            return
        return

    def onPushButtonPrev(self):
        self.spinBoxFeatureIndex.setValue(self.spinBoxFeatureIndex.value() - 1)
        prevFeatureId = self.mAllFeatureIds[self.spinBoxFeatureIndex.value() -
                                            1]
        errMsg = ['']
        self.selectFeatureById(errMsg, prevFeatureId)
        if errMsg[0] <> '':
            QMessageBox.information(self, "Nostra Illust Check",
                                    """error:\n%s""" % errMsg[0])
            return
        return

    def onPushButtonNext(self):
        self.spinBoxFeatureIndex.setValue(self.spinBoxFeatureIndex.value() + 1)
        nextFeatureId = self.mAllFeatureIds[self.spinBoxFeatureIndex.value() -
                                            1]
        errMsg = ['']
        self.selectFeatureById(errMsg, nextFeatureId)
        if errMsg[0] <> '':
            QMessageBox.information(self, "Nostra Illust Check",
                                    """error:\n%s""" % errMsg[0])
            return
        return

    def selectFeatureById(self, errMsg, featureId, bZoomToSelected=True):
        self.mTheLayer.removeSelection()
        self.mTheLayer.select(featureId)
        theFeature = self.mTheLayer.selectedFeatures()[0]
        self.showFeatureDetail(errMsg, theFeature)
        if errMsg[0] <> '':
            return
        if bZoomToSelected == True:
            center = self.mTheCanvas.panToSelected(self.mTheLayer)
            self.mTheCanvas.refresh()
        self.clearHighlight()
        arc1 = "%.0f" % theFeature.attribute('arc1')
        sqlcmd = """
SET bytea_output TO escape;
select st_asbinary(the_geom) from temp_topo_link where routeid=%s
""" % arc1
        self.pg.execute(sqlcmd)
        rows = self.pg.fetchall()
        for row in rows:
            qgsGeometry = QgsGeometry()
            qgsGeometry.fromWkb(str(row[0]))
            self.highlightByGeometry(qgsGeometry, QColor(249, 27, 15, 168))

        arc2 = "%.0f" % theFeature.attribute('arc2')
        sqlcmd = """
SET bytea_output TO escape;
select st_asbinary(the_geom) from temp_topo_link where routeid=%s
""" % arc2
        self.pg.execute(sqlcmd)
        rows = self.pg.fetchall()
        for row in rows:
            qgsGeometry = QgsGeometry()
            qgsGeometry.fromWkb(str(row[0]))
            self.highlightByGeometry(qgsGeometry, QColor(22, 151, 0, 168))

        new_arc1 = "%.0f" % theFeature.attribute('new_arc1')
        if new_arc1 is not None and new_arc1 <> arc1:
            sqlcmd = """
SET bytea_output TO escape;
select st_asbinary(the_geom) from temp_topo_link where routeid=%s
""" % new_arc1
            self.pg.execute(sqlcmd)
            rows = self.pg.fetchall()
            for row in rows:
                qgsGeometry = QgsGeometry()
                qgsGeometry.fromWkb(str(row[0]))
                self.highlightByGeometry(qgsGeometry,
                                         QColor(253, 158, 153, 128))

        new_arc2 = "%.0f" % theFeature.attribute('new_arc2')
        if new_arc2 is not None and new_arc2 <> arc2:
            sqlcmd = """
SET bytea_output TO escape;
select st_asbinary(the_geom) from temp_topo_link where routeid=%s
""" % new_arc2
            self.pg.execute(sqlcmd)
            rows = self.pg.fetchall()
            for row in rows:
                qgsGeometry = QgsGeometry()
                qgsGeometry.fromWkb(str(row[0]))
                self.highlightByGeometry(qgsGeometry,
                                         QColor(147, 255, 155, 128))

        return

    def getPixMapSizedByWidgt(self, pixmap, theWidgt):
        pixmapWidth = pixmap.width()
        pixmapHeight = pixmap.height()
        gpViewWidth = theWidgt.width()
        gpViewHeight = theWidgt.height()

        destWidth = 0
        destHeight = 0
        if pixmapWidth > gpViewWidth - 5:
            destWidth = gpViewWidth - 5
        else:
            destWidth = pixmapWidth

        if pixmapHeight > gpViewHeight - 5:
            destHeight = gpViewHeight - 5
        else:
            destHeight = pixmapHeight

        return pixmap.scaled(destWidth, destHeight,
                             QtCore.Qt.IgnoreAspectRatio,
                             QtCore.Qt.SmoothTransformation)

    def mIsMyFeature(self, theFeature):
        return NostraIllustCheckDlg.isMyFeature(theFeature)

    @staticmethod
    def isMyFeature(theFeature):
        try:
            gid = theFeature.attribute('gid')
            arc1 = theFeature.attribute('arc1')
            arc2 = theFeature.attribute('arc2')
            day_pic = theFeature.attribute('day_pic')
            night_pic = theFeature.attribute('night_pic')
            arrowimg = theFeature.attribute('arrowimg')
            lon = theFeature.attribute('lon')
            lat = theFeature.attribute('lat')
            new_arc1 = theFeature.attribute('new_arc1')
            new_arc2 = theFeature.attribute('new_arc2')
        except KeyError, kErr:
            return False
        except Exception, ex:
            return False
Beispiel #41
0
class OWQualityControl(widget.OWWidget):
    name = "Quality Control"
    description = "Experiment quality control"
    icon = "../widgets/icons/QualityControl.svg"
    priority = 5000

    inputs = [("Experiment Data", Orange.data.Table, "set_data")]
    outputs = []

    DISTANCE_FUNCTIONS = [("Distance from Pearson correlation", dist_pcorr),
                          ("Euclidean distance", dist_eucl),
                          ("Distance from Spearman correlation", dist_spearman)
                          ]

    settingsHandler = SetContextHandler()

    split_by_labels = settings.ContextSetting({})
    sort_by_labels = settings.ContextSetting({})

    selected_distance_index = settings.Setting(0)

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

        ## Attributes
        self.data = None
        self.distances = None
        self.groups = None
        self.unique_pos = None
        self.base_group_index = 0

        ## GUI
        box = gui.widgetBox(self.controlArea, "Info")
        self.info_box = gui.widgetLabel(box, "\n")

        ## Separate By box
        box = gui.widgetBox(self.controlArea, "Separate By")
        self.split_by_model = itemmodels.PyListModel(parent=self)
        self.split_by_view = QListView()
        self.split_by_view.setSelectionMode(QListView.ExtendedSelection)
        self.split_by_view.setModel(self.split_by_model)
        box.layout().addWidget(self.split_by_view)

        self.split_by_view.selectionModel().selectionChanged.connect(
            self.on_split_key_changed)

        ## Sort By box
        box = gui.widgetBox(self.controlArea, "Sort By")
        self.sort_by_model = itemmodels.PyListModel(parent=self)
        self.sort_by_view = QListView()
        self.sort_by_view.setSelectionMode(QListView.ExtendedSelection)
        self.sort_by_view.setModel(self.sort_by_model)
        box.layout().addWidget(self.sort_by_view)

        self.sort_by_view.selectionModel().selectionChanged.connect(
            self.on_sort_key_changed)

        ## Distance box
        box = gui.widgetBox(self.controlArea, "Distance Measure")
        gui.comboBox(box,
                     self,
                     "selected_distance_index",
                     items=[name for name, _ in self.DISTANCE_FUNCTIONS],
                     callback=self.on_distance_measure_changed)

        self.scene = QGraphicsScene()
        self.scene_view = QGraphicsView(self.scene)
        self.scene_view.setRenderHints(QPainter.Antialiasing)
        self.scene_view.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.mainArea.layout().addWidget(self.scene_view)

        self.scene_view.installEventFilter(self)

        self._disable_updates = False
        self._cached_distances = {}
        self._base_index_hints = {}
        self.main_widget = None

        self.resize(800, 600)

    def clear(self):
        """Clear the widget state."""
        self.data = None
        self.distances = None
        self.groups = None
        self.unique_pos = None

        with disable_updates(self):
            self.split_by_model[:] = []
            self.sort_by_model[:] = []

        self.main_widget = None
        self.scene.clear()
        self.info_box.setText("\n")
        self._cached_distances = {}

    def set_data(self, data=None):
        """Set input experiment data."""
        self.closeContext()
        self.clear()

        self.error(0)
        self.warning(0)

        if data is not None:
            keys = self.get_suitable_keys(data)
            if not keys:
                self.error(0, "Data has no suitable feature labels.")
                data = None

        self.data = data
        if data is not None:
            self.on_new_data()

    def update_label_candidates(self):
        """Update the label candidates selection GUI 
        (Group/Sort By views).

        """
        keys = self.get_suitable_keys(self.data)
        with disable_updates(self):
            self.split_by_model[:] = keys
            self.sort_by_model[:] = keys

    def get_suitable_keys(self, data):
        """ Return suitable attr label keys from the data where
        the key has at least two unique values in the data.

        """
        attrs = [attr.attributes.items() for attr in data.domain.attributes]
        attrs = reduce(operator.iadd, attrs, [])
        # in case someone put non string values in attributes dict
        attrs = [(str(key), str(value)) for key, value in attrs]
        attrs = set(attrs)
        values = defaultdict(set)
        for key, value in attrs:
            values[key].add(value)
        keys = [key for key in values if len(values[key]) > 1]
        return keys

    def selected_split_by_labels(self):
        """Return the current selected split labels.
        """
        sel_m = self.split_by_view.selectionModel()
        indices = [r.row() for r in sel_m.selectedRows()]
        return [self.sort_by_model[i] for i in indices]

    def selected_sort_by_labels(self):
        """Return the current selected sort labels
        """
        sel_m = self.sort_by_view.selectionModel()
        indices = [r.row() for r in sel_m.selectedRows()]
        return [self.sort_by_model[i] for i in indices]

    def selected_distance(self):
        """Return the selected distance function.
        """
        return self.DISTANCE_FUNCTIONS[self.selected_distance_index][1]

    def selected_base_group_index(self):
        """Return the selected base group index
        """
        return self.base_group_index

    def selected_base_indices(self, base_group_index=None):
        indices = []
        for g, ind in self.groups:
            if base_group_index is None:
                label = group_label(self.selected_split_by_labels(), g)
                ind = [i for i in ind if i is not None]
                i = self._base_index_hints.get(label, ind[0] if ind else None)
            else:
                i = ind[base_group_index]
            indices.append(i)
        return indices

    def on_new_data(self):
        """We have new data and need to recompute all.
        """
        self.closeContext()

        self.update_label_candidates()
        self.info_box.setText(
            "%s genes \n%s experiments" %
            (len(self.data), len(self.data.domain.attributes)))

        self.base_group_index = 0

        keys = self.get_suitable_keys(self.data)
        self.openContext(keys)

        ## Restore saved context settings (split/sort selection)
        split_by_labels = self.split_by_labels
        sort_by_labels = self.sort_by_labels

        def select(model, selection_model, selected_items):
            """Select items in a Qt item model view
            """
            all_items = list(model)
            try:
                indices = [all_items.index(item) for item in selected_items]
            except:
                indices = []
            for ind in indices:
                selection_model.select(model.index(ind),
                                       QItemSelectionModel.Select)

        with disable_updates(self):
            select(self.split_by_view.model(),
                   self.split_by_view.selectionModel(), split_by_labels)

            select(self.sort_by_view.model(),
                   self.sort_by_view.selectionModel(), sort_by_labels)

        with widget_disable(self):
            self.split_and_update()

    def on_split_key_changed(self, *args):
        """Split key has changed
        """
        with widget_disable(self):
            if not self._disable_updates:
                self.base_group_index = 0
                self.split_by_labels = self.selected_split_by_labels()
                self.split_and_update()

    def on_sort_key_changed(self, *args):
        """Sort key has changed
        """
        with widget_disable(self):
            if not self._disable_updates:
                self.base_group_index = 0
                self.sort_by_labels = self.selected_sort_by_labels()
                self.split_and_update()

    def on_distance_measure_changed(self):
        """Distance measure has changed
        """
        if self.data is not None:
            with widget_disable(self):
                self.update_distances()
                self.replot_experiments()

    def on_view_resize(self, size):
        """The view with the quality plot has changed
        """
        if self.main_widget:
            current = self.main_widget.size()
            self.main_widget.resize(size.width() - 6, current.height())

            self.scene.setSceneRect(self.scene.itemsBoundingRect())

    def on_rug_item_clicked(self, item):
        """An ``item`` in the quality plot has been clicked.
        """
        update = False
        sort_by_labels = self.selected_sort_by_labels()
        if sort_by_labels and item.in_group:
            ## The item is part of the group
            if item.group_index != self.base_group_index:
                self.base_group_index = item.group_index
                update = True

        else:
            if sort_by_labels:
                # If the user clicked on an background item it
                # invalidates the sorted labels selection
                with disable_updates(self):
                    self.sort_by_view.selectionModel().clear()
                    update = True

            index = item.index
            group = item.group
            label = group_label(self.selected_split_by_labels(), group)

            if self._base_index_hints.get(label, 0) != index:
                self._base_index_hints[label] = index
                update = True

        if update:
            with widget_disable(self):
                self.split_and_update()

    def eventFilter(self, obj, event):
        if obj is self.scene_view and event.type() == QEvent.Resize:
            self.on_view_resize(event.size())
        return super().eventFilter(obj, event)

    def split_and_update(self):
        """
        Split the data based on the selected sort/split labels
        and update the quality plot.

        """
        split_labels = self.selected_split_by_labels()
        sort_labels = self.selected_sort_by_labels()

        self.warning(0)
        if not split_labels:
            self.warning(0, "No separate by label selected.")

        self.groups, self.unique_pos = \
                exp.separate_by(self.data, split_labels,
                                consider=sort_labels,
                                add_empty=True)

        self.groups = sorted(self.groups.items(),
                             key=lambda t: list(map(float_if_posible, t[0])))
        self.unique_pos = sorted(
            self.unique_pos.items(),
            key=lambda t: list(map(float_if_posible, t[0])))

        if self.groups:
            if sort_labels:
                group_base = self.selected_base_group_index()
                base_indices = self.selected_base_indices(group_base)
            else:
                base_indices = self.selected_base_indices()
            self.update_distances(base_indices)
            self.replot_experiments()

    def get_cached_distances(self, measure):
        if measure not in self._cached_distances:
            attrs = self.data.domain.attributes
            mat = numpy.zeros((len(attrs), len(attrs)))

            self._cached_distances[measure] = \
                (mat, set(zip(range(len(attrs)), range(len(attrs)))))

        return self._cached_distances[measure]

    def get_cached_distance(self, measure, i, j):
        matrix, computed = self.get_cached_distances(measure)
        key = (i, j) if i < j else (j, i)
        if key in computed:
            return matrix[i, j]
        else:
            return None

    def get_distance(self, measure, i, j):
        d = self.get_cached_distance(measure, i, j)
        if d is None:
            vec_i = take_columns(self.data, [i])
            vec_j = take_columns(self.data, [j])
            d = measure(vec_i, vec_j)

            mat, computed = self.get_cached_distances(measure)
            mat[i, j] = d
            key = key = (i, j) if i < j else (j, i)
            computed.add(key)
        return d

    def store_distance(self, measure, i, j, dist):
        matrix, computed = self.get_cached_distances(measure)
        key = (i, j) if i < j else (j, i)
        matrix[j, i] = matrix[i, j] = dist
        computed.add(key)

    def update_distances(self, base_indices=()):
        """Recompute the experiment distances.
        """
        distance = self.selected_distance()
        if base_indices == ():
            base_group_index = self.selected_base_group_index()
            base_indices = [ind[base_group_index] \
                            for _, ind in self.groups]

        assert (len(base_indices) == len(self.groups))

        base_distances = []
        attributes = self.data.domain.attributes
        pb = gui.ProgressBar(self, len(self.groups) * len(attributes))

        for (group, indices), base_index in zip(self.groups, base_indices):
            # Base column of the group
            if base_index is not None:
                base_vec = take_columns(self.data, [base_index])
                distances = []
                # Compute the distances between base column
                # and all the rest data columns.
                for i in range(len(attributes)):
                    if i == base_index:
                        distances.append(0.0)
                    elif self.get_cached_distance(distance, i,
                                                  base_index) is not None:
                        distances.append(
                            self.get_cached_distance(distance, i, base_index))
                    else:
                        vec_i = take_columns(self.data, [i])
                        dist = distance(base_vec, vec_i)
                        self.store_distance(distance, i, base_index, dist)
                        distances.append(dist)
                    pb.advance()

                base_distances.append(distances)
            else:
                base_distances.append(None)

        pb.finish()
        self.distances = base_distances

    def replot_experiments(self):
        """Replot the whole quality plot.
        """
        self.scene.clear()
        labels = []

        max_dist = numpy.nanmax(list(filter(None, self.distances)))
        rug_widgets = []

        group_pen = QPen(Qt.black)
        group_pen.setWidth(2)
        group_pen.setCapStyle(Qt.RoundCap)
        background_pen = QPen(QColor(0, 0, 250, 150))
        background_pen.setWidth(1)
        background_pen.setCapStyle(Qt.RoundCap)

        main_widget = QGraphicsWidget()
        layout = QGraphicsGridLayout()
        attributes = self.data.domain.attributes
        if self.data is not None:
            for (group, indices), dist_vec in zip(self.groups, self.distances):
                indices_set = set(indices)
                rug_items = []
                if dist_vec is not None:
                    for i, attr in enumerate(attributes):
                        # Is this a within group distance or background
                        in_group = i in indices_set
                        if in_group:
                            rug_item = ClickableRugItem(
                                dist_vec[i] / max_dist, 1.0,
                                self.on_rug_item_clicked)
                            rug_item.setPen(group_pen)
                            tooltip = experiment_description(attr)
                            rug_item.setToolTip(tooltip)
                            rug_item.group_index = indices.index(i)
                            rug_item.setZValue(rug_item.zValue() + 1)
                        else:
                            rug_item = ClickableRugItem(
                                dist_vec[i] / max_dist, 0.85,
                                self.on_rug_item_clicked)
                            rug_item.setPen(background_pen)
                            tooltip = experiment_description(attr)
                            rug_item.setToolTip(tooltip)

                        rug_item.group = group
                        rug_item.index = i
                        rug_item.in_group = in_group

                        rug_items.append(rug_item)

                rug_widget = RugGraphicsWidget(parent=main_widget)
                rug_widget.set_rug(rug_items)

                rug_widgets.append(rug_widget)

                label = group_label(self.selected_split_by_labels(), group)
                label_item = QGraphicsSimpleTextItem(label, main_widget)
                label_item = GraphicsSimpleTextLayoutItem(label_item,
                                                          parent=layout)
                label_item.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
                labels.append(label_item)

        for i, (label, rug_w) in enumerate(zip(labels, rug_widgets)):
            layout.addItem(label, i, 0, Qt.AlignVCenter)
            layout.addItem(rug_w, i, 1)
            layout.setRowMaximumHeight(i, 30)

        main_widget.setLayout(layout)
        self.scene.addItem(main_widget)
        self.main_widget = main_widget
        self.rug_widgets = rug_widgets
        self.labels = labels
        self.on_view_resize(self.scene_view.size())