def __init__(self, table, vector, mass=1.0): """Documentation here""" self.name = table.name self._mediator = Mediator() # layout widget x, y = vector.x, vector.y text = QGraphicsSimpleTextItem('{0} as {1}'.format(self.name, self.alias)) width = text.boundingRect().width() QGraphicsRectItem.__init__(self, x, y, width + 10, 22) self.table = table.alias(self.alias) self.setBrush(Qt.cyan) self.setPen(Qt.darkCyan) self.width = width + 10 self.height = 22 self.setFlag(self.ItemIsSelectable, True) text.setParentItem(self) text.setX(x + 5) text.setY(y + 5) self.point = vector self.mass = mass self.velocity = Vector(0, 0) self.force = Vector(0, 0) self.instances.append(self)
def draw_y_axis(self): lineItem = QGraphicsLineItem(0, self.coordY(self.ylim[0]), 0, self.coordY(self.ylim[1]), parent=self.item) lineItem.setPen(QPen(QColor('black'))) lineItem.setZValue(10) max_w = 0 for y in set(self.hlines + list(self.ylim)): lineItem = QGraphicsLineItem(0, self.coordY(y), -5, self.coordY(y), parent=self.item) lineItem.setPen(QPen(QColor('black'))) lineItem.setZValue(10) text = QGraphicsSimpleTextItem(str(y)) text.setFont(QFont("Arial", self.fsize-2)) text.setParentItem(self.item) tw = text.boundingRect().width() max_w = tw if tw > max_w else max_w th = text.boundingRect().height() # Center text according to masterItem size text.setPos(-tw - 5, self.coordY(y)-th/2) if self.ylabel: text = QGraphicsSimpleTextItem(self.ylabel) text.setFont(QFont("Arial", self.fsize-1)) text.setParentItem(self.item) text.rotate(-90) tw = text.boundingRect().width() th = text.boundingRect().height() # Center text according to masterItem size text.setPos(-th -5-max_w, tw/2+self.coordY(sum(self.ylim)/2))
def iLabel(node, *args, **kargs): #code for making specialized faces for intermediates mostly cribbed from the ete2 website example (though not interactive): # http://pythonhosted.org/ete2/tutorial/tutorial_drawing.html#creating-your-custom-interactive-item-faces my_label = node.name ellipse = QGraphicsEllipseItem(0,0,fontSize*2,fontSize*2) #I think the first two are coords of center; second pair is major/minor axis ellipse.setPen(QPen(QColor( 'black' ))) ellipse.setBrush(QBrush(QColor( 'white' ))) text = QGraphicsSimpleTextItem(my_label) text.setParentItem(ellipse) text.setBrush(QBrush(QColor("black"))) font = QFont("Arial",fontSize*.9,weight=80) font.setLetterSpacing(1, 2) #add 2 pixels between letters for legibility text.setFont(font) #Center text according to masterItem size tw = text.boundingRect().width() th = text.boundingRect().height() center = ellipse.boundingRect().center() text.setPos(center.x()+1-tw/2, center.y()-th/2) #since the last letter has an extra 2 pixels after it from the spacing command, adjust center to compensate return ellipse
def draw_x_axis(self): #lineItem = QGraphicsLineItem(self.col_w/2, # self.coordY(self.ylim[0])+2, # self.width-self.col_w/2, # self.coordY(self.ylim[0])+2, # parent=self.item) #lineItem.setPen(QPen(QColor('black'))) #lineItem.setZValue(10) #all_vals = list(range(0, len(self.values), 5)) #if (len(self.values)-1)%5: # all_vals += [len(self.values)-1] for x, lab in enumerate(self.values): # lineItem = QGraphicsLineItem(0, self.coordY(self.ylim[0])+2, # 0, self.coordY(self.ylim[0])+6, # parent=self.item) # lineItem.setX(x*self.col_w + self.col_w/2) # lineItem.setPen(QPen(QColor('black'))) # lineItem.setZValue(10) text = QGraphicsSimpleTextItem(str(lab)) text.rotate(-90) text.setFont(QFont("Arial", self.fsize - 2)) text.setParentItem(self.item) tw = text.boundingRect().height() # Center text according to masterItem size text.setPos(x * self.col_w - tw / 2 + self.col_w / 2, self.coordY(self.ylim[0]))
def iLabel(node, *args, **kargs): #code for making specialized faces for intermediates mostly cribbed from the ete2 website example (though not interactive): # http://pythonhosted.org/ete2/tutorial/tutorial_drawing.html#creating-your-custom-interactive-item-faces my_label = node.name ellipse = QGraphicsEllipseItem( 0, 0, fontSize * 2, fontSize * 2 ) #I think the first two are coords of center; second pair is major/minor axis ellipse.setPen(QPen(QColor('black'))) ellipse.setBrush(QBrush(QColor('white'))) text = QGraphicsSimpleTextItem(my_label) text.setParentItem(ellipse) text.setBrush(QBrush(QColor("black"))) font = QFont("Arial", fontSize * .9, weight=80) font.setLetterSpacing(1, 2) #add 2 pixels between letters for legibility text.setFont(font) #Center text according to masterItem size tw = text.boundingRect().width() th = text.boundingRect().height() center = ellipse.boundingRect().center() text.setPos( center.x() + 1 - tw / 2, center.y() - th / 2 ) #since the last letter has an extra 2 pixels after it from the spacing command, adjust center to compensate return ellipse
def draw_x_axis(self): #lineItem = QGraphicsLineItem(self.col_w/2, # self.coordY(self.ylim[0])+2, # self.width-self.col_w/2, # self.coordY(self.ylim[0])+2, # parent=self.item) #lineItem.setPen(QPen(QColor('black'))) #lineItem.setZValue(10) #all_vals = list(range(0, len(self.values), 5)) #if (len(self.values)-1)%5: # all_vals += [len(self.values)-1] for x, lab in enumerate(self.values): # lineItem = QGraphicsLineItem(0, self.coordY(self.ylim[0])+2, # 0, self.coordY(self.ylim[0])+6, # parent=self.item) # lineItem.setX(x*self.col_w + self.col_w/2) # lineItem.setPen(QPen(QColor('black'))) # lineItem.setZValue(10) text = QGraphicsSimpleTextItem(str(lab)) text.rotate(-90) text.setFont(QFont("Arial", self.fsize-2)) text.setParentItem(self.item) tw = text.boundingRect().height() # Center text according to masterItem size text.setPos(x*self.col_w-tw/2 + self.col_w/2, self.coordY(self.ylim[0]))
def draw_y_axis(self): lineItem = QGraphicsLineItem(0, self.coordY(self.ylim[0]), 0, self.coordY(self.ylim[1]), parent=self.item) lineItem.setPen(QPen(QColor('black'))) lineItem.setZValue(10) max_w = 0 for y in set(self.hlines + list(self.ylim)): lineItem = QGraphicsLineItem(0, self.coordY(y), -5, self.coordY(y), parent=self.item) lineItem.setPen(QPen(QColor('black'))) lineItem.setZValue(10) text = QGraphicsSimpleTextItem(str(y)) text.setFont(QFont("Arial", self.fsize - 2)) text.setParentItem(self.item) tw = text.boundingRect().width() max_w = tw if tw > max_w else max_w th = text.boundingRect().height() # Center text according to masterItem size text.setPos(-tw - 5, self.coordY(y) - th / 2) if self.ylabel: text = QGraphicsSimpleTextItem(self.ylabel) text.setFont(QFont("Arial", self.fsize - 1)) text.setParentItem(self.item) text.rotate(-90) tw = text.boundingRect().width() th = text.boundingRect().height() # Center text according to masterItem size text.setPos(-th - 5 - max_w, tw / 2 + self.coordY(sum(self.ylim) / 2))
def add_text(self): if (self.labels): center = self.item.boundingRect().center() text = QGraphicsSimpleTextItem(str(self.labels)) text.setFont(QFont("Arial", self.label_size)) text.setParentItem(self.item) text.setBrush(QBrush(QColor('#ddd'))) tw = text.boundingRect().width() / 2. th = text.boundingRect().height() / 2. x = -tw + center.x() y = -th + center.y() # Center text according to masterItem size text.setPos(x, y)
def draw_x_axis(self): lineItem = QGraphicsLineItem(self.col_w / 2, self.coordY(self.ylim[0]) + 2, self.width - self.col_w / 2, self.coordY(self.ylim[0]) + 2, parent=self.item) lineItem.setPen(QPen(QColor('black'))) lineItem.setZValue(10) all_vals = list(range(0, len(self.values), self.x_inter_values)) if (len(self.values) - 1) % self.x_inter_values: all_vals += [len(self.values) - 1] hp_x = [] if self.hp: for x in list(range(0, len(self.values))): if self.x_values[x] in self.hp: hp_x.append(x) if not x in all_vals: all_vals += [x] all_vals.sort() for x in all_vals: lineItem = QGraphicsLineItem(0, self.coordY(self.ylim[0]) + 2, 0, self.coordY(self.ylim[0]) + 6, parent=self.item) lineItem.setX(x * self.col_w + self.col_w / 2) lineItem.setPen(QPen(QColor('black'))) lineItem.setZValue(10) if x in hp_x: text = QGraphicsSimpleTextItem("*" + str(self.x_values[x])) qfont = QFont("Arial", self.fsize - 1) #qfont.setBold(True) text.setFont(qfont) else: text = QGraphicsSimpleTextItem(" " + str(self.x_values[x])) text.setFont(QFont("Arial", self.fsize - 1)) text.rotate(-90) text.setParentItem(self.item) text.setZValue(10) tw = text.boundingRect().width() th = text.boundingRect().height() # Center text according to masterItem size text.setPos(x * self.col_w - th / 2 + self.col_w / 2, tw + self.coordY(self.ylim[0]) + 7)
def update_items(self): rect_h = self.height if self.x_axis: rect_h += 30 self.item = QGraphicsRectItem(0, 0, self.width + 40, rect_h) self.item.setPen(QPen(QColor('white'))) #X axis if self.x_axis: self.draw_x_axis() # Legend self.draw_legend() # Y axes and colo rect yi = -1 for model in ["PCOC", "PC", "OC", "Topological", "Identical"]: if self.dict_values_pcoc.has_key(model): yi += 1 y = yi * self.col_w # Y axes ## Stick yaxis = (yi + 0.5) * self.col_w lineItem = QGraphicsLineItem(self.width, yaxis, self.width + 5, yaxis, parent=self.item) lineItem.setPen(QPen(QColor('black'))) ## Text text = QGraphicsSimpleTextItem(model) text.setFont(QFont("Arial", self.fsize - 2)) text.setParentItem(self.item) tw = text.boundingRect().width() th = text.boundingRect().height() ## Center text according to masterItem size text.setPos(self.width + 5, yaxis - th / 2) # Color rect for each model values = self.dict_values_pcoc[model] for i, val in enumerate(values): self.draw_fun(i * self.col_w, y, val, col_width=self.col_w)
def ugly_name_face(node, *args, **kargs): """ This is my item generator. It must receive a node object, and returns a Qt4 graphics item that can be used as a node face. """ # receive an arbitrary number of arguments, in this case width and # height of the faces width = args[0][0] height = args[0][1] ## Creates a main master Item that will contain all other elements ## Items can be standard QGraphicsItem # masterItem = QGraphicsRectItem(0, 0, width, height) # Or your custom Items, in which you can re-implement interactive # functions, etc. Check QGraphicsItem doc for details. masterItem = InteractiveItem(0, 0, width, height) # Keep a link within the item to access node info masterItem.node = node # I dont want a border around the masterItem masterItem.setPen(QPen(QtCore.Qt.NoPen)) # Add ellipse around text ellipse = QGraphicsEllipseItem(masterItem.rect()) ellipse.setParentItem(masterItem) # Change ellipse color ellipse.setBrush(QBrush(QColor( random_color()))) # Add node name within the ellipse text = QGraphicsSimpleTextItem(node.name) text.setParentItem(ellipse) text.setPen(QPen(QPen(QColor("white")))) # Center text according to masterItem size tw = text.boundingRect().width() th = text.boundingRect().height() center = masterItem.boundingRect().center() text.setPos(center.x()-tw/2, center.y()-th/2) return masterItem
def ugly_name_face(node, *args, **kargs): """ This is my item generator. It must receive a node object, and returns a Qt4 graphics item that can be used as a node face. """ # receive an arbitrary number of arguments, in this case width and # height of the faces width = args[0][0] height = args[0][1] ## Creates a main master Item that will contain all other elements ## Items can be standard QGraphicsItem # masterItem = QGraphicsRectItem(0, 0, width, height) # Or your custom Items, in which you can re-implement interactive # functions, etc. Check QGraphicsItem doc for details. masterItem = InteractiveItem(0, 0, width, height) # Keep a link within the item to access node info masterItem.node = node # I dont want a border around the masterItem masterItem.setPen(QPen(QtCore.Qt.NoPen)) # Add ellipse around text ellipse = QGraphicsEllipseItem(masterItem.rect()) ellipse.setParentItem(masterItem) # Change ellipse color ellipse.setBrush(QBrush(QColor(random_color()))) # Add node name within the ellipse text = QGraphicsSimpleTextItem(node.name) text.setParentItem(ellipse) text.setPen(QPen(QPen(QColor("white")))) # Center text according to masterItem size tw = text.boundingRect().width() th = text.boundingRect().height() center = masterItem.boundingRect().center() text.setPos(center.x() - tw / 2, center.y() - th / 2) return masterItem
def iLabel(node, *args, **kargs): #code for making specialized faces for intermediates mostly cribbed from the ete2 website example (though not interactive): # http://pythonhosted.org/ete2/tutorial/tutorial_drawing.html#creating-your-custom-interactive-item-faces my_label = args[0][0] #or maybe just node.name? ellipse = QGraphicsEllipseItem(0,0,fontSize*2,fontSize*2) #I think the first two are coords of center; second pair is major/minor axis ellipse.setBrush(QBrush(QColor( 'black' ))) text = QGraphicsSimpleTextItem(my_label) text.setParentItem(ellipse) text.setBrush(QBrush(QColor("white"))) text.setFont(QFont("Arial",fontSize*.75)) #Center text according to masterItem size tw = text.boundingRect().width() th = text.boundingRect().height() center = ellipse.boundingRect().center() text.setPos(center.x()-tw/2, center.y()-th/2) return ellipse
def draw_legend(self): legend_h = self.height * ((self.nb_models - 1) / float(self.nb_models)) if legend_h < 35: legend_h = 35 legend_rect = QGraphicsRectItem(-20, 0, 10, legend_h, parent=self.item) x0 = -20 n_cat = 6. for y, str_y in [(1, 1), (1 / n_cat * 5, 0.99), (1 / n_cat * 4, 0.9), (1 / n_cat * 3, 0.8), (1 / n_cat * 2, 0.7), (1 / n_cat * 1, 0.5), (1 / n_cat * 0, 0)]: y_stick = legend_h - y * legend_h lineItem = QGraphicsLineItem(x0 - 5, y_stick, x0, y_stick, parent=self.item) lineItem.setPen(QPen(QColor('black'))) text = QGraphicsSimpleTextItem(str(str_y)) text.setFont(QFont("Arial", self.fsize - 4)) text.setParentItem(self.item) tw = text.boundingRect().width() th = text.boundingRect().height() # Center text according to masterItem size text.setPos(x0 - tw - 7, y_stick - th / 2) for (y1, y2, c) in [(1, 1 / n_cat * 5, 0.99), (1 / n_cat * 5, 1 / n_cat * 4, 0.9), (1 / n_cat * 4, 1 / n_cat * 3, 0.8), (1 / n_cat * 3, 1 / n_cat * 2, 0.7), (1 / n_cat * 2, 1 / n_cat * 1, 0.5), (1 / n_cat * 1, 1 / n_cat * 0, 0)]: y1_stick = legend_h - y1 * legend_h y2_stick = legend_h - y2 * legend_h self.draw_fun(x0, y1_stick, c, col_width=10, col_height=y2_stick - y1_stick)
def iLabel(node, *args, **kargs): #code for making specialized faces for intermediates mostly cribbed from the ete2 website example (though not interactive): # http://pythonhosted.org/ete2/tutorial/tutorial_drawing.html#creating-your-custom-interactive-item-faces my_label = args[0][0] #or maybe just node.name? ellipse = QGraphicsEllipseItem( 0, 0, fontSize * 2, fontSize * 2 ) #I think the first two are coords of center; second pair is major/minor axis ellipse.setBrush(QBrush(QColor('black'))) text = QGraphicsSimpleTextItem(my_label) text.setParentItem(ellipse) text.setBrush(QBrush(QColor("white"))) text.setFont(QFont("Arial", fontSize * .75)) #Center text according to masterItem size tw = text.boundingRect().width() th = text.boundingRect().height() center = ellipse.boundingRect().center() text.setPos(center.x() - tw / 2, center.y() - th / 2) return ellipse
def polygon_name_face(node, *args, **kwargs): """create a wedge shaped face in the style of ARB Args: width (int): size in pixels for the width of the wedge height (int): size in pixels for the height of the wedge width_percent (float): change the angle of the point of the wedge. This must be a number between 0 and 1 Returns: QGraphicsRectItem: The Qt graphics item of the polygon """ n_leaves = len(node.get_leaves()) closest_leaf_dist = node.get_closest_leaf()[1] farthest_leaf_dist = node.get_farthest_leaf()[1] base_height = 30 width = 60 height = math.log(n_leaves, 2) + base_height width_percent = closest_leaf_dist / farthest_leaf_dist #print(width, height, width_percent) points = [ (0.0, 0.0), # top left point (width, 0.0), # top right point (width * width_percent, height), # bottom right point (0.0, height), # bottom left point (0.0, 0.0) # back to the beginning ] shape = QPolygonF() for i in points: shape << QtCore.QPointF(*i) ## Creates a main master Item that will contain all other elements ## Items can be standard QGraphicsItem masterItem = QGraphicsRectItem(0, 0, width, height) # Keep a link within the item to access node info masterItem.node = node # I dont want a border around the masterItem masterItem.setPen(QPen(QtCore.Qt.NoPen)) polygon = QGraphicsPolygonItem(shape, masterItem) # Make the wedge grey in color polygon.setBrush(QBrush(QColor( '#D3D3D3'))) # Print the name of the node # Center text according to masterItem size center = masterItem.boundingRect().center() text = QGraphicsSimpleTextItem(node.name) text.setParentItem(polygon) tw = text.boundingRect().width() th = text.boundingRect().height() text.setPos(center.x() + tw/2, center.y() - th/2) # this is a hack to prevent the name being printed twice # we set the node name to blank after we write it with the QGraphicsSimpleTextItem # it must be set to a blank string for it not to be printed later node.name = '' # print the number of collapsed leaves in the polygon leaves_count_text = QGraphicsSimpleTextItem('('+str(n_leaves)+')') leaves_count_text.setParentItem(polygon) leaves_count_text.setFont(QFont('Veranda', 6)) leaves_count_text.setPos(masterItem.boundingRect().x() + 5, center.y() - leaves_count_text.boundingRect().height()/2) polygon.setPos(0, masterItem.boundingRect().y()/1.5) return masterItem
def write_header(self): text = QGraphicsSimpleTextItem(self.header) text.setFont(QFont("Arial", self.fsize)) text.setParentItem(self.item) text.setPos(0, 5)
def write_header(self): text = QGraphicsSimpleTextItem(self.header) text.setFont(QFont("Arial", self.fsize)) text.setParentItem(self.item) text.setPos(0, 5)
class PathHelixHandle(QGraphicsItem): """docstring for PathHelixHandle""" radius = styles.PATHHELIXHANDLE_RADIUS rect = QRectF(0, 0, 2*radius, 2*radius) defBrush = QBrush(styles.grayfill) defPen = QPen(styles.graystroke, styles.PATHHELIXHANDLE_STROKE_WIDTH) hovBrush = QBrush(styles.bluefill) hovPen = QPen(styles.bluestroke, styles.PATHHELIXHANDLE_STROKE_WIDTH) useBrush = QBrush(styles.orangefill) usePen = QPen(styles.orangestroke, styles.PATHHELIXHANDLE_STROKE_WIDTH) def __init__(self, vhelix, parent): super(PathHelixHandle, self).__init__(parent) self.vhelix = vhelix self.parent = parent self.restoreParentItem = parent self.setParentItem(parent) self._number = self.vhelix.number() self.label = None self.focusRing = None self.beingHoveredOver = False self.setAcceptsHoverEvents(True) self.font = QFont("Times", 30, QFont.Bold) self.setNumber() #self.setFlag(QGraphicsItem.ItemIsMovable) self.setFlag(QGraphicsItem.ItemIsSelectable) self.setFlag(QGraphicsItem.ItemSendsScenePositionChanges) # end def def boundingRect(self): return self.rect def paint(self, painter, option, widget=None): if self._number >= 0: if self.isSelected(): painter.setBrush(self.hovBrush) painter.setPen(self.hovPen) else: painter.setBrush(self.useBrush) painter.setPen(self.usePen) else: painter.setBrush(self.defBrush) painter.setPen(self.defPen) if self.beingHoveredOver: painter.setPen(self.hovPen) painter.drawEllipse(self.rect) def setNumber(self): """docstring for setNumber""" if self.label == None: self.label = QGraphicsSimpleTextItem("%d" % self._number) self.label.setFont(self.font) self.label.setParentItem(self) y_val = self.radius / 3 if self._number < 10: self.label.setPos(self.radius / 1.5, y_val) elif self._number < 100: self.label.setPos(self.radius / 3, y_val) else: # _number >= 100 self.label.setPos(0, y_val) def number(self): """docstring for number""" return self._number class FocusRingPainter(QGraphicsItem): """Draws a focus ring around helix in parent""" def __init__(self, helix, scene, parent=None): super(PathHelixHandle.FocusRingPainter, self).__init__(parent) self.parent = parent self.scene = scene self.helix = helix self.setPos(helix.pos()) def paint(self, painter, option, widget=None): painter.setPen(PathHelixHandle.hovPen) painter.drawEllipse(self.helix.rect) def boundingRect(self): return self.helix.rect # end class def hoverEnterEvent(self, event): """ hoverEnterEvent changes the PathHelixHandle brush and pen from default to the hover colors if necessary. """ if self.focusRing == None: self.focusRing = PathHelixHandle.FocusRingPainter(self,\ self.scene(),\ self.parentItem()) self.update(self.rect) # end def def hoverLeaveEvent(self, event): """ hoverEnterEvent changes the PathHelixHanle brush and pen from hover to the default colors if necessary. """ if self.focusRing != None: self.focusRing.setParentItem(None) self.focusRing = None self.update(self.rect) # end def def mousePressEvent(self, event): selectionGroup = self.group() if selectionGroup == None: selectionGroup = self.parent.phhSelectionGroup selectionGroup.setSelected(False) selectionGroup.addToGroup(self) self.setSelected(True) selectionGroup.mousePressEvent(event) # end def def restoreParent(self): tempP = self.restoreParentItem.mapFromItem(self.parentItem(), self.pos()) self.setParentItem(self.restoreParentItem) self.setPos(tempP) # end def def itemChange(self, change, value): # for selection changes test against QGraphicsItem.ItemSelectedChange # intercept the change instead of the has changed to enable features. # if change == QGraphicsItem.ItemSelectedHasChanged and self.scene(): if change == QGraphicsItem.ItemSelectedChange and self.scene(): selectionGroup = self.parent.phhSelectionGroup lock = selectionGroup.parentItem().selectionLock if value == True and (lock == None or lock == selectionGroup): selectionGroup.addToGroup(self) selectionGroup.parentItem().selectionLock = selectionGroup return QGraphicsItem.itemChange(self, change, True) # end if else: return QGraphicsItem.itemChange(self, change, False) # end else self.update(self.boundingRect()) return QGraphicsItem.itemChange(self, change, value)