def update_items(self): rect_cls = QGraphicsRectItem self.item = rect_cls(0, 0, self.width, self.row_h) seq_width = 0 nopen = QPen(Qt.NoPen) font = QFont(self.ftype, self.fsize) for i, letter in enumerate(self.seq): width = self.col_w rectitem = rect_cls(0, 0, width, self.row_h, parent=self.item) rectitem.setX(seq_width) # to give correct X to children item rectitem.setBrush(self.bg_col[letter]) rectitem.setPen(nopen) # write letter if enough space if width >= self.fsize: text = None if self.style == "codon": text = QGraphicsTextItem(parent=rectitem) text.setHtml(self.get_html(i, self.fg_col[letter])) else: text = QGraphicsSimpleTextItem(letter, parent=rectitem) text.setBrush(QBrush(QColor(self.fg_col[letter]))) text.setFont(font) # Center text according to rectitem size txtw = text.boundingRect().width() txth = text.boundingRect().height() text.setPos((width - txtw) / 2, (self.row_h - txth) / 2) seq_width += width self.width = seq_width
def createImage(self, transform): if self.type == DemoTextItem.DYNAMIC_TEXT: return None sx = min(transform.m11(), transform.m22()) sy = max(transform.m22(), sx) textItem = QGraphicsTextItem() textItem.setHtml(self.text) textItem.setTextWidth(self.textWidth) textItem.setFont(self.font) textItem.setDefaultTextColor(self.textColor) textItem.document().setDocumentMargin(2) w = textItem.boundingRect().width() h = textItem.boundingRect().height() image = QImage(int(w * sx), int(h * sy), QImage.Format_ARGB32_Premultiplied) image.fill(QColor(0, 0, 0, 0).rgba()) painter = QPainter(image) painter.scale(sx, sy) style = QStyleOptionGraphicsItem() textItem.paint(painter, style, None) return image
def render_items(self, event=None): self.links = self.get_links_dict() self.render_preview() for item in self.settings['items']: text = QGraphicsTextItem() font_color = QColor('black') text.setPos(QPointF(item['x'], item['y'])) font = QFont() font_name = item['params'].get(const.ITEM_DATA_KEY_FONT) if font_name: font.fromString(font_name) font_size = item['params'].get(const.ITEM_DATA_KEY_FONT_SIZE) if font_size: font.setPointSize(font_size) else: font.setPointSize(12) font_color_list = item['params'].get( const.ITEM_DATA_KEY_FONT_COLOR) if font_color_list: font_color.setRgb(*font_color_list) text.setFont(font) text_align = item['params'].get(const.ITEM_DATA_KEY_FONT_ALIGN) text.setFont(font) text.setTextWidth(item['w']) text.setDefaultTextColor(font_color) text.setHtml( f"<div align='{text_align}'>{self.test_row[self.links[item['name']]]}</div>" ) self.scene.addItem(text)
class AnimatedClock(QGraphicsView): def __init__(self, parent=None): QGraphicsView.__init__(self, parent) self.updateSecs = 0.5 # Border self.setLineWidth(0) self.setFrameShape(QtWidgets.QFrame.NoFrame) # Size sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) sizePolicy.setHeightForWidth(True) self.setSizePolicy(sizePolicy) # No scrollbars self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # Scene self.scene = QGraphicsScene() self.setScene(self.scene) self.setBackgroundBrush(QColor("black")) # Text of clock self.textItem = QGraphicsTextItem() self.textItem.color = QColor(QColor("black")) self.textItem.setFont(QFont("Segoe UI", 80)) self.textItem.setDefaultTextColor(QColor("white")) self.textItem.setHtml("") self.textItem.setZValue(20) self.scene.addItem(self.textItem) # Start ticking self.start() def sizeHint(self): return QSize(300, 150) def start(self): self.updateTimer = QTimer() self.updateTimer.setInterval(self.updateSecs * 990) self.updateTimer.timeout.connect(self.updateClock) self.updateTimer.start() print("Animated clock - starting") def stop(self): if self.updateTimer != None: self.updateTimer.stop() print("Animated clock - stopping") def updateClock(self): localtime = time.localtime() timeString = time.strftime("%H:%M:%S", localtime) self.textItem.setHtml(timeString) width = self.frameGeometry().width() self.textItem.setFont(QFont("Segoe UI", width / 8)) self.textItem.update() def heightForWidth(self, width): return width * .32 def keyPressEvent(self, event): #QKeyEvent event.ignore()
def showImage(self): (newImg, newImgInfo) = self.loadImage() # return PicItem(Pixmap(QPixmap(newImg)), -1, -1, xFactor, yFactor, newImgInfo) self.scene.clear() imgSz = newImgInfo.imgSize self.setSceneRect(QRectF(0,0,imgSz.width(), imgSz.height())) pixMap = QPixmap.fromImage(newImg) # # pixMap.setWidth(self.width()) pixMapItem = self.scene.addPixmap(pixMap) # pixMapItem.setPos(50,50) # self.fitInView(QRectF(0, 0, self.width(), self.height()), Qt.KeepAspectRatio) # Add caption caption = QGraphicsTextItem() caption.setDefaultTextColor(QColor(255,255,255)) caption.setPos(0, self.height()*0.94) caption.setFont(QFont("Segoe UI", 30)) caption.setTextWidth(self.width()) # caption.setPos(100, 100) # caption.setTextWidth(1500) # if newImgInfo.createDate is not None: # caption.setPlainText(newImgInfo.createDate.format()); # else: # caption.setPlainText("Image is called bananas"); # print("Tags", newImgInfo.tags) # tagStr = "" # for tag in newImgInfo.tags: # if tag != "Duplicate": # tagStr += (", " if len(tagStr) != 0 else "") + tag # if tagStr == "": # tagStr = "NO TAGS" # captionStr = '<h1 style="text-align:center;width:100%">' + tagStr + '</h1>' # if newImgInfo.createDate is not None: # print(newImgInfo.createDate.format()) # captionStr += '<BR><h2>' + newImgInfo.createDate.format() + '</h2>' captionStr = "" try: if newImgInfo.rating is not None: for i in range(newImgInfo.rating): captionStr += "★" for i in range(5-newImgInfo.rating): captionStr += "☆" if newImgInfo.mainDate is not None: if len(captionStr) != 0: captionStr += " " captionStr += newImgInfo.mainDate.strftime("%d %b %Y") except Exception as excp: print("StaticPhotos: Cannot set caption") captionStr = '<div style="background-color:#000000;text-align: right;padding-right:10dp;">' + captionStr + "</div>" print(captionStr) caption.setHtml(captionStr) self.scene.addItem(caption) self.scene.update()
class PickingStation(VisualizerGraphicItem): def __init__(self, ID=0, x=0, y=0): super(self.__class__, self).__init__(ID, x, y) self._kind_name = 'pickingStation' self._items = [] self._graphics_item = QGraphicsRectItem(self) self._items.append(QGraphicsRectItem(self._graphics_item)) self._items.append(QGraphicsRectItem(self._graphics_item)) self._text = QGraphicsTextItem(self._graphics_item) def set_rect(self, rect): scale = config.get('display', 'id_font_scale') bold = config.get('display', 'id_font_bold') self._text.setFont(QFont('', rect.width() * 0.08 * scale)) self._text.setPos(rect.x(), rect.y() + 0.6 * rect.height()) self._text.setDefaultTextColor( QColor(config.get('display', 'id_font_color'))) if self._display_mode == 0: if bold: self._text.setHtml('<b>P(' + str(self._id) + ')</b>') else: self._text.setHtml('P(' + str(self._id) + ')') self._graphics_item.setRect(rect.x(), rect.y(), rect.width(), rect.height()) self._items[0].setRect(rect.x() + rect.width() / 5, rect.y(), rect.width() / 5, rect.height()) self._items[1].setRect(rect.x() + rect.width() / 5 * 3, rect.y(), rect.width() / 5, rect.height()) elif self._display_mode == 1: self._text.setPlainText('') self._graphics_item.setRect(rect.x(), rect.y(), rect.width(), rect.height()) self._items[0].setRect(rect.x() + rect.width() / 5, rect.y(), rect.width() / 5, rect.height()) self._items[1].setRect(rect.x() + rect.width() / 5 * 3, rect.y(), rect.width() / 5, rect.height()) def determine_color(self, number, count, pattern=None): color = self._colors[0] color2 = self._colors[1] color.setAlpha(150) color2.setAlpha(150) brush = QBrush(color) brush2 = QBrush(color2) self._graphics_item.setBrush(brush) self._items[0].setBrush(brush2) self._items[1].setBrush(brush2) def get_rect(self): return self._graphics_item.rect()
def add_text(self, text, item_list): items = [] text_item = QGraphicsTextItem(text) text_item.setFont(ComparisionChart.arial_font) text_item.setPos(0,0) items.append(text_item) next_y = text_item.boundingRect().height()+5 html = "<br />".join(sorted(item_list)) text_item = QGraphicsTextItem() text_item.setHtml(html) text_item.setFont(ComparisionChart.font) text_item.setPos(5,next_y) items.append(text_item) group = self.scene.createItemGroup(items) return group
class PointOfInterest: def __init__(self, **kwargs): super().__init__() self.location = MapPoint() self.__dict__.update(kwargs) self.text = QGraphicsTextItem() self.text.setHtml("<font color='{}' size='{}'>{}</font>".format( self.location.color.name(), 1 + self.location.size, '\u272a' + self.location.text)) self.text.setZValue(2) self.text.setPos(self.location.x, self.location.y) def update_(self, scale): self.text.setScale(scale) self.text.setPos( self.location.x - self.text.boundingRect().width() * 0.05 * scale, self.location.y - self.text.boundingRect().height() / 2 * scale)
class AnimatedClock(): updateTimer = None calDataLock = threading.Lock() calDataUpdated = False curCalendars = None def __init__(self, scene, widthClkTextArea, heightClkTextArea, borders, updateSecs): self.masterScene = scene self.widthClkTextArea = widthClkTextArea self.heightClkTextArea = heightClkTextArea self.borders = borders self.updateSecs = updateSecs # Background self.textBkgd = QGraphicsRectItem(0, 0, self.widthClkTextArea, self.heightClkTextArea) self.textBkgd.setPos(self.borders[3], self.borders[0]) self.textBkgd.setBrush(QColor("light green")) self.textBkgd.setZValue(10) scene.addItem(self.textBkgd) # Text Item self.textItem = QGraphicsTextItem() self.textItem.setFont(QFont("Segoe UI", 80)) self.textItem.setDefaultTextColor(QColor("black")) self.textItem.setPos(QPointF(self.borders[3]+10,self.borders[0]+5)) self.textItem.setHtml("<B>Clock</B>") self.textItem.setZValue(20) self.textItem.setTextWidth(self.widthClkTextArea-20) scene.addItem(self.textItem) def start(self): self.updateTimer = QTimer() self.updateTimer.setInterval(self.updateSecs * 1000) self.updateTimer.timeout.connect(self.updateClock) self.updateTimer.start() def stop (self): if self.updateTimer != None: self.updateTimer.stop() def updateClock(self): localtime = time.localtime() # dateString = time.strftime("%a %d %b %Y", localtime) timeString = time.strftime("%H:%M:%S", localtime) self.textItem.setHtml(timeString) # self.textItem.setTextWidth(self.widthCalTextArea-20) self.textItem.update()
class MainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.view = VideoGraphicsView() self.setCentralWidget(self.view) self.view.videoItem.nativeSizeChanged.connect( self.handle_native_size_changed) url = QUrl( "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4" ) self.view.player.setMedia(QMediaContent(url)) self.view.player.play() self.resize(640, 480) self.text_item = QGraphicsTextItem(self.view.videoItem) self.text_item.setHtml( """<div style="color: #41CD52; font-weight: bold; font-size: 20px;">Qt is awesome</div>""" ) self.text_item.hide() self.animation = QVariantAnimation() self.animation.setDuration(1000) self.animation.setStartValue(QPointF(0.0, 0.0)) self.animation.setEndValue(QPointF(0.0, 0.0)) self.animation.valueChanged.connect(self.text_item.setPos) self.animation.finished.connect(self.start_of_start_animation) def handle_native_size_changed(self): self.start_of_start_animation() def start_of_start_animation(self): w = self.view.videoItem.size().width() - self.text_item.boundingRect( ).width() h = self.view.videoItem.size().height() - self.text_item.boundingRect( ).height() end_pos_x = random.uniform(0, w) end_pos_y = random.uniform(0, h) self.animation.setStartValue(self.animation.endValue()) self.animation.setEndValue(QPointF(end_pos_x, end_pos_y)) self.text_item.show() self.animation.start()
def label_maker(node, label): """Form correctly formatted leaf label.""" face = QGraphicsTextItem() face.setHtml(label) # Create parent RectItem with TextItem in center fbox = face.boundingRect() rect = QGraphicsRectItem(0, 0, fbox.width(), fbox.height()) rbox = rect.boundingRect() face.setPos(rbox.x(), rbox.center().y() - fbox.height() / 2) # Remove border rect.setPen(QPen(QtCore.Qt.NoPen)) # Set as parent item so DynamicItemFace can use .rect() method face.setParentItem(rect) return rect
def _constructTree(self, node, x, y, par_x, par_y, text, depth=1, h_index=0): node_item = BinTreeNodeGraphicsItem(text, node.data, depth) node_item.setBrush(Qt.white) self.addItem(node_item) node_item.moveBy(x, y) dx, dy = self.width() / (2 ** (depth + 2)), 4 * self.rad text_item = QGraphicsTextItem() text_item.setHtml(text+"</sub>") text_item.moveBy(x-self.rad/2, y-self.rad/2) self.addItem(text_item) edge = QGraphicsLineItem(x, y, par_x, par_y) edge.setZValue(-1) self.addItem(edge) if node.left: new_text = text + "1" self._constructTree(node.left, x-dx, y+dy, x, y, new_text, depth+1, 2*h_index) if node.right: new_text = text + "2" self._constructTree(node.right, x+dx, y+dy, x, y, new_text, depth+1, 2*h_index+1)
class AnimatedCalendar(): updatesRunning = False updateTimer = None listUpdateThread = None calDataLock = threading.Lock() calDataUpdated = False curCalendars = None def __init__(self, scene, widthCalTextArea, heightCalTextArea, borders, calFeeds, calUpdateSecs): self.masterScene = scene self.widthCalTextArea = widthCalTextArea self.heightCalTextArea = heightCalTextArea self.borders = borders self.calFeeds = calFeeds self.calendarUpdateSecs = calUpdateSecs # Background self.textBkgd = QGraphicsRectItem(0, 0, self.widthCalTextArea, self.heightCalTextArea) self.textBkgd.setPos(self.borders[3], self.borders[0]) self.textBkgd.setBrush(QColor("light green")) self.textBkgd.setZValue(10) scene.addItem(self.textBkgd) # Text Item self.textItem = QGraphicsTextItem() self.textItem.setFont(QFont("Segoe UI", 24)) self.textItem.setDefaultTextColor(QColor("black")) self.textItem.setPos(QPointF(self.borders[3]+10,self.borders[0]+10)) self.textItem.setHtml("<B>Hello</B>Hello") self.textItem.setZValue(20) self.textItem.setTextWidth(self.widthCalTextArea-20) scene.addItem(self.textItem) def start(self): self.updatesRunning = True QTimer.singleShot(100, self.updateCalendar) self.listUpdateThread = CalendarUpdateThread(self, self.calFeeds, self.calendarUpdateSecs) self.listUpdateThread.start() # print("CalStarted") def stop (self): self.updatesRunning = False if self.updateTimer != None: self.updateTimer.stop() if self.listUpdateThread != None: self.listUpdateThread.stop() def setNewCalendarEntries(self, calendars): with self.calDataLock: self.curCalendars = calendars self.calDataUpdated = True def updateCalendar(self): # print("Update cal") with self.calDataLock: if self.calDataUpdated and self.curCalendars != None: for calEvents in self.curCalendars: calStr = "" lastDay = -1 for anEvent in calEvents: # date, duration, summary, location, UID eventDate = anEvent[0] duration = anEvent[1] summary = anEvent[2] location = anEvent[3] if lastDay != eventDate.day: if lastDay != -1: calStr += "<br/>" calStr += "<b>" + anEvent[0].strftime("%a") + " (" + anEvent[0].strftime("%d %B)") + ")</b><br/>" lastDay = eventDate.day strDurTime = str(duration).rpartition(":")[0] durStr = (str(duration.days) + "day" + ("s" if duration.days != 1 else "")) if duration.days > 0 else strDurTime locStr = "<small>("+location+")</small>" if location != "" else "" calStr += anEvent[0].strftime("%H:%M") + " <small>(" + durStr + ")</small> " + summary + " " + locStr + "<br/>" # print (anEvent) # print(date) self.textItem.setHtml(calStr) self.textItem.setTextWidth(self.widthCalTextArea-20) self.textItem.update() self.calDataUpdated = False if not self.updatesRunning: return self.updateTimer = QTimer() self.updateTimer.setInterval(5000) self.updateTimer.setSingleShot(True) self.updateTimer.timeout.connect(self.updateCalendar) self.updateTimer.start()
class Checkpoint(VisualizerGraphicItem): def __init__(self, ID=0, x=0, y=0): super(self.__class__, self).__init__(ID, x, y) self._kind_name = 'checkpoint' self._ids = {} self._graphics_item = QGraphicsRectItem(self) self._text = QGraphicsTextItem(self._graphics_item) self._shine = False def set_rect(self, rect): scale = config.get('display', 'id_font_scale') bold = config.get('display', 'id_font_bold') font = QFont('', rect.width() * 0.08 * scale) self._text.setFont(font) self._text.setPos(rect.x(), rect.y() + 0.6 * rect.height()) self._text.setDefaultTextColor( QColor(config.get('display', 'id_font_color'))) if self._display_mode == 0: ss = '' if bold: ss = '<b>' for key in self._ids: count = 0 for ii in self._ids[key]: if count == 0: ss = ss + '(' + key + ': ' + ii[0] else: ss = ss + ', ' + ii[0] count += 1 ss = ss + ')\n' if bold: ss += '</b>' self._text.setHtml(ss) self._graphics_item.setRect(rect.x(), rect.y(), rect.width(), rect.height()) elif self._display_mode == 1: self._text.setPlainText('') self._graphics_item.setRect(rect.x(), rect.y(), rect.width(), rect.height()) def do_action(self, time_step): self._shine = False return def undo_action(self, time_step): self._shine = False return def visit(self): self._shine = True def determine_color(self, number, count, pattern=None): color = None if len(self._ids) == 1: for key in self._ids: color_id = self._ids[key][0][1] + 1 if color_id < len(self._colors): color = self._colors[color_id] if color is None: color = self._colors[0] if self._shine: color = calculate_color(color, QColor(255, 255, 255), 0.4) self._graphics_item.setBrush(QBrush(color)) def parse_init_value(self, name, value): result = super(self.__class__, self).parse_init_value(name, value) if result != 1: return result if name == 'checkpoint' and len(value.arguments) == 3: if str(value.arguments[0]) not in self._ids: self._ids[str(value.arguments[0])] = [] self._ids[str(value.arguments[0])].append( (str(value.arguments[1]), value.arguments[2].number)) return 0 return 1 def get_rect(self): return self._graphics_item.rect()
class Robot(VisualizerGraphicItem): def __init__(self, ID=0, x=0, y=0): super(self.__class__, self).__init__(ID, x, y) self._kind_name = 'robot' self._carries = None self._initial_carries = None self._tasks = [] self._graphics_item = QGraphicsRectItem(self) self._text = QGraphicsTextItem(self) self.setZValue(1.0) def set_position(self, x, y): super(self.__class__, self).set_position(x, y) if self._carries is not None: self._carries.set_position(x, y) def set_starting_position(self, x, y): super(self.__class__, self).set_starting_position(x, y) if self._initial_carries is not None: self._initial_carries.set_starting_position(x, y) def set_carries(self, shelf): if shelf == self._carries: return old = self._carries self._carries = shelf if old != None: old.set_carried(None) if self._carries != None: self._carries.set_carried(self) def set_initial_carries(self, shelf): self._initial_carries = shelf def set_rect(self, rect): scale = config.get('display', 'id_font_scale') bold = config.get('display', 'id_font_bold') self._text.setFont(QFont('', rect.width() * 0.08 * scale)) self._text.setPos(rect.x(), rect.y() + 0.2 * rect.height()) self._text.setDefaultTextColor( QColor(config.get('display', 'id_font_color'))) if self._display_mode == 0: if bold: self._text.setHtml('<b>R(' + str(self._id) + ')</b>') else: self._text.setHtml('R(' + str(self._id) + ')') self._graphics_item.setRect( rect.x() + 0.25 * rect.width(), rect.y() + 0.25 * rect.height(), rect.width() * 0.5, rect.height() * 0.5, ) elif self._display_mode == 1: self._text.setPlainText('') self._graphics_item.setRect(rect.x() + 0.05 * rect.width(), rect.y() + 0.05 * rect.height(), rect.width() * 0.9, rect.height() * 0.9) if self._carries is not None: self._carries.set_rect(rect) def add_task(self, task): if task is None: return if task in self._tasks: return self._tasks.append(task) task.set_robot(self) def parse_init_value(self, name, value): result = super(self.__class__, self).parse_init_value(name, value) if result <= 0: return result if name == 'carries': shelf = self._model.get_item('shelf', value, True, True) self.set_initial_carries(shelf) self.set_carries(shelf) return 0 return 1 def restart(self): super(self.__class__, self).restart() self.set_carries(self._initial_carries) def to_init_str(self): s = super(self.__class__, self).to_init_str() if self._initial_carries is not None: s += ("init(object(robot," + str(self._id) + "),value(carries," + str(self._initial_carries.get_id()) + ")).") return s def do_action(self, time_step): if time_step >= len(self._actions): return 0 #break, if no action is defined if self._actions[time_step] == None: return 0 #break, if no action is defined if self._model is None: return -3 try: action = self._actions[time_step].arguments[0] value = self._actions[time_step].arguments[1] except: return -1 if action.name == 'move': if len(value.arguments) != 2: return -1 try: move_x = value.arguments[0].number move_y = value.arguments[1].number self.set_position(self._position[0] + move_x, self._position[1] + move_y) except: self.set_position(self._position[0], self._position[1]) for task in self._tasks: for checkpoint in task.get_checkpoints(): checkpoint = checkpoint[0] pos = checkpoint.get_position() if pos[0] == self._position[0] and pos[ 1] == self._position[1]: task.visit_checkpoint(checkpoint) break return 1 elif action.name == 'pickup': shelf = self._model.filter_items(item_kind='shelf', position=self._position, return_first=True)[0] if shelf is None: return -2 self.set_carries(shelf) return 2 elif action.name == 'putdown': if self._carries == None: return -2 self.set_carries(None) return 3 elif action.name == 'deliver' and len(value.arguments) > 2: try: if self._carries is not None: self._carries.remove_product(value.arguments[1], value.arguments[2].number) order = self._model.filter_items(item_kind='order', ID=value.arguments[0], return_first=True)[0] if order is None: return -2 order.deliver(value.arguments[1], value.arguments[2].number, time_step) except: return -3 return 4 elif action.name == 'deliver' and len(value.arguments) > 1: try: if self._carries is not None: self._carries.remove_product(value.arguments[1], 0) order = self._model.filter_items(item_kind='order', ID=value.arguments[0], return_first=True)[0] if order is None: return -2 order.deliver(value.arguments[1], 0, time_step) except: return -3 return 5 return 0 def undo_action(self, time_step): if time_step >= len(self._actions): return 0 #break, if no action is defined if self._actions[time_step] == None: return 0 #break, if no action is defined if self._model is None: return -3 try: action = self._actions[time_step].arguments[0] value = self._actions[time_step].arguments[1] except: return -1 if action.name == 'move': if len(value.arguments) != 2: return -1 for task in self._tasks: for checkpoint in task.get_checkpoints(): checkpoint = checkpoint[0] pos = checkpoint.get_position() if pos[0] == self._position[0] and pos[ 1] == self._position[1]: task.unvisit_checkpoint(checkpoint) break try: move_x = value.arguments[0].number move_y = value.arguments[1].number self.set_position(self._position[0] - move_x, self._position[1] - move_y) except: self.set_position(self._position[0], self._position[1]) if self._carries is not None: self._carries.set_position(self._position[0], self._position[1]) return 1 elif action.name == 'putdown': shelf = self._model.filter_items(item_kind='shelf', position=self._position, return_first=True)[0] if shelf is None: return -2 self.set_carries(shelf) return 3 elif action.name == 'pickup': if self._carries == None: return -2 self.set_carries(None) return 2 elif action.name == 'deliver' and len(value.arguments) > 2: try: if self._carries is not None: self._carries.remove_product(value.arguments[1], -value.arguments[2].number) order = self._model.filter_items(item_kind='order', ID=value.arguments[0], return_first=True)[0] if order is None: return -2 order.deliver(value.arguments[1], -value.arguments[2].number, time_step) except: return -3 return 4 elif action.name == 'deliver' and len(value.arguments) > 1: try: if self._carries is not None: self._carries.remove_product(value.arguments[1], 0) order = self._model.filter_items(item_kind='order', ID=value.arguments[0], return_first=True)[0] if order is None: return -2 order.deliver(value.arguments[1], 0, time_step) except: return -3 return 5 return 0 def determine_color(self, number, count, pattern=None): color = calculate_color(self._colors[0], self._colors[1], (float)(number) / count) brush = QBrush(color) self._graphics_item.setBrush(brush) def get_rect(self): if self._display_mode == 0: rect = self._graphics_item.rect() width = rect.width() * 2 height = rect.height() * 2 rect.setLeft(rect.x() - 0.25 * width) rect.setTop(rect.y() - 0.25 * height) rect.setWidth(width) rect.setHeight(height) return rect elif self._display_mode == 1: rect = self._graphics_item.rect() width = rect.width() / 0.9 height = rect.height() / 0.9 rect.setLeft(rect.x() - 0.05 * width) rect.setTop(rect.y() - 0.05 * height) rect.setWidth(width) rect.setHeight(height) return rect def get_carries(self): return self._carries def get_initial_carries(self): return self._initial_carries def edit_position_to(self, x, y): if (x, y) == self._position: return item2 = self._model.filter_items(item_kind=self._kind_name, position=(x, y), return_first=True)[0] shelf = self._model.filter_items('shelf', position=self._position, return_first=True)[0] shelf2 = self._model.filter_items('shelf', position=(x, y), return_first=True)[0] if shelf2 is not None and shelf is not None: if shelf.get_carried() is not None or shelf2.get_carried( ) is not None: shelf.set_position(x, y) shelf.set_starting_position(x, y) shelf2.set_position(self._position[0], self._position[1]) shelf2.set_starting_position(self._position, self._position[1]) if item2 is not None: item2.set_position(self._position[0], self._position[1]) item2.set_starting_position(self._position[0], self._position[1]) self.set_position(x, y) self.set_starting_position(x, y)
class HumanoidLeagueRelativeRqt(Plugin): """ This class provides a rqt plugin which shows a 2d view of a RoboCup Soccer field. Different objects can be shown. Their position changing is handled in the respective callbacks.""" def __init__(self, context): super(HumanoidLeagueRelativeRqt, self).__init__(context) self.setObjectName('2dField') # color values self.green = np.array([30, 186, 44]) self.red = np.array([186, 45, 30]) # outlines self.outline_thickness = 9 self.goal_outline = QColor(250, 0, 0) self.ball_outline = QColor(0, 0, 250) self.obstacle_outline = QColor(30, 30, 30) # image values self.image_width = 1200.0 self.image_height = 1200.0 self.meter_length_img = 50 self.scale = 1 # scaling factor between meters in reality and pixels on display # object values self.obstacle_size = 75 self.obstacle_pen_width = 5 self.ball_size = 50 self.opacity = 0.75 self.post_size = 50 self.center_size = 30 self.obsacle_size = 50 self.ball_active = True self.goal_active = True # initialize the UI self._widget = QWidget() rp = rospkg.RosPack() ui_file = os.path.join(rp.get_path('humanoid_league_relative_rqt'), 'resource', 'relative.ui') loadUi(ui_file, self._widget) self._widget.setObjectName('2dFieldUi') if context.serial_number() > 1: self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number())) self._widget.resize_push_button.setIcon( QIcon.fromTheme('view-refresh')) self._widget.resize_push_button.pressed.connect(self.resize_field) # set drawing space self.view = self._widget.graphics_view self.view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self._scene = QGraphicsScene() self._scene.setBackgroundBrush(QColor(255, 255, 255)) # radar object rp = rospkg.RosPack() image_path = rp.get_path( 'humanoid_league_relative_rqt') + "/resource/radar.png" field_image = QPixmap(image_path) self.radar = QGraphicsPixmapItem(field_image) self.radar.setPos(0, 0) self._scene.addItem(self.radar) # legend self.legend = QGraphicsTextItem(self.radar) html_legend = ('<p style="font-size: 50px;">Legend</p> \ <div style="font-size: 30px"><li>\ <ul style="color: rgb{};">Goal outline</ul>\ <ul style="color: rgb{};">Ball outline</ul>\ <ul style="color: rgb{};">Obstacle outline</ul>\ <ul style="color: rgb{};">Low confidence</ul>\ <ul style="color: rgb{};">High confidence</ul>\ </li></div>'.format(self.QColor2String(self.goal_outline), self.QColor2String(self.ball_outline), self.QColor2String(self.obstacle_outline), self.Npcolor2String(self.red), self.Npcolor2String(self.green))) self.legend.setHtml(html_legend) self.legend.setPos(self.image_width, 50) # ball self.ball_pen = QPen(self.ball_outline) self.ball_pen.setWidth(self.outline_thickness) # goal posts self.post_pen = QPen(self.goal_outline) self.post_pen.setWidth(self.outline_thickness) self.left_post = QGraphicsEllipseItem(0, 0, self.post_size, self.post_size, self.radar) self.left_post.setPen(self.post_pen) self.left_post.setVisible(False) self.left_post.setOpacity(self.opacity) self.right_post = QGraphicsEllipseItem(0, 0, self.post_size, self.post_size, self.radar) self.right_post.setPen(self.post_pen) self.right_post.setVisible(False) self.right_post.setOpacity(self.opacity) # goal center self.center_pen = QPen(self.goal_outline) self.center_pen.setWidth(self.outline_thickness) self.center = QGraphicsEllipseItem(0, 0, self.center_size, self.center_size, self.radar) self.center.setPen(self.center_pen) self.center.setVisible(False) self.center.setOpacity(self.opacity) # Obstacles self.obstacle_pen = QPen(self.obstacle_outline) self.obstacle_pen.setWidth(self.outline_thickness) self.obstacles = [] # set the right positions and sizes self.resize_field() self.view.setScene(self._scene) # self.dyn_reconf = Server(field_rqt_params, self.reconfigure) rospy.Subscriber("balls_relative", PoseWithCertaintyArray, self.balls_cb, queue_size=100) rospy.Subscriber("goal_relative", GoalRelative, self.goal_cb, queue_size=100) rospy.Subscriber("obstacles_relative", ObstacleRelativeArray, self.obstacle_cb, queue_size=100) self.tf_buffer = tf2_ros.Buffer(cache_time=rospy.Duration(10.0)) self.tf_listener = tf2_ros.TransformListener(self.tf_buffer) context.add_widget(self._widget) def QColor2String(self, color): return ("({},{},{})".format(color.red(), color.green(), color.blue())) def Npcolor2String(self, color): return ("({},{},{})".format(color[0], color[1], color[2])) def reconfigure(self, config, level): # set visibilities accordingly self.ball_active = config["ball"] self.goal_active = config["goal"] # todo # config["obstacles"] # config["lines"] def resize_field(self): # fits the field into current window size size = self._widget.size() x_scale = size.width() / self.image_width y_scale = size.height() / self.image_height self.scale = min(x_scale, y_scale) self.radar.setScale(self.scale) self.view.centerOn(size.width() / 2, size.height() / 2) self.radar.offset() def set_scaled_position(self, item, x, y, height, width): item_scale = min(self.scale + 0.5, 1) item.setScale(item_scale) x *= self.meter_length_img # scaling from meters to pixels on original image x += self.image_width / 2 # transform from upper left corner (qt coord system) to center point (robocup coord sys) x -= width * item_scale / 2 x = max(min(x, self.image_width - 50), 0) # dont let it get outside of the window y *= self.meter_length_img y += self.image_height / 2 y -= height * item_scale / 2 y = max(min(y, self.image_height - 50), 0) item.setX(y) item.setY(x) def balls_cb(self, msg): ball_msgs = msg.poses for ball_msg in ball_msgs: ball_point = PointStamped() ball_point.header.frame_id = msg.header.frame_id ball_point.header.stamp = msg.header.stamp ball_point.point = ball_msg.pose.pose.position try: ball_point = self.tf_buffer.transform(ball_point, "base_footprint") except tf2_ros.LookupException: rospy.logwarn("Could not transform from " + msg.header.frame_id + " to 'base_footprint'") return None ball = QGraphicsEllipseItem(0, 0, self.ball_size, self.ball_size, self.radar) ball.setPen(self.ball_pen) ball.setVisible(False) ball.setOpacity(self.opacity) self.set_scaled_position(ball, -1 * ball_point.point.x, -1 * ball_point.point.y, self.ball_size, self.ball_size) color_tuple = self.confidence2color(ball_msg.confidence) ball.setBrush(QBrush(QColor(*color_tuple))) ball.setVisible(self.ball_active) def goal_cb(self, msg): self.draw_goal_part(self.left_post, msg, msg.left_post, self.post_size) self.draw_goal_part(self.right_post, msg, msg.right_post, self.post_size) self.draw_goal_part(self.center, msg, msg.center_direction, self.center_size) def draw_goal_part(self, obj, msg, point, size): goal_point = PointStamped() goal_point.header.frame_id = msg.header.frame_id goal_point.header.stamp = msg.header.stamp goal_point.point = point try: goal_point = self.tf_buffer.transform(goal_point, "base_footprint") except tf2_ros.LookupException: rospy.logwarn("Could not transform from " + msg.header.frame_id + " to 'base_footprint'") return None self.set_scaled_position(obj, -1 * goal_point.point.x, -1 * goal_point.point.y, size, size) color_tuple = self.confidence2color(msg.confidence) obj.setBrush(QBrush(QColor(*color_tuple))) obj.setVisible(self.goal_active) def confidence2color(self, confidence): diff = self.green - self.red ball_color = self.red + diff * confidence return tuple(ball_color) def obstacle_cb(self, msg): for item in self.obstacles: self._scene.removeItem(item) for obstacle_msg in msg.obstacles: obstacle = QGraphicsEllipseItem(0, 0, self.obsacle_size, self.obsacle_size, self.radar) obstacle.setPen(self.obstacle_pen) obstacle.setOpacity(self.opacity) obstacle_point = PointStamped() obstacle_point.header.frame_id = msg.header.frame_id obstacle_point.header.stamp = msg.header.stamp obstacle_point.point = obstacle_msg.pose.pose.pose.position try: obstacle_point = self.tf_buffer.transform( obstacle_point, "base_footprint") except tf2_ros.LookupException: rospy.logwarn("Could not transform from " + msg.header.frame_id + " to 'base_footprint'") return None self.set_scaled_position(obstacle, -1 * obstacle_point.point.x, -1 * obstacle_point.point.y, self.obsacle_size, self.obsacle_size) color_tuple = self.confidence2color(obstacle_msg.pose.confidence) obstacle.setBrush(QBrush(QColor(*color_tuple))) obstacle.setVisible(True) self.obstacles.append(obstacle)
def buildDiagram(self): """ Public method to build the modules shapes of the diagram. """ initlist = glob.glob(os.path.join(self.packagePath, '__init__.*')) if len(initlist) == 0: ct = QGraphicsTextItem(None) ct.setHtml( self.tr( "The directory <b>'{0}'</b> is not a Python package.") .format(self.package)) self.scene.addItem(ct) return shapes = {} p = 10 y = 10 maxHeight = 0 sceneRect = self.umlView.sceneRect() modules = self.__buildModulesDict() sortedkeys = sorted(modules.keys()) externalMods = [] packageList = self.shortPackage.split('.') packageListLen = len(packageList) for module in sortedkeys: impLst = [] for i in modules[module].imports: if i.startswith(self.package): n = i[len(self.package) + 1:] else: n = i if i in modules: impLst.append(n) elif self.showExternalImports: impLst.append(n) if n not in externalMods: externalMods.append(n) for i in list(modules[module].from_imports.keys()): if i.startswith('.'): dots = len(i) - len(i.lstrip('.')) if dots == 1: n = i[1:] i = n else: if self.showExternalImports: n = '.'.join( packageList[:packageListLen - dots + 1] + [i[dots:]]) else: n = i elif i.startswith(self.package): n = i[len(self.package) + 1:] else: n = i if i in modules: impLst.append(n) elif self.showExternalImports: impLst.append(n) if n not in externalMods: externalMods.append(n) classNames = [] for cls in list(modules[module].classes.keys()): className = modules[module].classes[cls].name if className not in classNames: classNames.append(className) shape = self.__addModule(module, classNames, 0.0, 0.0) shapeRect = shape.sceneBoundingRect() shapes[module] = (shape, impLst) pn = p + shapeRect.width() + 10 maxHeight = max(maxHeight, shapeRect.height()) if pn > sceneRect.width(): p = 10 y += maxHeight + 10 maxHeight = shapeRect.height() shape.setPos(p, y) p += shapeRect.width() + 10 else: shape.setPos(p, y) p = pn for module in externalMods: shape = self.__addModule(module, [], 0.0, 0.0) shapeRect = shape.sceneBoundingRect() shapes[module] = (shape, []) pn = p + shapeRect.width() + 10 maxHeight = max(maxHeight, shapeRect.height()) if pn > sceneRect.width(): p = 10 y += maxHeight + 10 maxHeight = shapeRect.height() shape.setPos(p, y) p += shapeRect.width() + 10 else: shape.setPos(p, y) p = pn rect = self.umlView._getDiagramRect(10) sceneRect = self.umlView.sceneRect() if rect.width() > sceneRect.width(): sceneRect.setWidth(rect.width()) if rect.height() > sceneRect.height(): sceneRect.setHeight(rect.height()) self.umlView.setSceneSize(sceneRect.width(), sceneRect.height()) self.__createAssociations(shapes) self.umlView.autoAdjustSceneSize(limit=True)
class GraphicLine(QGraphicsLineItem): """ This class is a graphic line with an arrow which connects two blocks in the scene. Attributes ---------- origin : QGraphicsRectItem Origin rect of the line. destination : QGraphicsRectItem Destination rect of the line. scene : QGraphicsScene Current drawing scene. brush : QBrush Brush to draw the arrow. pen : QPen Pen to draw the arrow. arrow_head : QGraphicsPolygonItem Final arrow of the line. arrow_size : int Size of the head of the arrow. dim_label : QGraphicsTextItem Text showing the dimensions of the edge. is_valid : bool Flag monitoring whether the connection is consistent. Methods ---------- gen_endpoints(QRectF, QRectF) Returns the shortest connection between the two rects. draw_arrow() Draws the polygon for the arrow. set_valid(bool) Assign validity for this line. update_dims(tuple) Update the line dimensions. update_pos(QRectF) Update the line position given the new rect position. remove_self() Delete this line. """ def __init__(self, origin: QGraphicsRectItem, destination: QGraphicsRectItem, scene): super(GraphicLine, self).__init__() self.origin = origin self.destination = destination self.scene = scene # This flag confirms a legal connection self.is_valid = True # Get the four sides of the rects destination_lines = u.get_sides_of( self.destination.sceneBoundingRect()) origin_lines = u.get_sides_of(self.origin.sceneBoundingRect()) # Get the shortest edge between the two blocks self.setLine(self.gen_endpoints(origin_lines, destination_lines)) self.brush = QBrush(QColor(style.GREY_0)) self.pen = QPen(QColor(style.GREY_0)) self.pen.setWidth(4) self.pen.setCapStyle(Qt.RoundCap) self.pen.setJoinStyle(Qt.RoundJoin) self.setPen(self.pen) # Dimensions labels self.dim_label = QGraphicsTextItem() self.dim_label.setZValue(6) self.scene.addItem(self.dim_label) # Arrow head self.arrow_head = QGraphicsPolygonItem() self.arrow_head.setPen(self.pen) self.arrow_head.setBrush(self.brush) self.arrow_size = 15.0 self.draw_arrow() @staticmethod def gen_endpoints(origin_sides: dict, destination_sides: dict) -> QLineF: """ This method finds the shortest path between two rectangles. Parameters ---------- origin_sides : dict The dictionary {side_label: side_size} of the starting rect. destination_sides : dict The dictionary {side_label: side_size} of the ending rect. Returns ---------- QLineF The shortest line. """ # Init the line with the maximum possible value shortest_line = QLineF(-sys.maxsize / 2, -sys.maxsize / 2, sys.maxsize / 2, sys.maxsize / 2) for o_side, origin_side in origin_sides.items(): o_mid_x, o_mid_y = u.get_midpoint(o_side, origin_side) for d_side, destination_side in destination_sides.items(): d_mid_x, d_mid_y = u.get_midpoint(d_side, destination_side) # Update line line = QLineF(o_mid_x, o_mid_y, d_mid_x, d_mid_y) if line.length() < shortest_line.length(): shortest_line = line return shortest_line def draw_arrow(self) -> None: """ This method draws an arrow at the end of the line. """ polygon_arrow_head = QPolygonF() # Compute the arrow angle angle = math.acos(self.line().dx() / self.line().length()) angle = ((math.pi * 2) - angle) # Compute the direction where the arrow points (1 up, -1 down) arrow_direction = 1 if math.asin(self.line().dy() / self.line().length()) < 0: arrow_direction = -1 # First point of the arrow tail arrow_p1 = self.line().p2() - arrow_direction * QPointF( arrow_direction * math.sin(angle + math.pi / 2.5) * self.arrow_size, math.cos(angle + math.pi / 2.5) * self.arrow_size) # Second point of the arrow tail arrow_p2 = self.line().p2() - arrow_direction * QPointF( arrow_direction * math.sin(angle + math.pi - math.pi / 2.5) * self.arrow_size, math.cos(angle + math.pi - math.pi / 2.5) * self.arrow_size) # Third point is the line end polygon_arrow_head.append(self.line().p2()) polygon_arrow_head.append(arrow_p2) polygon_arrow_head.append(arrow_p1) # Add the arrow to the scene self.arrow_head.setZValue(1) self.arrow_head.setParentItem(self) self.arrow_head.setPolygon(polygon_arrow_head) def set_valid(self, valid: bool) -> None: """ This method changes the arrow style: if the connection is not valid the arrow becomes red, otherwise it remains grey with dimensions displayed. Parameters ---------- valid : bool New value for the legality flag. """ if valid: self.is_valid = True self.pen.setColor(QColor(style.GREY_0)) self.brush.setColor(QColor(style.GREY_0)) self.dim_label.setVisible(False) else: self.is_valid = False self.pen.setColor(QColor(style.RED_2)) self.brush.setColor(QColor(style.RED_2)) if self.scene.is_dim_visible: self.dim_label.setVisible(True) def update_dims(self, dims: tuple) -> None: """ This method updates the input & output dimensions. Parameters ---------- dims : tuple The new dimensions to update. """ self.dim_label.setHtml("<div style = 'background-color: " + style.RED_2 + "; color: white; font-family: consolas;'>" + str(dims) + "</div>") self.dim_label.setPos(self.line().center()) def update_pos(self, new_target: QRectF): """ This method updates the line as it origin or its destination has changed location. Parameters ---------- new_target : QRectF """ if new_target == self.destination: self.destination = new_target elif new_target == self.origin: self.origin = new_target # Get the four sides of the rects destination_lines = u.get_sides_of( self.destination.sceneBoundingRect()) origin_lines = u.get_sides_of(self.origin.sceneBoundingRect()) # Get the shortest edge between the two blocks self.setLine(self.gen_endpoints(origin_lines, destination_lines)) self.draw_arrow() self.dim_label.setPos(self.line().center()) def remove_self(self) -> None: """ The line is removed from the scene along with origin and destination pointers. """ self.scene.removeItem(self) self.scene.edges.remove(self) self.scene.removeItem(self.dim_label) self.origin = None self.destination = None
def buildDiagram(self): """ Public method to build the class shapes of the package diagram. The algorithm is borrowed from Boa Constructor. """ self.allClasses = {} initlist = glob.glob(os.path.join(self.package, '__init__.*')) if len(initlist) == 0: ct = QGraphicsTextItem(None) self.scene.addItem(ct) ct.setHtml( self.tr("The directory <b>'{0}'</b> is not a package.").format( self.package)) return modules = self.__buildModulesDict() if not modules: ct = QGraphicsTextItem(None) self.scene.addItem(ct) ct.setHtml( self.tr( "The package <b>'{0}'</b> does not contain any modules."). format(self.package)) return # step 1: build all classes found in the modules classesFound = False for modName in list(modules.keys()): module = modules[modName] for cls in list(module.classes.keys()): classesFound = True self.__addLocalClass(cls, module.classes[cls], 0, 0) if not classesFound: ct = QGraphicsTextItem(None) self.scene.addItem(ct) ct.setHtml( self.tr( "The package <b>'{0}'</b> does not contain any classes."). format(self.package)) return # step 2: build the class hierarchies routes = [] nodes = [] for modName in list(modules.keys()): module = modules[modName] todo = [module.createHierarchy()] while todo: hierarchy = todo[0] for className in list(hierarchy.keys()): cw = self.__getCurrentShape(className) if not cw and className.find('.') >= 0: cw = self.__getCurrentShape(className.split('.')[-1]) if cw: self.allClasses[className] = cw if cw and cw.noAttrs != self.noAttrs: cw = None if cw and not (cw.external and (className in module.classes or className in module.modules)): if className not in nodes: nodes.append(className) else: if className in module.classes: # this is a local class (defined in this module) self.__addLocalClass(className, module.classes[className], 0, 0) elif className in module.modules: # this is a local module (defined in this module) self.__addLocalClass(className, module.modules[className], 0, 0, True) else: self.__addExternalClass(className, 0, 0) nodes.append(className) if hierarchy.get(className): todo.append(hierarchy.get(className)) children = list(hierarchy.get(className).keys()) for child in children: if (className, child) not in routes: routes.append((className, child)) del todo[0] # step 3: build the subpackages subpackages = self.__buildSubpackagesDict() for subpackage in sorted(subpackages.keys()): self.__addPackage(subpackage, subpackages[subpackage], 0, 0) nodes.append(subpackage) self.__arrangeClasses(nodes, routes[:]) self.__createAssociations(routes) self.umlView.autoAdjustSceneSize(limit=True)
class Main_Player(Entity): contador = 1 def __init__(self, dir_assets, *args): super().__init__(*args) self.name = "Jugador {0}".format(Main_Player.contador) self.sprite_generator = sprite_generator(dir_assets, 7, 8) next(self.sprite_generator) self.experience = 0 self.progress_bar = Progress_Bar(1000) self.set_health_var() self.set_pixmap_image() self.set_attack_timer() self.set_animation_timer() self.attack_velocity = 1000 self.move = True self.atacar = True self.level_impar = False self.set_movement_timer() self.setTransformOriginPoint(50 * self.ponderador, 50 * self.ponderador) self.score = 0 self.set_score_timer() self.score_label = QGraphicsTextItem() self.score_label.setDefaultTextColor(QColor("green")) Main_Player.contador += 1 def set_score_timer(self): self.score_timer = QTimer() self.score_timer.timeout.connect(self.add_score) self.score_timer.start(1000) def add_score(self): self.score += 50 self.score_label.setHtml( '<div style="background:white;">{0} Score: '.format(self.name) + str(self.score) + '</p>') def set_experience(self, experience): self.experience += experience print(self.experience) level_up = self.progress_bar.set_actual_experience(experience) if level_up and not self.level_impar: self.tamaño += 1 self.level_impar = True for i in range(0, 100): self.ponderador += 0.001 print(self.ponderador) def set_attack_timer(self): self.attack_timer = QTimer() self.attack_timer.timeout.connect(self.reset_attack) def reset_attack(self): self.atacar = True self.attack_timer.stop() def set_movement_timer(self): self.movement_timer = QTimer() self.movement_timer.timeout.connect(self.movement) self.movement_timer.start(50) def movement(self): self.orientation += self.angular_velocity self.setRotation(self.orientation) self.health_var.setRotation(-self.orientation) self.collide_with_items() if self.move: self.change_in_x, self.change_in_y = pol2rect( self.velocity, self.orientation) if self.x() + self.change_in_x < 0 or self.x( ) + self.change_in_x + 64 * self.ponderador > 900: if self.y() + self.change_in_y < 0 or self.y( ) + self.change_in_y + 64 * self.ponderador > 600: self.wall.play() else: self.setPos(self.x(), self.y() + self.change_in_y) self.wall.play() elif self.y() + self.change_in_y < 0 or self.y( ) + self.change_in_y + 64 * self.ponderador > 600: if self.x() + self.change_in_x < 0 or self.x( ) + self.change_in_x + 64 * self.ponderador > 900: self.wall.play() else: self.setPos(self.x() + self.change_in_x, self.y()) self.wall.play() else: self.setPos(self.x() + self.change_in_x, self.y() + self.change_in_y) def resize_health_bar(self): self.health_var.setScale(self.tamaño * self.ponderador) def set_pixmap_image(self): # descriptivo self.pixmap_image = QPixmap(next(self.sprite_generator)).scaled( self.ponderador * 128, self.ponderador * 128) self.setTransformOriginPoint(50 * self.ponderador, 50 * self.ponderador) self.setPixmap(self.pixmap_image) self.health_var.update(self.health) self.progress_bar.fill() self.resize_health_bar() def set_animation_timer( self ): # timer para que se actualize el sprite periodicamente, ya que es un dragon y los dragones vuelan :D self.animation_timer = QTimer() self.animation_timer.timeout.connect(self.set_pixmap_image) self.animation_timer.start(85) def set_health_var(self): self.health_var = Health_Bar(self.max_health, 200 * self.ponderador) self.health_var.setParentItem(self) self.health_var.setX(-60 * self.ponderador) self.health_var.setTransformationMode(Qt.SmoothTransformation) self.health_var.setTransformOriginPoint(118.76 * self.ponderador, 58.76 * self.ponderador) def enemy_attack(self, enemy): self.damage = round(self.tamaño * 1 / 10 * self.max_health, 0) enemy.health -= self.damage enemy.health_var.update(enemy.health) self.atacar = False self.attack_timer.start(self.attack_velocity) if enemy.health < 0: if self.health > 0: self.set_experience(100 * max(enemy.tamaño - self.tamaño + 3, 1)) self.score += 1000 * abs((enemy.tamaño - self.tamaño)) self.aux_signal_object.signal_sender(enemy, "Enemy") def collide_with_items(self): self.object_list = self.collidingItems() for object in self.object_list: if isinstance( object, Enemy) or isinstance(object, Main_Player) and self.move: self.change_in_x, self.change_in_y = pol2rect( 6, self.orientation) if self.velocity > 0: self.setPos(self.x() - self.change_in_x, self.y() - self.change_in_y) if isinstance(object, Enemy) and self.atacar: self.enemy_attack(object) else: self.setPos(self.x() + self.change_in_x, self.y() + self.change_in_y)
def buildDiagram(self): """ Public method to build the class shapes of the package diagram. The algorithm is borrowed from Boa Constructor. """ self.allClasses = {} initlist = glob.glob(os.path.join(self.package, '__init__.*')) if len(initlist) == 0: ct = QGraphicsTextItem(None) self.scene.addItem(ct) ct.setHtml( self.tr("The directory <b>'{0}'</b> is not a package.") .format(self.package)) return modules = self.__buildModulesDict() if not modules: ct = QGraphicsTextItem(None) self.scene.addItem(ct) ct.setHtml( self.tr( "The package <b>'{0}'</b> does not contain any modules.") .format(self.package)) return # step 1: build all classes found in the modules classesFound = False for modName in list(modules.keys()): module = modules[modName] for cls in list(module.classes.keys()): classesFound = True self.__addLocalClass(cls, module.classes[cls], 0, 0) if not classesFound: ct = QGraphicsTextItem(None) self.scene.addItem(ct) ct.setHtml( self.tr( "The package <b>'{0}'</b> does not contain any classes.") .format(self.package)) return # step 2: build the class hierarchies routes = [] nodes = [] for modName in list(modules.keys()): module = modules[modName] todo = [module.createHierarchy()] while todo: hierarchy = todo[0] for className in list(hierarchy.keys()): cw = self.__getCurrentShape(className) if not cw and className.find('.') >= 0: cw = self.__getCurrentShape(className.split('.')[-1]) if cw: self.allClasses[className] = cw if cw and cw.noAttrs != self.noAttrs: cw = None if cw and not (cw.external and (className in module.classes or className in module.modules) ): if className not in nodes: nodes.append(className) else: if className in module.classes: # this is a local class (defined in this module) self.__addLocalClass( className, module.classes[className], 0, 0) elif className in module.modules: # this is a local module (defined in this module) self.__addLocalClass( className, module.modules[className], 0, 0, True) else: self.__addExternalClass(className, 0, 0) nodes.append(className) if hierarchy.get(className): todo.append(hierarchy.get(className)) children = list(hierarchy.get(className).keys()) for child in children: if (className, child) not in routes: routes.append((className, child)) del todo[0] # step 3: build the subpackages subpackages = self.__buildSubpackagesDict() for subpackage in sorted(subpackages.keys()): self.__addPackage(subpackage, subpackages[subpackage], 0, 0) nodes.append(subpackage) self.__arrangeClasses(nodes, routes[:]) self.__createAssociations(routes) self.umlView.autoAdjustSceneSize(limit=True)
def buildDiagram(self): """ Public method to build the modules shapes of the diagram. """ initlist = glob.glob(os.path.join(self.packagePath, '__init__.*')) if len(initlist) == 0: ct = QGraphicsTextItem(None) ct.setHtml( self.tr("The directory <b>'{0}'</b> is not a Python package."). format(self.package)) self.scene.addItem(ct) return shapes = {} p = 10 y = 10 maxHeight = 0 sceneRect = self.umlView.sceneRect() modules = self.__buildModulesDict() sortedkeys = sorted(modules.keys()) externalMods = [] packageList = self.shortPackage.split('.') packageListLen = len(packageList) for module in sortedkeys: impLst = [] for i in modules[module].imports: if i.startswith(self.package): n = i[len(self.package) + 1:] else: n = i if i in modules: impLst.append(n) elif self.showExternalImports: impLst.append(n) if n not in externalMods: externalMods.append(n) for i in list(modules[module].from_imports.keys()): if i.startswith('.'): dots = len(i) - len(i.lstrip('.')) if dots == 1: n = i[1:] i = n else: if self.showExternalImports: n = '.'.join(packageList[:packageListLen - dots + 1] + [i[dots:]]) else: n = i elif i.startswith(self.package): n = i[len(self.package) + 1:] else: n = i if i in modules: impLst.append(n) elif self.showExternalImports: impLst.append(n) if n not in externalMods: externalMods.append(n) classNames = [] for cls in list(modules[module].classes.keys()): className = modules[module].classes[cls].name if className not in classNames: classNames.append(className) shape = self.__addModule(module, classNames, 0.0, 0.0) shapeRect = shape.sceneBoundingRect() shapes[module] = (shape, impLst) pn = p + shapeRect.width() + 10 maxHeight = max(maxHeight, shapeRect.height()) if pn > sceneRect.width(): p = 10 y += maxHeight + 10 maxHeight = shapeRect.height() shape.setPos(p, y) p += shapeRect.width() + 10 else: shape.setPos(p, y) p = pn for module in externalMods: shape = self.__addModule(module, [], 0.0, 0.0) shapeRect = shape.sceneBoundingRect() shapes[module] = (shape, []) pn = p + shapeRect.width() + 10 maxHeight = max(maxHeight, shapeRect.height()) if pn > sceneRect.width(): p = 10 y += maxHeight + 10 maxHeight = shapeRect.height() shape.setPos(p, y) p += shapeRect.width() + 10 else: shape.setPos(p, y) p = pn rect = self.umlView._getDiagramRect(10) sceneRect = self.umlView.sceneRect() if rect.width() > sceneRect.width(): sceneRect.setWidth(rect.width()) if rect.height() > sceneRect.height(): sceneRect.setHeight(rect.height()) self.umlView.setSceneSize(sceneRect.width(), sceneRect.height()) self.__createAssociations(shapes) self.umlView.autoAdjustSceneSize(limit=True)
import sys app = QApplication(sys.argv) stickMan = StickMan() stickMan.setDrawSticks(False) textItem = QGraphicsTextItem() textItem.setHtml( '<font color="white"><b>Stickman</b>' "<p>" "Tell the stickman what to do!" "</p>" "<p><i>" '<li>Press <font color="purple">J</font> to make the stickman jump.</li>' '<li>Press <font color="purple">D</font> to make the stickman dance.</li>' '<li>Press <font color="purple">C</font> to make him chill out.</li>' '<li>When you are done, press <font color="purple">Escape</font>.</li>' "</i></p>" "<p>If he is unlucky, the stickman will get struck by lightning, and never jump, dance or chill out again." "</p></font>" ) w = textItem.boundingRect().width() stickManBoundingRect = stickMan.mapToScene(stickMan.boundingRect()).boundingRect() textItem.setPos(-w / 2.0, stickManBoundingRect.bottom() + 25.0) scene = QGraphicsScene() scene.addItem(stickMan) scene.addItem(textItem) scene.setBackgroundBrush(Qt.black)
class painter(QGraphicsView): pixelSize = int(15 / narrowRatio) width = int(480 / narrowRatio) height = int(360 / narrowRatio) fontSize = int(30 / narrowRatio) anchorLineSize = int(100 / narrowRatio) ellipseRadius = int(8 / narrowRatio) textInterval = int(90 / narrowRatio) col = width / pixelSize line = height / pixelSize centerIndex = int(round(((line / 2 - 1) * col) + col / 2)) frameCount = 0 baseZValue = 0 mode = 1 body = 1 open_status = 0 textLineHeight = fontSize + 10 blurRaduis = 50 # Smoother improvement def __init__(self, dataThread): super(painter, self).__init__() self.dataThread = dataThread self.setFixedSize(self.width, self.height + self.textLineHeight) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scene = QGraphicsScene() self.setScene(self.scene) # center het text item self.centerTextItem = QGraphicsTextItem() self.centerTextItem.setPos(self.width / 2 - self.fontSize, 0) self.centerTextItem.setZValue(self.baseZValue + 1) self.scene.addItem(self.centerTextItem) # center anchor item centerX = self.width / 2 centerY = self.height / 2 self.ellipseItem = QGraphicsEllipseItem(0, 0, self.ellipseRadius * 2, self.ellipseRadius * 2) self.horLineItem = QGraphicsLineItem(0, 0, self.anchorLineSize, 0) self.verLineItem = QGraphicsLineItem(0, 0, 0, self.anchorLineSize) self.ellipseItem.setPos(centerX - self.ellipseRadius, centerY - self.ellipseRadius) self.horLineItem.setPos(centerX - self.anchorLineSize / 2, centerY) self.verLineItem.setPos(centerX, centerY - self.anchorLineSize / 2) self.ellipseItem.setPen(QColor(Qt.white)) self.horLineItem.setPen(QColor(Qt.white)) self.verLineItem.setPen(QColor(Qt.white)) self.ellipseItem.setZValue(self.baseZValue + 1) self.horLineItem.setZValue(self.baseZValue + 1) self.verLineItem.setZValue(self.baseZValue + 1) self.scene.addItem(self.ellipseItem) self.scene.addItem(self.horLineItem) self.scene.addItem(self.verLineItem) # camera item self.cameraBuffer = QPixmap(self.width, self.height + self.textLineHeight) self.cameraItem = QGraphicsPixmapItem() if useBlur: self.gusBlurEffect = QGraphicsBlurEffect() self.gusBlurEffect.setBlurRadius(self.blurRaduis) self.cameraItem.setGraphicsEffect(self.gusBlurEffect) self.cameraItem.setPos(0, 0) self.cameraItem.setZValue(self.baseZValue) self.scene.addItem(self.cameraItem) # het text item self.hetTextBuffer = QPixmap(self.width, self.textLineHeight) self.hetTextItem = QGraphicsPixmapItem() self.hetTextItem.setPos(0, self.height) self.hetTextItem.setZValue(self.baseZValue) self.scene.addItem(self.hetTextItem) # button item self.ctrlOpenButton = QPushButton('Open', self) self.ctrlOpenButton.clicked.connect(self.ctrl_open) self.ctrlOpenButton.setGeometry(10, 30, 100, 40) ''' self.ctrlCloseButton = QPushButton('stop send',self) self.ctrlCloseButton.clicked.connect(self.ctrl_close) self.ctrlCloseButton.setGeometry(10,80,100,40) ''' self.getOnePicButton = QPushButton('send a frame', self) self.getOnePicButton.clicked.connect(self.ctrl_sendone) self.getOnePicButton.setGeometry(10, 130, 100, 40) self.getOnePicButton.setEnabled(False) self.modeManualButton = QPushButton('Auto', self) self.modeManualButton.clicked.connect(self.mode_manual) self.modeManualButton.setGeometry(10, 180, 100, 40) self.modeObjButton = QPushButton('Body', self) self.modeObjButton.clicked.connect(self.obj_body) self.modeObjButton.setGeometry(10, 230, 100, 40) ''' self.modeAutoButton = QPushButton('mode: auto',self) self.modeAutoButton.clicked.connect(self.mode_auto) self.modeAutoButton.setGeometry(10,230,100,40) ''' self.modeFpsButton = QPushButton('3fps', self) self.modeFpsButton.clicked.connect(self.rate_0) self.modeFpsButton.setGeometry(10, 280, 100, 40) self.blackbodyEdit = QLineEdit() self.blackbodyEdit.setGeometry(270, 200, 100, 40) self.blackbodyEdit.setText('37') self.calibrateButton = QPushButton(calibrateStr[0], self) self.calibrateButton.clicked.connect(self.calibrate_handle) self.calibrateButton.setGeometry(370, 280, 100, 40) ''' self.modeAutoButton = QPushButton('1fps',self) self.modeAutoButton.clicked.connect(self.rate_1) self.modeAutoButton.setGeometry(35,280,50,40) self.modeAutoButton = QPushButton('2fps',self) self.modeAutoButton.clicked.connect(self.rate_2) self.modeAutoButton.setGeometry(60,280,50,40) self.modeAutoButton = QPushButton('3fps',self) self.modeAutoButton.clicked.connect(self.rate_3) self.modeAutoButton.setGeometry(85,280,50,40) ''' ''' self.modeAutoButton = QPushButton('obj: common',self) self.modeAutoButton.clicked.connect(self.obj_common) self.modeAutoButton.setGeometry(370,80,100,40) ''' # self.modeAutoButton = QPushButton('version',self) # self.modeAutoButton.clicked.connect(self.sys_ver) # self.modeAutoButton.setGeometry(370,230,100,40) def ctrl_open(self): if self.open_status == 1: print('start send C command 0') self.open_status = 0 self.ctrlOpenButton.setText("Open") self.dataThread.send_data('CMDC\0') else: print('start send C command 1') self.open_status = 1 self.ctrlOpenButton.setText("Close") self.dataThread.send_data('CMDC\1') ''' def ctrl_close(self): print('stop send') self.dataThread.send_data('CMDC\0') ''' def ctrl_sendone(self): print('send a frame') self.dataThread.send_data('CMDC\2') def mode_manual(self): if self.mode == 1: self.getOnePicButton.setEnabled(True) self.modeManualButton.setText("Manual") self.dataThread.send_data('CMDM\0') self.mode = 0 print('mode: manual') else: self.getOnePicButton.setEnabled(False) self.modeManualButton.setText("Auto") self.dataThread.send_data('CMDM\1') print('mode: auto') self.mode = 1 def mode_auto(self): print('mode: auto') self.dataThread.send_data('CMDM\1') def stop_calibration(self): global calibration_offset calibration_start = False self.calibrateButton.setText(calibrateStr[0]) if (calibration_frame_count): reply = QMessageBox.information(self, '信息', '校准很久都不行,模组是否没有预热20分钟呢?', QMessageBox.Yes) else: reply = QMessageBox.information(self, '信息', '校准已完成', QMessageBox.Yes) def calibrate_handle(self): global calibration_start global calibration_max_list global blackbody_temperature if calibration_start: calibration_start = False self.calibrateButton.setText(calibrateStr[0]) else: calibration_max_list.clear() blackbody_temperature = float(self.blackbodyEdit.text()) calibration_start = True print(" blackbody_temperature ", blackbody_temperature) self.calibrateButton.setText(calibrateStr[1]) def rate_0(self): global btn_index btn_index = (btn_index + 1) % 4 print('FPS:', strButton[btn_index]) self.modeFpsButton.setText(strButton[btn_index]) self.dataThread.send_data(strFpsCmd[btn_index]) #'CMDF\0') ''' def rate_1(self): print('FPS:1') self.dataThread.send_data('CMDF\1') def rate_2(self): print('FPS:2') self.dataThread.send_data('CMDF\2') def rate_3(self): print('FPS:3') self.dataThread.send_data('CMDF\3') ''' def obj_body(self): if self.body == 1: self.body = 0 print('obj: Object') self.modeObjButton.setText("Object") self.dataThread.send_data('CMDO\0') else: self.body = 1 print('obj: Human Body') self.modeObjButton.setText("Body") self.dataThread.send_data('CMDO\1') ''' def obj_common(self): print('obj: common') self.dataThread.send_data('CMDO\1') def sys_slp(self): print('sleep') self.dataThread.send_data('CMDS\1') ''' def draw(self): if len(hetaData) == 0: return font = QFont() color = QColor() font.setPointSize(self.fontSize) font.setFamily("Microsoft YaHei") font.setLetterSpacing(QFont.AbsoluteSpacing, 0) index = 0 lock.acquire() frame = hetaData.pop(0) lock.release() p = QPainter(self.cameraBuffer) p.fillRect(0, 0, self.width, self.height + self.textLineHeight, QBrush(QColor(Qt.black))) # draw camera color = QColor() for yIndex in range(int(self.height / self.pixelSize)): for xIndex in range(int(self.width / self.pixelSize)): color.setHsvF(frame[index] / 360, 1.0, 1.0) p.fillRect(xIndex * self.pixelSize, yIndex * self.pixelSize, self.pixelSize, self.pixelSize, QBrush(color)) index = index + 1 self.cameraItem.setPixmap(self.cameraBuffer) # draw text p = QPainter(self.hetTextBuffer) p.fillRect(0, 0, self.width, self.height + self.textLineHeight, QBrush(QColor(Qt.black))) hetDiff = maxHet - minHet bastNum = round(minHet) interval = round(hetDiff / 5) for i in range(5): hue = constrain( mapValue((bastNum + (i * interval)), minHet, maxHet, minHue, maxHue), minHue, maxHue) color.setHsvF(hue / 360, 1.0, 1.0) p.setPen(color) p.setFont(font) p.drawText(i * self.textInterval, self.fontSize + 3, str(bastNum + (i * interval)) + "°") self.hetTextItem.setPixmap(self.hetTextBuffer) # draw center het text cneter = round( mapValue(frame[self.centerIndex], minHue, maxHue, minHet, maxHet), 1) centerText = "<font color=white>%s</font>" self.centerTextItem.setFont(font) self.centerTextItem.setHtml(centerText % (str(cneter) + "°")) self.frameCount = self.frameCount + 1 print("picture->" + str(self.frameCount))
def initdetailgroup(self): view = QGraphicsView(parent=self) brush = QBrush(QColor(242, 242, 242)) view.setBackgroundBrush(brush) view.setFrameStyle(16) # QFrame.Plain def clickEventHandler(event): self.detailFigure_2Clicked.emit() detailFigure_1 = QGraphicsPixmapItem( QPixmap(cwd + '/guiunits/imags/pon56gdemo/detailfigure_1.png')) detailFigure_2_Qobj = fadingPic( QPixmap(cwd + '/guiunits/imags/pon56gdemo/detailfigure_2.png')) detailFigure_2 = detailFigure_2_Qobj.pixmap_item detailFigure_2_title = detailFigure_2_Qobj.text_item detailFigure_1.mousePressEvent = clickEventHandler title = QGraphicsTextItem("Our Innovation/Contribution") font = QFont("Nokia Pure Text Light", 25, QFont.Bold) title.setFont(font) title.setDefaultTextColor(self.nokia_blue) textItem1 = QGraphicsTextItem() textItem1.setHtml( '''<body style="font-family:Nokia Pure Text Light;color:#124191;font-size:23px;"> <div >10GHz</div> <div > Optics </div> </body>''') textItem1.setTextWidth(80) textItem2 = QGraphicsTextItem() textItem2.setHtml( '''<body style="font-family:Nokia Pure Text Light;color:#124191;font-size:23px;"> <div > 10GHz</div> <div > Optics </div> </body>''') textItem2.setTextWidth(100) fan = Fan() # a QObject which wraps a QGraphicsItem inside scene = QGraphicsScene() scene.setSceneRect(0, 0, 1285, 420) scene.addItem(detailFigure_2) scene.addItem(detailFigure_1) scene.addItem(detailFigure_2_title) scene.addItem(textItem1) scene.addItem(textItem2) scene.addItem(title) scene.addItem(fan.pixmap_item) detailFigure_1.setPos(QPointF(35, 88)) detailFigure_2.setPos(QPointF(570, 96)) detailFigure_2.setOpacity(0) # hided at first detailFigure_2_title.setPos(QPointF(750, 46)) detailFigure_2_title.setOpacity(0) title.setPos(QPointF(50, 20)) textItem1.setPos(QPointF(40, 168)) textItem2.setPos(QPointF(361, 168)) fan.pixmap_item.setPos(QPointF(456.5, 138)) self.fanAnim = fan.fanAnimation() view.setScene(scene) view.setSceneRect(0, 0, 1285, 420) view.setAlignment(Qt.AlignLeft | Qt.AlignTop) view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) view.setRenderHint(QPainter.Antialiasing) self.detailGrpTextItem1 = textItem1 self.detailGrpTextItem2 = textItem2 self.detailFigTitle = title self.detailFigure_2_title = detailFigure_2_title self.turbofan = fan self.NNfigure_fadeIn = detailFigure_2_Qobj.fadeIn() self.NNfigure_fadeOut = detailFigure_2_Qobj.fadeOut() self._detailFigure_2_state = 0 # 0-hided, 1-showed return view
class BaseItem(QAbstractGraphicsShapeItem): """ Base class for visualization items. """ cycleValuesOnKeypress = {} hotkeys = {} defaultAutoTextKeys = [] def __init__(self, model_item=None, prefix="", parent=None): """ Creates a visualization item. """ QAbstractGraphicsShapeItem.__init__(self, parent) self.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemSendsGeometryChanges | QGraphicsItem.ItemSendsScenePositionChanges) self._model_item = model_item if self._model_item is not None: self._model_item.model().dataChanged.connect(self.onDataChanged) # initialize members self._prefix = prefix self._auto_text_keys = self.defaultAutoTextKeys[:] self._text = "" self._text_bg_brush = None self._text_item = QGraphicsTextItem(self) self._text_item.setPos(0, 0) self._text_item.setAcceptHoverEvents(False) self._text_item.setFlags(QGraphicsItem.ItemIgnoresTransformations) self._text_item.setHtml(self._compile_text()) self._valid = True if len(self.cycleValuesOnKeypress) > 0: logging.warning( "cycleValueOnKeypress is deprecated and will be removed in the future. " + "Set BaseItem.hotkeys instead with cycleValue()") self.changeColor() def changeColor(self): if self._model_item is not None: c = self._model_item.getColor() if c is not None: self.setColor(c) return self.setColor(Qt.yellow) def onDataChanged(self, indexFrom, indexTo): # FIXME why is this not updated, when changed graphically via attribute box ? #print "onDataChanged", self._model_item.index(), indexFrom, indexTo, indexFrom.parent() if indexFrom == self._model_item.index(): self.changeColor() #print "hit" # self._text_item.setHtml(self._compile_text()) def modelItem(self): """ Returns the model item of this items. """ return self._model_item def index(self): """ Returns the index of this item. """ return self._model_item.index() def prefix(self): """ Returns the key prefix of the item. """ return self._prefix def setPen(self, pen): pen = QPen(pen) # convert to pen if argument is a QColor QAbstractGraphicsShapeItem.setPen(self, pen) self._text_item.setDefaultTextColor(pen.color()) def setText(self, text=""): """ Sets a text to be displayed on this item. """ self._text = text self._text_item.setHtml(self._compile_text()) def text(self): return self._text def setTextBackgroundBrush(self, brush=None): """ Sets the brush to be used to fill the background region behind the text. Set to None to not draw a background (leave transparent). """ self._text_bg_brush = brush def textBackgroundBrush(self): """ Returns the background brush for the text region. """ return self._text_bg_brush def setAutoTextKeys(self, keys=None): """ Sets the keys for which the values from the annotations are displayed automatically as text. """ self._auto_text_keys = keys or [] self._text_item.setHtml(self._compile_text()) def autoTextKeys(self): """ Returns the list of keys for which the values from the annotations are displayed as text automatically. """ return self._auto_text_keys def isValid(self): """ Return whether this graphics item is valid, i.e. has a matching, valid model item connected to it. An item is by default valid, will only be set invalid on failure. """ return self._valid def setValid(self, val): self._valid = val def _compile_text(self): text_lines = [] if self._text != "" and self._text is not None: text_lines.append(self._text) for key in self._auto_text_keys: text_lines.append("%s: %s" % \ (key, self._model_item.get(key, ""))) return '<br/>'.join(text_lines) def dataChanged(self): self.dataChange() self._text_item.setHtml(self._compile_text()) self.update() def dataChange(self): pass def updateModel(self, ann=None): if ann is not None: self._model_item.update(ann) def boundingRect(self): return QRectF(0, 0, 0, 0) def setColor(self, color): self.setPen(color) self.setBrush(color) self.update() def paint(self, painter, option, widget=None): pass def itemChange(self, change, value): if change == QGraphicsItem.ItemPositionHasChanged: self.updateModel() return QAbstractGraphicsShapeItem.itemChange(self, change, value) def keyPressEvent(self, event): """ This handles the value cycling as defined in cycleValuesOnKeypress. """ if str(event.text()) in self.cycleValuesOnKeypress: itemkey, valuelist = self.cycleValuesOnKeypress[str(event.text())] if isinstance(itemkey, IgnorePrefix): itemkey = itemkey.value else: itemkey = self.prefix() + itemkey if len(valuelist) > 0: oldvalue = self._model_item.get(itemkey, None) if oldvalue is None: nextindex = 0 else: try: nextindex = valuelist.index(oldvalue) + 1 nextindex %= len(valuelist) except ValueError: nextindex = 0 newvalue = valuelist[nextindex] if newvalue is None: if oldvalue is not None: self._model_item.delete(itemkey) else: self._model_item[itemkey] = valuelist[nextindex] self.dataChanged() event.accept() elif str(event.text()) in self.hotkeys: self.hotkeys[str(event.text())](self) event.accept()
def buildDiagram(self): """ Public method to build the class shapes of the class diagram. The algorithm is borrowed from Boa Constructor. """ import Utilities.ModuleParser self.allClasses = {} self.allModules = {} try: extensions = (Preferences.getPython("PythonExtensions") + Preferences.getPython("Python3Extensions") + ['.rb']) module = Utilities.ModuleParser.readModule(self.file, extensions=extensions, caching=False) except ImportError: ct = QGraphicsTextItem(None) ct.setHtml( self.tr("The module <b>'{0}'</b> could not be found.").format( self.file)) self.scene.addItem(ct) return if self.file not in self.allModules: self.allModules[self.file] = [] routes = [] nodes = [] todo = [module.createHierarchy()] classesFound = False while todo: hierarchy = todo[0] for className in hierarchy: classesFound = True cw = self.__getCurrentShape(className) if not cw and className.find('.') >= 0: cw = self.__getCurrentShape(className.split('.')[-1]) if cw: self.allClasses[className] = cw if className not in self.allModules[self.file]: self.allModules[self.file].append(className) if cw and cw.noAttrs != self.noAttrs: cw = None if cw and not (cw.external and (className in module.classes or className in module.modules)): if cw.scene() != self.scene: self.scene.addItem(cw) cw.setPos(10, 10) if className not in nodes: nodes.append(className) else: if className in module.classes: # this is a local class (defined in this module) self.__addLocalClass(className, module.classes[className], 0, 0) elif className in module.modules: # this is a local module (defined in this module) self.__addLocalClass(className, module.modules[className], 0, 0, True) else: self.__addExternalClass(className, 0, 0) nodes.append(className) if hierarchy.get(className): todo.append(hierarchy.get(className)) children = list(hierarchy.get(className).keys()) for child in children: if (className, child) not in routes: routes.append((className, child)) del todo[0] if classesFound: self.__arrangeClasses(nodes, routes[:]) self.__createAssociations(routes) self.umlView.autoAdjustSceneSize(limit=True) else: ct = QGraphicsTextItem(None) ct.setHtml( self.tr("The module <b>'{0}'</b> does not contain any classes." ).format(self.file)) self.scene.addItem(ct)
class CallOut(): ''' This represents a callouton the diagram This class creates a text item and then surrounds it with a polygon that is a rectangle with a pointer to another object on the diagram. This can be used by hover over functions or be displayed as a part of a node or relationship ''' def __init__(self, scene, text, anchorPoint, diagramType, format): self.scene = scene self.model = self.scene.parent.model self.text = text self.anchorPoint = anchorPoint self.diagramType = diagramType self.format = format # initialize the two qgraphicsitems needed to draw a relationship to None self.itemText = None self.itemPolygon = None self.drawIt def name(self, ): return "no name" def NZID(self, ): return None def clearItem(self, ): if (not self.itemText is None and not self.itemText.scene() is None): self.itemText.scene().removeItem(self.itemText) if (not self.itemPolygon is None and not self.itemPolygon.scene() is None): self.itemPolygon.scene().removeItem(self.itemPolygon) def drawIt(self, ): ''' draw the callout ''' # if the polygon and text graphics items already exist on the scene then delete them self.clearItem() # draw the relationship arc pen = self.format.pen() brush = self.format.brush() # create text box # draw the text self.itemText = QGraphicsTextItem(self.relationInstance.relName, parent=None) self.itemText.setZValue(CALLOUTLAYER) self.itemText.setFlag(QGraphicsItem.ItemIsMovable, True) self.itemText.setFlag(QGraphicsItem.ItemIsSelectable, True) self.itemText.setSelected(False) self.itemText.setData(NODEID, self.relationInstance.NZID) self.itemText.setData(ITEMTYPE, CALLOUT) self.itemText.setHtml(self.genTextHTML()) # set the position of the text self.itemText.setPos(self.anchorPoint) # get the height and width of the text graphics item th = self.IRtext.boundingRect().height() tw = self.IRtext.boundingRect().width() #create an empty polygon arrowPolygon = QPolygonF() # add callout points arrowPolygon.append(self.anchorPoint) arrowPolygon.append( QPointF(self.anchorPoint.x() + tw, self.anchorPoint.y())) arrowPolygon.append( QPointF(self.anchorPoint.x() + tw, self.anchorPoint.y())) arrowPolygon.append( QPointF(self.anchorPoint.x() + tw, self.anchorPoint.y() + th)) arrowPolygon.append( QPointF(self.anchorPoint.x(), self.anchorPoint.y() + th)) self.itemPolygon = QGraphicsPolygonItem( arrowPolygon, parent=None, ) self.itemPolygon.setZValue(CALLOUTLAYER) self.itemPolygon.setBrush(brush) self.itemPolygon.setPen(pen) self.itemPolygon.setFlag(QGraphicsItem.ItemIsMovable, True) self.itemPolygon.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.itemPolygon.setFlag(QGraphicsItem.ItemIsSelectable, False) self.itemPolygon.setSelected(False) # set data in the RelLine object self.IRel.setData(NODEID, self.relationInstance.NZID) self.IRel.setData(ITEMTYPE, RELINSTANCEARC) # add the polygon object to the scene self.scene.addItem(self.itemPolygon) # add text to the scene self.scene.addItem(self.itemText) def updateText(self, ): # # force the node instance to update its values in case it has been updated from another diagram or the tree view # self.relationInstance.reloadDictValues() # self.IRtext.setPlainText(self.relationInstance.relName) self.itemText.setHtml(self.genTextHTML()) def genTextHTML(self): '''generate html to display the text ''' prefix = '<html><body>' suffix = "</body></html>" myHTML = ('{}<p><font size="1"> [{}]</font></p>{}'.format( prefix, self.text, suffix)) return myHTML def moveIt(self, ): self.drawIt()
class NodeTemplateItem(): ''' This represents one node template on the diagram. A node template can be on many diagrams This class creates the rectangle graphics item and the text graphics item and adds them to the scene. ''' def __init__(self, scene, x, y, nodeTemplateDict=None, NZID=None): self.scene = scene self.logMsg = None self.x = x self.y = y self.nodeTemplateDict = nodeTemplateDict # self.name = self.nodeTemplateDict.get("name", "") THIS HAS BEEN REPLACED BY THE name FUNCTION - SEE BELOW self.diagramType = "Node Template" self.displayText = None self.model = self.scene.parent.model self.gap = 100 self.relList = [] # assign a unique key if it doesn't already have one if NZID == None: self.NZID = str(uuid.uuid4()) else: self.NZID = NZID # init graphics objects to none self.TNode = None self.TNtext = None # draw the node template on the diagram self.drawIt() def name(self, ): return self.nodeTemplateDict.get("name", "") def getX(self, ): return self.TNode.boundingRect().x() def getY(self, ): return self.TNode.boundingRect().y() def getHeight(self, ): return self.TNode.boundingRect().height() def getWidth(self, ): return self.TNode.boundingRect().width() def getRelList(self, ): '''return a list of all relationitems that are inbound or outbound from this node template. do not include self referencing relationships ''' return [ diagramItem for key, diagramItem in self.scene.parent.itemDict.items() if diagramItem.diagramType == "Relationship Template" and ( diagramItem.startNZID == self.NZID or diagramItem.endNZID == self.NZID) ] def getPoint(self, offset=None): ''' This function is used by the template diagram to calculate the location to drop a node template on the diagram ''' if offset is None: return QPointF(self.x, self.y) else: return QPointF(self.x + offset, self.y + offset) def getFormat(self, ): ''' determine if the Node Template has a template format or should use the project default format ''' # get the node Template custom format customFormat = self.nodeTemplateDict.get("TNformat", None) if not customFormat is None: # get the template custom format self.nodeFormat = TNodeFormat(formatDict=customFormat) else: # get the project default format self.nodeFormat = TNodeFormat( formatDict=self.model.modelData["TNformat"]) def clearItem(self, ): if (not self.TNode is None and not self.TNode.scene() is None): self.TNode.scene().removeItem(self.TNode) if (not self.TNtext is None and not self.TNtext.scene() is None): self.TNtext.scene().removeItem(self.TNtext) def drawIt(self, ): # get current format as it may have changed self.getFormat() # create the qgraphicsItems if they don't exist if self.TNode is None: # create the rectangle self.TNode = QGraphicsRectItem(QRectF( self.x, self.y, self.nodeFormat.formatDict["nodeWidth"], self.nodeFormat.formatDict["nodeHeight"]), parent=None) self.TNode.setZValue(NODELAYER) self.TNode.setFlag(QGraphicsItem.ItemIsMovable, True) self.TNode.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.TNode.setFlag(QGraphicsItem.ItemIsSelectable, True) self.TNode.setSelected(True) self.TNode.setData(1, self.NZID) # get with self.INode.data(1) self.TNode.setData(ITEMTYPE, NODETEMPLATE) # create the text box self.TNtext = QGraphicsTextItem("", parent=None) self.TNtext.setPos(self.x, self.y) self.TNtext.setFlag(QGraphicsItem.ItemIsMovable, True) self.TNtext.setFlag(QGraphicsItem.ItemIsSelectable, False) self.TNtext.setData(NODEID, self.NZID) self.TNtext.setData(ITEMTYPE, NODETEMPLATETEXT) self.TNtext.setZValue(NODELAYER) # save the location self.x = self.TNode.sceneBoundingRect().x() self.y = self.TNode.sceneBoundingRect().y() # generate the html and resize the rectangle self.formatItem() # add the graphics items to the scene self.scene.addItem(self.TNode) self.scene.addItem(self.TNtext) else: # generate the html and resize the rectangle self.formatItem() def formatItem(self, ): # configure the formatting aspects of the qgraphics item pen = self.nodeFormat.pen() brush = self.nodeFormat.brush() self.TNode.setBrush(brush) self.TNode.setPen(pen) # generate the HTML genHTML = self.generateHTML() self.TNtext.prepareGeometryChange() # print("before html bounding rectangle width:{}".format(self.TNtext.boundingRect().width())) # print("before html text width:{}".format(self.TNtext.textWidth())) self.TNtext.setTextWidth( -1 ) # reset the width to unkonwn so it will calculate a new width based on the new html self.TNtext.setHtml(genHTML) # print("after html bounding rectangle width:{}".format(self.TNtext.boundingRect().width())) # print("after html text width:{}".format(self.TNtext.textWidth())) # make sure minimum width of 120 if self.TNtext.boundingRect().width() < 120: self.TNtext.setTextWidth(120) else: self.TNtext.setTextWidth( self.TNtext.boundingRect().width() ) # you have to do a setTextWidth to get the html to render correctly. # set the rectangle item to the same size as the formatted html self.TNode.prepareGeometryChange() currentRect = self.TNode.rect() # insure minimum height of 120 if self.TNtext.boundingRect().height() < 120: currentRect.setHeight(120) else: currentRect.setHeight(self.TNtext.boundingRect().height()) currentRect.setWidth(self.TNtext.boundingRect().width()) self.TNode.setRect(currentRect) def generateHTML(self, ): ''' Generate the HTML that formats the node template data inside the rectangle ''' # generate the html prefix = "<!DOCTYPE html><html><body>" # head = "<head><style>table, th, td {border: 1px solid black; border-collapse: collapse;}</style></head>" suffix = "</body></html>" # blankRow = "<tr><td><left>{}</left></td><td><left>{}</left></td><td><left>{}</left></td><td><left>{}</left></td></tr>".format("", "", "", "") name = "<center><b>{}</b></center>".format( self.nodeTemplateDict.get("name", "")) lbls = self.genLblHTML() props = self.genPropHTML() genHTML = "{}{}<hr>{}<br><hr>{}{}".format(prefix, name, lbls, props, suffix) # print("{} html: {}".format(self.name(), genHTML)) return genHTML def genLblHTML(self): # html = '<table width="90%">' html = '<table style="width:90%;border:1px solid black;">' if len(self.nodeTemplateDict.get("labels", [])) > 0: for lbl in self.nodeTemplateDict.get("labels", []): if lbl[NODEKEY] == Qt.Checked: nk = "NK" else: nk = " " if lbl[REQUIRED] == Qt.Checked: rq = "R" else: rq = "" html = html + '<tr align="left"><td width="15%"><left>{}</left></td><td width="65%"><left>{}</left></td><td width="10%"><left>{}</left></td><td width="10%"><left>{}</left></td></tr>'.format( nk, lbl[LABEL], "", rq) html = html + "</table>" else: html = '<tr align="left"><td width="15%"><left>{}</left></td><td width="65%"><left>{}</left></td><td width="10%"><left>{}</left></td><td width="10%"><left>{}</left></td></tr>'.format( " ", "NO{}LABELS".format(" "), "", "") html = html + "</table>" return html def genPropHTML(self): # PROPERTY, DATATYPE, PROPREQ, DEFAULT, EXISTS, UNIQUE, PROPNODEKEY html = '<table style="width:90%;border:1px solid black;">' if len(self.nodeTemplateDict.get("properties", [])) > 0: for prop in self.nodeTemplateDict.get("properties", []): if prop[PROPNODEKEY] == Qt.Checked: nk = "NK" else: nk = " " if prop[PROPREQ] == Qt.Checked: rq = "R" else: rq = "" if prop[EXISTS] == Qt.Checked: ex = "E" else: ex = "" if prop[UNIQUE] == Qt.Checked: uq = "U" else: uq = "" html = html + '<tr align="left"><td width="15%"><left>{}</left></td><td width="65%"><left>{}</left></td><td width="10%"><left>{}</left></td><td width="10%"><left>{}</left></td><td width="10%"><left>{}</left></td></tr>'.format( nk, prop[PROPERTY], rq, ex, uq) html = html + "</table>" else: html = html + '<tr align="left"><td width="15%"><left>{}</left></td><td width="65%"><left>{}</left></td><td width="10%"><left>{}</left></td><td width="10%"><left>{}</left></td></tr>'.format( " ", "NO{}PROPERTIES".format(" "), "", "", "") html = html + "</table>" return html def moveIt(self, dx, dy): ''' Move the node rectangle and the node textbox to the delta x,y coordinate. ''' # print("before moveIt: sceneboundingrect {} ".format( self.INode.sceneBoundingRect())) self.TNode.moveBy(dx, dy) self.x = self.TNode.sceneBoundingRect().x() self.y = self.TNode.sceneBoundingRect().y() self.TNtext.moveBy(dx, dy) # print("after moveIt: sceneboundingrect {} ".format( self.INode.sceneBoundingRect())) # now redraw all the relationships self.drawRels() def drawRels(self, ): '''Redraw all the relationship lines connected to the Node Template Rectangle''' # get a list of the relationship items connected to this node template self.relList = self.getRelList() # assign the correct inbound/outbound side for the rel for rel in self.relList: if rel.endNodeItem.NZID != rel.startNodeItem.NZID: # ignore bunny ears rel.assignSide() # get a set of all the nodes and sides involved nodeSet = set() for rel in self.relList: if rel.endNodeItem.NZID != rel.startNodeItem.NZID: # ignore bunny ears nodeSet.add((rel.endNodeItem, rel.inboundSide)) nodeSet.add((rel.startNodeItem, rel.outboundSide)) # tell each node side to assign rel locations for nodeSide in nodeSet: nodeSide[0].assignPoint(nodeSide[1]) ############################################ # now tell them all to redraw for rel in self.relList: rel.drawIt2() def calcOffset(self, index, totRels): offset = [-60, -40, -20, 0, 20, 40, 60] offsetStart = [3, 2, 2, 1, 1, 0, 0] if totRels > 7: totRels = 7 return offset[offsetStart[totRels - 1] + index] def assignPoint(self, side): # go through all the rels on a side and assign their x,y coord for that side self.relList = self.getRelList() sideList = [ rel for rel in self.relList if ((rel.startNZID == self.NZID and rel.outboundSide == side) or ( rel.endNZID == self.NZID and rel.inboundSide == side)) ] totRels = len(sideList) if totRels > 0: if side == R: # calc center of the side x = self.x + self.getWidth() y = self.y + self.getHeight() / 2 # sort the rels connected to this side by the y value sideList.sort(key=self.getSortY) # assign each of them a position on the side starting in the center and working out in both directions for index, rel in enumerate(sideList): if rel.startNZID == self.NZID: rel.outboundPoint = QPointF( x, y + (self.calcOffset(index, totRels))) if rel.endNZID == self.NZID: rel.inboundPoint = QPointF( x, y + (self.calcOffset(index, totRels))) elif side == L: x = self.x y = self.y + self.getHeight() / 2 sideList.sort(key=self.getSortY) for index, rel in enumerate(sideList): if rel.startNZID == self.NZID: rel.outboundPoint = QPointF( x, y + (self.calcOffset(index, totRels))) if rel.endNZID == self.NZID: rel.inboundPoint = QPointF( x, y + (self.calcOffset(index, totRels))) elif side == TOP: x = self.x + self.getWidth() / 2 y = self.y sideList.sort(key=self.getSortX) for index, rel in enumerate(sideList): if rel.startNZID == self.NZID: rel.outboundPoint = QPointF( x + (self.calcOffset(index, totRels)), y) if rel.endNZID == self.NZID: rel.inboundPoint = QPointF( x + (self.calcOffset(index, totRels)), y) elif side == BOTTOM: x = self.x + self.getWidth() / 2 y = self.y + self.getHeight() sideList.sort(key=self.getSortX) for index, rel in enumerate(sideList): if rel.startNZID == self.NZID: rel.outboundPoint = QPointF( x + (self.calcOffset(index, totRels)), y) if rel.endNZID == self.NZID: rel.inboundPoint = QPointF( x + (self.calcOffset(index, totRels)), y) else: print("error, no side") def getSortY(self, rel): # if this node is the start node then return the end node's Y if rel.startNZID == self.NZID: return rel.endNodeItem.TNode.sceneBoundingRect().center().y() # if this node is the end node then return the start node's Y if rel.endNZID == self.NZID: return rel.startNodeItem.TNode.sceneBoundingRect().center().y() # this should never happen return 0 def getSortX(self, rel): # if this node is the start node then return the end node's X if rel.startNZID == self.NZID: return rel.endNodeItem.TNode.sceneBoundingRect().center().x() # if this node is the end node then return the start node's X if rel.endNZID == self.NZID: return rel.startNodeItem.TNode.sceneBoundingRect().center().x() # this should never happen return 0 def getObjectDict(self, ): ''' This function returns a dictionary with all the data that represents this node template item. The dictionary is added to the Instance Diagram dictionary.''' objectDict = {} objectDict["NZID"] = self.NZID objectDict["name"] = self.nodeTemplateDict.get("name", "") objectDict["displayText"] = self.displayText objectDict["x"] = self.TNode.sceneBoundingRect().x() objectDict["y"] = self.TNode.sceneBoundingRect().y() objectDict["diagramType"] = self.diagramType objectDict["labels"] = self.nodeTemplateDict.get("labels", []) objectDict["properties"] = self.nodeTemplateDict.get("properties", []) return objectDict def setLogMethod(self, logMethod=None): if logMethod is None: if self.logMsg is None: self.logMsg = self.noLog else: self.logMsg = logMethod def noLog(self, msg): return
class painter(QGraphicsView): pixelSize = int(15 / narrowRatio) width = int(480 / narrowRatio) height = int(360 / narrowRatio) fontSize = int(15 / narrowRatio) anchorLineSize = int(100 / narrowRatio) ellipseRadius = int(8 / narrowRatio) textInterval = int(90 / narrowRatio) col = width / pixelSize line = height / pixelSize centerIndex = int(round(((line / 2 - 1) * col) + col / 2)) frameCount = 0 failedCount = 0 baseZValue = 0 mode = 1 body = 1 open_status = 0 textLineHeight = fontSize + 10 blurRaduis = 50 # Smoother improvement def __init__(self, dataThread): super(painter, self).__init__() self.dataThread = dataThread self.setFixedSize(self.width + 200, self.height + self.textLineHeight) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scene = QGraphicsScene() self.setScene(self.scene) # center het text item self.centerTextItem = QGraphicsTextItem() self.centerTextItem.setPos((self.width + 200) / 2 - self.fontSize, 0) self.centerTextItem.setZValue(self.baseZValue + 1) self.scene.addItem(self.centerTextItem) # version text item self.versionTextItem = QGraphicsTextItem() self.versionTextItem.setPos(self.width * 0.8 - self.fontSize, self.height * 0.8 - self.fontSize) self.versionTextItem.setZValue(self.baseZValue + 1) self.scene.addItem(self.versionTextItem) self.userCom = None # center anchor item centerX = self.width / 2 centerY = self.height / 2 self.ellipseItem = QGraphicsEllipseItem(0, 0, self.ellipseRadius * 2, self.ellipseRadius * 2) self.horLineItem = QGraphicsLineItem(0, 0, self.anchorLineSize, 0) self.verLineItem = QGraphicsLineItem(0, 0, 0, self.anchorLineSize) self.ellipseItem.setPos(centerX - self.ellipseRadius, centerY - self.ellipseRadius) self.horLineItem.setPos(centerX - self.anchorLineSize / 2, centerY) self.verLineItem.setPos(centerX, centerY - self.anchorLineSize / 2) self.ellipseItem.setPen(QColor(Qt.white)) self.horLineItem.setPen(QColor(Qt.white)) self.verLineItem.setPen(QColor(Qt.white)) self.ellipseItem.setZValue(self.baseZValue + 1) self.horLineItem.setZValue(self.baseZValue + 1) self.verLineItem.setZValue(self.baseZValue + 1) self.scene.addItem(self.ellipseItem) self.scene.addItem(self.horLineItem) self.scene.addItem(self.verLineItem) # camera item self.cameraBuffer = QPixmap(self.width, self.height + self.textLineHeight) self.cameraItem = QGraphicsPixmapItem() if useBlur: self.gusBlurEffect = QGraphicsBlurEffect() self.gusBlurEffect.setBlurRadius(self.blurRaduis) self.cameraItem.setGraphicsEffect(self.gusBlurEffect) self.cameraItem.setPos(100, 0) self.cameraItem.setZValue(self.baseZValue) self.scene.addItem(self.cameraItem) # het text item self.hetTextBuffer = QPixmap(self.width + 200, self.textLineHeight) self.hetTextItem = QGraphicsPixmapItem() self.hetTextItem.setPos(0, self.height) self.hetTextItem.setZValue(self.baseZValue) self.scene.addItem(self.hetTextItem) # button item self.ctrlOpenButton = QPushButton('Open', self) self.ctrlOpenButton.clicked.connect(self.ctrlOpen) self.ctrlOpenButton.setGeometry(10, 30, 100, 40) self.EvaluateButton = QPushButton('None', self) self.EvaluateButton.clicked.connect(self.evaluate) self.EvaluateButton.setGeometry(10, 80, 100, 40) self.getOnePicButton = QPushButton('Get a frame', self) self.getOnePicButton.clicked.connect(self.ctrlSendone) self.getOnePicButton.setGeometry(10, 130, 100, 40) self.getOnePicButton.setEnabled(False) self.modeManualButton = QPushButton('Auto', self) self.modeManualButton.clicked.connect(self.modeManual) self.modeManualButton.setGeometry(10, 180, 100, 40) self.modeObjButton = QPushButton('Body', self) self.modeObjButton.clicked.connect(self.objBody) self.modeObjButton.setGeometry(10, 230, 100, 40) self.modeFpsButton = QPushButton('4FPS', self) self.modeFpsButton.clicked.connect(self.rate) self.modeFpsButton.setGeometry(10, 280, 100, 40) self.modeAutoButton = QPushButton('Get offset', self) self.modeAutoButton.clicked.connect(self.commonOffset) self.modeAutoButton.setGeometry(570, 30, 100, 40) self.modeAutoButton = QPushButton('Get version', self) self.modeAutoButton.clicked.connect(self.sysVer) self.modeAutoButton.setGeometry(570, 80, 100, 40) self.evaluate = 1 self.evaluateButton = QPushButton('Evaluate', self) self.evaluateButton.clicked.connect(self.setEvaluate) self.evaluateButton.setGeometry(570, 120, 100, 40) self.serial_l = QLabel(self) self.serial_l.move(580, 250) self.serial_l.resize(60, 30) self.serial_l.setStyleSheet( "QLabel{color:rgb(0,0,0,255);background-color: rgb(255,255,255);font-size:16px;font-weight:normal;font-family:Arial;}" ) self.serial_l.setText("Serial:") self.serialList = SerialComboBox(self) self.serialList.setCurrentIndex(0) self.serialList.setStyleSheet( "border-width: 1px;border-style: solid;border-color: rgb(255, 170, 0);" ) self.serialList.currentIndexChanged.connect(self.serialChange) # self.evaluateButton.setGeometry(570,140,100,40) self.serialList.move(580, 280) self.serialList.resize(120, 30) self.serialList.addItem("Please select serial device") def checkSerial(self): reply = QMessageBox.information(self, 'No serial', "Please select serial device", QMessageBox.Yes) # portlist = SerialComboBox().get_port_list(self) # self.userCom = None # if portlist is not None: # for port in portlist: # print("port ",port) # self.userCom = port # if self.userCom is not None : # self.dataThread.openSerial(self.userCom) # else: # reply = QMessageBox.information(self, '没有设置串口', "请选择串口" , QMessageBox.Yes) def serialChange(self, i): print("serialChange", i, self.serialList.currentText()) if i > 0: self.userCom = self.serialList.currentText() self.dataThread.initSerialPort(self.userCom) def ctrlOpen(self): print("self.userCom", self.userCom) if self.userCom is None: self.checkSerial() return if self.open_status == 1: print('start send C command 0') self.open_status = 0 self.ctrlOpenButton.setText("Open") self.dataThread.sendData('CMDC\0') else: print('start send C command 1') self.open_status = 1 self.ctrlOpenButton.setText("Close") self.dataThread.sendData('CMDC\1') def evaluate(self): if self.userCom is None: self.checkSerial() return global evaluate_mode if evaluate_mode == "operate": print('start send E command 0') evaluate_mode = "evaluate" self.EvaluateButton.setText("Evaluate") self.dataThread.sendData('CMDE\1') else: print('start send E command 1') evaluate_mode = "operate" self.EvaluateButton.setText("Operate") self.dataThread.sendData('CMDE\0') def ctrlSendone(self): if self.userCom is None: self.checkSerial() return print('send a frame') self.dataThread.sendData('CMDC\2') def modeManual(self): if self.userCom is None: self.checkSerial() return if self.mode == 1: self.getOnePicButton.setEnabled(True) self.modeManualButton.setText("Manual") self.dataThread.sendData('CMDM\0') self.mode = 0 print('mode: manual') else: self.getOnePicButton.setEnabled(False) self.modeManualButton.setText("Auto") self.dataThread.sendData('CMDM\1') print('mode: auto') self.mode = 1 def modeAuto(self): if self.userCom is None: self.checkSerial() return print('mode: auto') self.dataThread.sendData('CMDM\1') def rate(self): if self.userCom is None: self.checkSerial() return global btn_index btn_index = (btn_index + 1) % 5 print('FPS:', strButton[btn_index]) self.modeFpsButton.setText(strButton[btn_index]) self.dataThread.sendData(strFpsCmd[btn_index]) #'CMDF\0') def objBody(self): if self.userCom is None: self.checkSerial() return if self.body == 1: self.body = 0 print('obj: Object') self.modeObjButton.setText("Object") self.dataThread.sendData('CMDO\0') else: self.body = 1 print('obj: Human Body') self.modeObjButton.setText("Body") self.dataThread.sendData('CMDO\1') def uiUpdate(self): global evaluate_mode print("update UI ", evaluate_mode) if evaluate_mode == "operate": self.EvaluateButton.setText("Operate") elif evaluate_mode == "evaluate": self.EvaluateButton.setText("Evaluate") else: self.EvaluateButton.setText("None") def cmdUpdate(self): if self.userCom is None: self.checkSerial() return print("get evaluate status and version\n") time.sleep(0.1) self.dataThread.sendData('CMDE\2') time.sleep(0.1) self.dataThread.sendData('CMDV\0') time.sleep(0.1) self.dataThread.sendData('CMDT\1') def commonOffset(self): if self.userCom is None: self.checkSerial() return self.dataThread.sendData('CMDT\1') print("Get commonOffset") def sysVer(self): if self.userCom is None: self.checkSerial() return self.dataThread.sendData('CMDV\1') print("Get firmware version and calibration version.") def setEvaluate(self): if self.userCom is None: self.checkSerial() return if self.evaluate == 1: self.evaluate = 0 self.evaluateButton.setText("Operate") self.dataThread.sendData('CMDE\0') else: self.evaluate = 1 self.evaluateButton.setText("Evaluate") self.dataThread.sendData('CMDE\1') def draw(self): global minHue global maxHue global maxHet global minHet global device_commonOffset global evaluate_mode if len(displayData) == 0: return font = QFont() color = QColor() font.setPointSize(self.fontSize) #font.setFamily("Microsoft YaHei") font.setLetterSpacing(QFont.AbsoluteSpacing, 0) index = 0 lock.acquire() frame = displayData.pop(0) lock.release() p = QPainter(self.cameraBuffer) p.fillRect(0, 0, self.width, self.height + self.textLineHeight, QBrush(QColor(Qt.black))) # draw camera color = QColor() cneter = 0.0 if chip == "90640": if self.centerIndex == 0: centerIndex = 12 * 32 + 16 for yIndex in range(int(self.height / self.pixelSize)): for xIndex in range(int(self.width / self.pixelSize)): color.setHsvF(frame[index] / 360, 1.0, 1.0) p.fillRect(xIndex * self.pixelSize, yIndex * self.pixelSize, self.pixelSize, self.pixelSize, QBrush(color)) index = index + 1 cneter = round( mapValue(frame[self.centerIndex], minHue, maxHue, minHet, maxHet), 1) elif chip == "90621": if self.centerIndex == 0 or self.centerIndex >= 64: self.centerIndex = 2 * 16 + 8 cneter = round( mapValue(frame[self.centerIndex], minHue, maxHue, minHet, maxHet), 1) for yIndex in range(int(self.height / self.pixelSize / 6)): for xIndex in range(int(self.width / self.pixelSize / 2)): color.setHsvF(frame[index] / 360, 1.0, 1.0) p.fillRect(xIndex * self.pixelSize * 2, yIndex * self.pixelSize * 2 + 160, self.pixelSize * 2, self.pixelSize * 2, QBrush(color)) index = index + 1 elif chip == "90641": if self.centerIndex == 0 or self.centerIndex >= 192: self.centerIndex = 6 * 16 + 8 cneter = round( mapValue(frame[self.centerIndex], minHue, maxHue, minHet, maxHet), 1) for yIndex in range(int(self.height / self.pixelSize / 2)): for xIndex in range(int(self.width / self.pixelSize / 2)): color.setHsvF(frame[index] / 360, 1.0, 1.0) p.fillRect(xIndex * self.pixelSize * 2, yIndex * self.pixelSize * 2, self.pixelSize * 2, self.pixelSize * 2, QBrush(color)) index = index + 1 else: print("Dsiplay Error: can't detect any chip type!") self.cameraItem.setPixmap(self.cameraBuffer) self.frameCount = self.frameCount + 1 # draw text p = QPainter(self.hetTextBuffer) p.fillRect(0, 0, self.width + 200, self.height + self.textLineHeight, QBrush(QColor(Qt.black))) version = self.dataThread.getID() p.setPen(QColor(Qt.white)) p.setFont(font) p.drawText(0, self.fontSize, " max:" + '{:.2f}'.format(maxHet)) p.drawText(self.textInterval, self.fontSize, " min:" + '{:.2f}'.format(minHet)) p.drawText(self.textInterval * 2, self.fontSize, "offset:" + '{:.2f}'.format(device_commonOffset)) p.drawText(self.textInterval * 3, self.fontSize, "mode:" + detect_status) p.drawText(self.textInterval * 4, self.fontSize, evaluate_mode) p.drawText(self.textInterval * 5, self.fontSize, "ID:" + str(version[0])) p.drawText(self.textInterval * 6, self.fontSize, "ver:" + str(version[1] & 0xff)) p.drawText(self.textInterval * 7, self.fontSize, chip) self.hetTextItem.setPixmap(self.hetTextBuffer) cneter = round( mapValue(frame[self.centerIndex], minHue, maxHue, minHet, maxHet), 1) centerText = "<font color=white>%s</font>" self.centerTextItem.setFont(font) self.centerTextItem.setHtml(centerText % (str(cneter) + "°")) # draw version text self.versionTextItem.setFont(font)
class painter(QGraphicsView): narrowRatio = int(sys.argv[4]) if len(sys.argv) >= 5 else 1 useBlur = sys.argv[5] != "False" if len(sys.argv) >= 6 else True pixelSize = int(15 / narrowRatio) width = int(480 / narrowRatio) height = int(360 / narrowRatio) fontSize = int(30 / narrowRatio) anchorLineSize = int(100 / narrowRatio) ellipseRadius = int(8 / narrowRatio) textInterval = int(90 / narrowRatio) col = width / pixelSize line = height / pixelSize centerIndex = int(round(((line / 2 - 1) * col) + col / 2)) frameCount = 0 baseZValue = 0 textLineHeight = fontSize + 10 blurRaduis = 50 # Smoother improvement def __init__(self): super(painter, self).__init__() self.setFixedSize(self.width, self.height + self.textLineHeight) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scene = QGraphicsScene() self.setScene(self.scene) # center het text item self.centerTextItem = QGraphicsTextItem() self.centerTextItem.setPos(self.width / 2 - self.fontSize, 0) self.centerTextItem.setZValue(self.baseZValue + 1) self.scene.addItem(self.centerTextItem) # center anchor item centerX = self.width / 2 centerY = self.height / 2 self.ellipseItem = QGraphicsEllipseItem(0, 0, self.ellipseRadius * 2, self.ellipseRadius * 2) self.horLineItem = QGraphicsLineItem(0, 0, self.anchorLineSize, 0) self.verLineItem = QGraphicsLineItem(0, 0, 0, self.anchorLineSize) self.ellipseItem.setPos(centerX - self.ellipseRadius, centerY - self.ellipseRadius) self.horLineItem.setPos(centerX - self.anchorLineSize / 2, centerY) self.verLineItem.setPos(centerX, centerY - self.anchorLineSize / 2) self.ellipseItem.setPen(QColor(Qt.white)) self.horLineItem.setPen(QColor(Qt.white)) self.verLineItem.setPen(QColor(Qt.white)) self.ellipseItem.setZValue(self.baseZValue + 1) self.horLineItem.setZValue(self.baseZValue + 1) self.verLineItem.setZValue(self.baseZValue + 1) self.scene.addItem(self.ellipseItem) self.scene.addItem(self.horLineItem) self.scene.addItem(self.verLineItem) # camera item self.cameraBuffer = QPixmap(self.width, self.height + self.textLineHeight) self.cameraItem = QGraphicsPixmapItem() if self.useBlur: self.gusBlurEffect = QGraphicsBlurEffect() self.gusBlurEffect.setBlurRadius(self.blurRaduis) self.cameraItem.setGraphicsEffect(self.gusBlurEffect) self.cameraItem.setPos(0, 0) self.cameraItem.setZValue(self.baseZValue) self.scene.addItem(self.cameraItem) # het text item self.hetTextBuffer = QPixmap(self.width, self.textLineHeight) self.hetTextItem = QGraphicsPixmapItem() self.hetTextItem.setPos(0, self.height) self.hetTextItem.setZValue(self.baseZValue) self.scene.addItem(self.hetTextItem) def draw(self): if len(hetaData) == 0: return font = QFont() color = QColor() font.setPointSize(self.fontSize) font.setFamily("Microsoft YaHei") font.setLetterSpacing(QFont.AbsoluteSpacing, 0) index = 0 lock.acquire() frame = hetaData.pop(0) lock.release() maxHet = frame["maxHet"] minHet = frame["minHet"] frame = frame["frame"] p = QPainter(self.cameraBuffer) p.fillRect(0, 0, self.width, self.height + self.textLineHeight, QBrush(QColor(Qt.black))) # draw camera color = QColor() for yIndex in range(int(self.height / self.pixelSize)): for xIndex in range(int(self.width / self.pixelSize)): tempData = constrain( mapValue(frame[index], minHet, maxHet, minHue, maxHue), minHue, maxHue) color.setHsvF(tempData / 360, 1.0, 1.0) p.fillRect(xIndex * self.pixelSize, yIndex * self.pixelSize, self.pixelSize, self.pixelSize, QBrush(color)) index = index + 1 self.cameraItem.setPixmap(self.cameraBuffer) # draw text p = QPainter(self.hetTextBuffer) p.fillRect(0, 0, self.width, self.height + self.textLineHeight, QBrush(QColor(Qt.black))) hetDiff = maxHet - minHet bastNum = round(minHet) interval = round(hetDiff / 5) for i in range(5): hue = constrain( mapValue((bastNum + (i * interval)), minHet, maxHet, minHue, maxHue), minHue, maxHue) color.setHsvF(hue / 360, 1.0, 1.0) p.setPen(color) p.setFont(font) p.drawText(i * self.textInterval, self.fontSize + 3, str(bastNum + (i * interval)) + "°") self.hetTextItem.setPixmap(self.hetTextBuffer) # draw center het text cneter = round(frame[self.centerIndex], 1) centerText = "<font color=white>%s</font>" self.centerTextItem.setFont(font) self.centerTextItem.setHtml(centerText % (str(cneter) + "°")) self.frameCount = self.frameCount + 1 print("picture->" + str(self.frameCount))
def test4(self): file_name = self.lf1[self.listWidget.currentRow()][ 0] # параметр функции - имя лог файла lines = [] # читаем лог файл file = open(self.path + file_name) for line in file: lines.append(line.rstrip('\n')) # Читаем файл по строкам file.close() #print lines cpw = [ ] # Временный массив для разбиения строк на составлящие (возмоно не нужен) for i in range(len(lines)): cpw.append(lines[i].strip().split(',')) #print cpw if 9 <= len(lines) < 29: #обработка длины лога step = len(lines) - 2 elif len(lines) < 9: self.scene.clear() self.scene.addText('неверный лог').setPos( self.graphicsView.width() * 0.9 / 2, self.graphicsView.height() * 0.9 / 2) return else: step = 29 xy = [] # Заполнение массива координат графиков for i in range(len(cpw)): xy.append([]) for j in range(len(cpw[i])): xy[-1].append(float(cpw[i][j])) #print xy cpw = [] # clear memory x1 = xy[-1][0] x0 = xy[0][0] # Вычитание нулевой точки по оси x for i in range(len(xy)): xy[i][0] = xy[i][0] - x0 maxx = xy[-1][0] # поиск максимумов координат графиков maxy = 0 maxz = 0 max3 = 0 max4 = 0 max5 = 0 for i in range(len(xy)): if maxy < xy[i][1]: maxy = xy[i][1] if maxz < xy[i][2]: maxz = xy[i][2] if max3 < xy[i][3]: max3 = xy[i][3] if max4 < xy[i][4]: max4 = xy[i][4] if max5 < xy[i][5]: max5 = xy[i][5] kx = int(self.graphicsView.width() * 0.9) / xy[-1][ 0] # Выбор коэффициентов нормировки по осям (сцена центрируется автоматически) ky = int(self.graphicsView.height() * 0.9) / maxy for i in range( len(xy)): # Преобразование координат графиков к экранным xy[i][0] *= kx # Простое растяжение по оси xy[i][1] = (maxy - xy[i][1]) * ky # Растяжение по оси с отражением if maxz != 0: xy[i][2] = maxy * xy[i][2] / ( maxz * 2 ) # Нормировка на 1 и далее нормировка на примерно половину высоты графика температуры if max3 != 0: xy[i][3] = maxy * xy[i][3] / (max3 * 2.1) if max4 != 0: xy[i][4] = maxy * xy[i][4] / (max4 * 2.2) if max5 != 0: xy[i][5] = maxy * xy[i][5] / (max5) self.scene.clear() # Очистка сцены for i in range(len(xy) - 1): # Вывод графика температуры self.scene.addLine(xy[i][0], xy[i][1], xy[i + 1][0], xy[i + 1][1], QPen(QColor(Qt.black), 4)) ssx = int(maxx / step) # Шаг сетки по оси x mx = 0 i = 0 while mx < maxx: # Прорисовка штрихов по оси x mx += ssx i += 1 if (mx % 60) < 10: tempor = str(mx // 60) + ':0' + str(mx % 60) else: tempor = str(mx // 60) + ':' + str(mx % 60) #textItem = QGraphicsTextItem(tempor) self.scene.addText(tempor).setPos( mx * kx - 15, self.graphicsView.height() * 0.38 + 20 * (i % 2)) self.scene.addLine(0, maxy * ky, mx * kx, maxy * ky, QPen(QColor(Qt.blue))) # Ось x ssy = int(maxy / step) # Шаг сетки по оси y my = 0 while my < maxy: # Прорисовка штрихов по оси y. my += ssy #textItem = QGraphicsTextItem(str(my),None,self.scene).setPos(0, (maxy-my)*ky) #textItem1 = QGraphicsTextItem(str(int(my*max5/maxy)),None,self.scene).setPos(mx*kx+10, (maxy-my)*ky) self.scene.addText(str(my)).setPos(0, (maxy - my) * ky) self.scene.addText(str(int(my * max5 / maxy))).setPos( mx * kx + 10, (maxy - my) * ky) self.scene.addLine(0, maxy * ky, 0, (maxy - my) * ky, QPen(QColor(Qt.black), 4)) # Ось y. self.scene.addLine(mx * kx, maxy * ky, mx * kx, (maxy - my) * ky, QPen(QColor(Qt.yellow), 4)) # Ось y2. nx = 0 # Прорисовка вертикальных линий сетки. while nx < maxx: nx += ssx self.scene.addLine(nx * kx, maxy * ky, nx * kx, (maxy - my) * ky, QPen(QColor(Qt.black), 0.3)) ny = 0 # Прорисовка горизонтальных линий сетки. while ny < maxy: ny += ssy self.scene.addLine(0, (maxy - ny) * ky, mx * kx, (maxy - ny) * ky, QPen(QColor(Qt.black), 0.3)) ust = file_name.split('_')[-1] # Выделение уствки из имени файла ust = int(ust.split('.')[0]) # print ust for i in range(len(xy) - 1): # Вывод остальных графиков self.scene.addLine(xy[i][0], (maxy - ust) * ky, xy[i + 1][0], (maxy - ust) * ky, QPen(QColor(Qt.red), 4)) # график уставки self.scene.addLine(xy[i][0], (maxy - xy[i][2]) * ky, xy[i + 1][0], (maxy - xy[i + 1][2]) * ky, QPen(QColor(Qt.cyan), 4)) # второй график self.scene.addLine(xy[i][0], (maxy - xy[i][3]) * ky, xy[i + 1][0], (maxy - xy[i + 1][3]) * ky, QPen(QColor(Qt.magenta), 4)) # третий график self.scene.addLine(xy[i][0], (maxy - xy[i][4]) * ky, xy[i + 1][0], (maxy - xy[i + 1][4]) * ky, QPen(QColor(Qt.green), 4)) # четвёртый график self.scene.addLine(xy[i][0], (maxy - xy[i][5]) * ky, xy[i + 1][0], (maxy - xy[i + 1][5]) * ky, QPen(QColor(Qt.yellow), 4)) # пятый график # легенда lx = mx * kx + 10 - 260 ly = my * ky / 5 - 60 lh = 220 lw = 200 self.scene.addRect(lx, ly, lw, lh, QPen(QColor(Qt.black)), QBrush(QColor(Qt.white))) w = QGraphicsTextItem("", None) l = file_name.split('_')[1] if l == "1": w.setHtml(self.SetInfoPanelText("Линия 6,5 м.")) # parse from file else: w.setHtml(self.SetInfoPanelText("Линия 3,5 м.")) # parse from file w.setPos(lx + 20, ly + 0) self.scene.addItem(w) self.scene.addLine(lx + 10, ly + 45, lx + 45, ly + 45, QPen(QColor(Qt.black), 4)) w1 = QGraphicsTextItem("", None) w1.setHtml(self.SetInfoPanelText('Температура')) w1.setPos(lx + 50, ly + 25) self.scene.addItem(w1) self.scene.addLine(lx + 10, ly + 65, lx + 45, ly + 65, QPen(QColor(Qt.red), 4)) w2 = QGraphicsTextItem("", None) w2.setHtml(self.SetInfoPanelText('Уставка ' + str(ust))) w2.setPos(lx + 50, ly + 45) self.scene.addItem(w2) self.scene.addLine(lx + 10, ly + 85, lx + 45, ly + 85, QPen(QColor(Qt.cyan), 4)) w3 = QGraphicsTextItem("", None) w3.setHtml(self.SetInfoPanelText('Мощность')) w3.setPos(lx + 50, ly + 65) self.scene.addItem(w3) self.scene.addLine(lx + 10, ly + 105, lx + 45, ly + 105, QPen(QColor(Qt.magenta), 4)) w4 = QGraphicsTextItem("", None) w4.setHtml(self.SetInfoPanelText('Состояние')) w4.setPos(lx + 50, ly + 85) self.scene.addItem(w4) self.scene.addLine(lx + 10, ly + 125, lx + 45, ly + 125, QPen(QColor(Qt.green), 4)) w5 = QGraphicsTextItem("", None) w5.setHtml(self.SetInfoPanelText('Вентилятор')) w5.setPos(lx + 50, ly + 105) self.scene.addItem(w5) self.scene.addLine(lx + 10, ly + 145, lx + 45, ly + 145, QPen(QColor(Qt.yellow), 4)) w6 = QGraphicsTextItem("", None) w6.setHtml(self.SetInfoPanelText('Тены ' + str(max5))) w6.setPos(lx + 50, ly + 125) self.scene.addItem(w6) # Фактическая выдаржка dx = x1 - x0 min = dx // 60 #hour=int(min//60) min = int(min % 60) #hour=str(hour) #if len(hour)==1: # hour='0'+hour min = str(min) #if len(min)==1: # min='0'+min #t=hour+':'+min t = min + ' мин' w7 = QGraphicsTextItem("", None) w7.setHtml(self.SetInfoPanelText('Выдержка ' + t)) w7.setPos(lx + 20, ly + 145) self.scene.addItem(w7) # Начало s = time.localtime(float(x0)) min = str(s[4]) if len(min) == 1: min = '0' + min hour = str(s[3]) if len(hour) == 1: hour = '0' + hour t = hour + ':' + min w8 = QGraphicsTextItem("", None) w8.setHtml(self.SetInfoPanelText('Начало ' + t)) w8.setPos(lx + 20, ly + 165) self.scene.addItem(w8) # Окончание s = time.localtime(float(x1)) min = str(s[4]) if len(min) == 1: min = '0' + min hour = str(s[3]) if len(hour) == 1: hour = '0' + hour t = hour + ':' + min w9 = QGraphicsTextItem("", None) w9.setHtml(self.SetInfoPanelText('Окончание ' + t)) w9.setPos(lx + 20, ly + 185) self.scene.addItem(w9)
class NodeItem(): ''' This represents one node on the diagram. This class creates the ellipse graphics item and the text graphics item and adds them to the scene. ''' def __init__(self, scene, x, y, nodeInstance=None): self.scene = scene self.logMsg = None self.x = x self.y = y self.itemInstance = nodeInstance self.diagramType = self.itemInstance.diagramType self.displayText = None self.model = self.scene.parent.model self.neoCon = self.scene.parent.model.modelNeoCon self.getFormat() # remember current width and height self.oldNodeWidth = 0 self.oldNodeHeight = 0 # init graphics objects to none self.INode = None self.INtext = None # # init list of qgrapphicellipseitems to none # self.ellipsePoints = [] # self.ellipseGraphicItems = [] # draw the ellipse self.drawIt() def name(self, ): return self.itemInstance.NZID def NZID(self, ): return self.itemInstance.NZID def getFormat(self, ): ''' determine the format to use to draw the instance node - start with the project default - if the instance node has a template then use the instance format defined on the template ''' # get the default self.nodeFormat = INodeFormat( formatDict=self.model.modelData["INformat"]) # get a custom template format if there is one if not self.itemInstance.nodeTemplate is None: index, nodeTemplateDict = self.model.getDictByName( topLevel="Node Template", objectName=self.itemInstance.nodeTemplate) if not nodeTemplateDict is None: self.instanceNodeFormatDict = nodeTemplateDict.get( "INformat", None) if not self.instanceNodeFormatDict is None: self.nodeFormat = INodeFormat( formatDict=self.instanceNodeFormatDict) def clearItem(self, ): if (not self.INode is None and not self.INode.scene() is None): self.INode.scene().removeItem(self.INode) if (not self.INtext is None and not self.INtext.scene() is None): self.INtext.scene().removeItem(self.INtext) # # remove the points on the ellipse - this code is only for debugging # for point in self.ellipseGraphicItems: # if (not point is None and not point.scene() is None): # point.scene().removeItem(point) def drawIt(self, ): # force the node instance to update its values in case it has been updated from another diagram or the tree view self.itemInstance.reloadDictValues() # get current format as it may have changed self.getFormat() if self.oldNodeWidth != self.nodeFormat.formatDict[ "nodeWidth"] or self.oldNodeHeight != self.nodeFormat.formatDict[ "nodeHeight"]: # remove graphic items that already exist self.clearItem() # create the node ellipse self.INode = QGraphicsEllipseItem(QRectF( self.x, self.y, self.nodeFormat.formatDict["nodeWidth"], self.nodeFormat.formatDict["nodeHeight"]), parent=None) # create the node text self.INtext = QGraphicsTextItem("", parent=None) self.INtext.setPos(self.x, self.y) self.x = self.INode.sceneBoundingRect().x() self.y = self.INode.sceneBoundingRect().y() # print("after create items before drawIt: sceneboundingrect {} ".format( self.INode.sceneBoundingRect())) # print("x:{} y:{}".format(self.x, self.y)) self.formatItem() self.scene.addItem(self.INode) self.scene.addItem(self.INtext) # # add points # for point in self.ellipseGraphicItems: # self.scene.addItem(point) # redraw all the rels associated to this node. self.moveRels() else: # print("before drawIt: sceneboundingrect {} ".format( self.INode.sceneBoundingRect())) # print("x:{} y:{}".format(self.x, self.y)) self.formatItem() # remember current width and height self.oldNodeWidth = self.nodeFormat.formatDict["nodeWidth"] self.oldNodeHeight = self.nodeFormat.formatDict["nodeHeight"] # print("after drawIt: sceneboundingrect {} ".format( self.INode.sceneBoundingRect())) # print("x:{} y:{}".format(self.x, self.y)) # def genPoints(self, ): # '''Ellipse Constructor - not sure of these, need to verify # def __init__(self, mx, my, rh, rv): # mx - center point x # my - center point y # rh - height of ellipse # rv - width of ellipse''' # x = self.INode.sceneBoundingRect().center().x() # y = self.INode.sceneBoundingRect().center().y() # w = self.INode.sceneBoundingRect().width()/2.0 # h = self.INode.sceneBoundingRect().height()/2.0 # myEllipse = Ellipse(x, y, w, h) # for d in range(0, 360, 10): # x, y = myEllipse.pointFromAngle(radians(d)) # self.ellipsePoints.append([d, x, y]) # aPoint = QGraphicsEllipseItem(QRectF(x-2.5,y-2.5,5, 5), parent=None) # self.ellipseGraphicItems.append(aPoint) ## print(self.ellipsePoints) def formatItem(self, ): # configure the formatting aspects of the qgraphics item pen = self.nodeFormat.pen() brush = self.nodeFormat.brush() self.INode.setZValue(NODELAYER) self.INode.setBrush(brush) self.INode.setPen(pen) self.INode.setFlag(QGraphicsItem.ItemIsMovable, True) self.INode.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.INode.setFlag(QGraphicsItem.ItemIsSelectable, True) self.INode.setSelected(True) self.INode.setData( 1, self.itemInstance.NZID) # get with self.INode.data(1) self.INode.setData(ITEMTYPE, NODEINSTANCE) # draw the text self.updateText() self.INtext.setZValue(NODELAYER) self.INtext.setTextWidth(self.INode.boundingRect().width()) self.INtext.setFlag(QGraphicsItem.ItemIsMovable, True) self.INtext.setFlag(QGraphicsItem.ItemIsSelectable, False) self.INtext.setData(NODEID, self.itemInstance.NZID) self.INtext.setData(ITEMTYPE, NODEINSTANCETEXT) def updateText(self, ): ''' Generate the HTML that formats the node data inside the ellipse ''' # generate the html prefix = "<!DOCTYPE html><html><body>" suffix = "</body></html>" try: Lbl = str(self.itemInstance.labelList[0][0]) except: Lbl = "No Labels" firstLbl = "<center><b>{}</b></center>".format(Lbl) try: propName = str(self.itemInstance.propList[0][PROPERTY]) propVal = str(self.itemInstance.propList[0][VALUE]) prop = "{}: {}".format(propName, propVal) except: prop = "No Properties" firstProp = "<center>{}</center>".format(prop) genHTML = '{}{}<hr width="75%">{}{}'.format(prefix, firstLbl, firstProp, suffix) self.INtext.setHtml(genHTML) def moveIt(self, dx, dy): '''Move the node ellipse and the node textbox to the delta x,y coordinate.''' # print("before moveIt: sceneboundingrect {} ".format( self.INode.sceneBoundingRect())) self.INode.moveBy(dx, dy) self.x = self.INode.sceneBoundingRect().x() self.y = self.INode.sceneBoundingRect().y() self.INtext.moveBy(dx, dy) # print("after moveIt: sceneboundingrect {} ".format( self.INode.sceneBoundingRect())) # # recalc points # self.genPoints() # for point in self.ellipseGraphicItems: # point.moveBy(dx, dy) self.moveRels() def moveRels(self, ): '''Redraw all the relationship arcs connected to the Node ellipse.''' # print("moveRels") for key, diagramItem in self.scene.parent.itemDict.items(): if diagramItem.diagramType == "Instance Relationship": if self.itemInstance.NZID in [ diagramItem.relationInstance.startNZID, diagramItem.relationInstance.endNZID ]: diagramItem.drawRelationship() # if diagramItem.relationInstance.startNZID == self.itemInstance.NZID: # diagramItem.moveRelationshipLine() ## print("move startnode {}-{}".format(self.x, self.y)) # if diagramItem.relationInstance.endNZID == self.itemInstance.NZID: # diagramItem.moveRelationshipLine() ## print("move endnode {}-{}".format(self.x, self.y)) def getObjectDict(self, ): ''' This function returns a dictionary with all the data that represents this node item. The dictionary is added to the Instance Diagram dictionary.''' objectDict = {} objectDict["NZID"] = self.itemInstance.NZID objectDict["x"] = self.INode.sceneBoundingRect().x() objectDict["y"] = self.INode.sceneBoundingRect().y() objectDict["diagramType"] = self.diagramType return objectDict def setLogMethod(self, logMethod=None): if logMethod is None: if self.logMsg is None: self.logMsg = self.noLog else: self.logMsg = logMethod def noLog(self, msg): return
def dialog(decoders, set_decoder, synth=None): import sys app = QApplication(sys.argv) cycleText = QGraphicsTextItem() cycleText.setHtml('<font color=\"white\"><b>One Cycle</b></font>') scopeText = QGraphicsTextItem() scopeText.setHtml('<font color=\"white\"><b>Oscilloscope</b></font>') spectrumText = QGraphicsTextItem() spectrumText.setHtml('<font color=\"white\"><b>Log Spectrum</b></font>') def getCycle(): cycle = synth.lastCycle() cycle = detrend(lfilter([1], [-1], x=cycle)) return cycle waveformCycle = Waveform(getCycle) lastScope = [np.zeros(10)] def getScope(): scope = synth.lastScope() lastScope[0] = np.copy(scope) return scope / 2 waveformScope = Waveform(getScope) window = [np.zeros(10)] def getSpectrum(): wave = lastScope[0] w = window[0] if w.shape[0] != wave.shape[0]: window[0] = hamming(wave.shape[0], False) w = window[0] spec = np.log(np.abs(np.fft.rfft(wave * w)) + 0.001) spec = (spec + 2) / 12.0 return spec waveformSpectrum = Waveform(getSpectrum) w = cycleText.boundingRect().width() cycleBoundingRect = waveformCycle.mapToScene(waveformCycle.boundingRect())\ .boundingRect() cycleText.setPos(0, cycleBoundingRect.bottom() + 10.0) waveformScope.setPos(0, cycleBoundingRect.bottom() + 100.0) w = scopeText.boundingRect().width() scopeBoundingRect = waveformScope.mapToScene(waveformScope.boundingRect())\ .boundingRect() scopeText.setPos(0, scopeBoundingRect.bottom() + 10.0) waveformSpectrum.setPos(0, scopeBoundingRect.bottom() + 100.0) w = spectrumText.boundingRect().width() spectrumBoundingRect = waveformSpectrum.mapToScene(waveformSpectrum.boundingRect())\ .boundingRect() spectrumText.setPos(0, spectrumBoundingRect.bottom() + 10.0) scene = QGraphicsScene() scene.addItem(waveformCycle) scene.addItem(waveformScope) scene.addItem(waveformSpectrum) scene.addItem(cycleText) scene.addItem(scopeText) scene.addItem(spectrumText) scene.setBackgroundBrush(Qt.black) view = GraphicsView() view.setRenderHints(QPainter.Antialiasing) view.setTransformationAnchor(QGraphicsView.NoAnchor) view.setScene(scene) view.show() view.setFocus() # Make enough room in the scene for stickman to jump and die. sceneRect = scene.sceneRect() view.resize(sceneRect.width() + 100, sceneRect.height() + 100) view.setSceneRect(sceneRect) return Dialog(view, synth, decoders, set_decoder).exec_()
import sys app = QApplication(sys.argv) stickMan = StickMan() stickMan.setDrawSticks(False) textItem = QGraphicsTextItem() textItem.setHtml( "<font color=\"white\"><b>Stickman</b>" "<p>" "Tell the stickman what to do!" "</p>" "<p><i>" "<li>Press <font color=\"purple\">J</font> to make the stickman jump.</li>" "<li>Press <font color=\"purple\">D</font> to make the stickman dance.</li>" "<li>Press <font color=\"purple\">C</font> to make him chill out.</li>" "<li>When you are done, press <font color=\"purple\">Escape</font>.</li>" "</i></p>" "<p>If he is unlucky, the stickman will get struck by lightning, and never jump, dance or chill out again." "</p></font>") w = textItem.boundingRect().width() stickManBoundingRect = stickMan.mapToScene( stickMan.boundingRect()).boundingRect() textItem.setPos(-w / 2.0, stickManBoundingRect.bottom() + 25.0) scene = QGraphicsScene() scene.addItem(stickMan) scene.addItem(textItem)
class Shelf(VisualizerGraphicItem): def __init__(self, ID=0, x=0, y=0): super(self.__class__, self).__init__(ID, x, y) self._kind_name = 'shelf' self._carried = None self._products = [] self._graphics_item = QGraphicsEllipseItem(self) self._graphics_carried = QGraphicsEllipseItem() self._text = QGraphicsTextItem(self) self.setZValue(2.0) self.update_tooltip() def set_rect(self, rect): if self._carried is not None: rect = self._carried.get_rect() scale = config.get('display', 'id_font_scale') bold = config.get('display', 'id_font_bold') self._text.setFont(QFont('', rect.width() * 0.08 * scale)) self._text.setPos(rect.x(), rect.y() + 0.4 * rect.height()) self._text.setDefaultTextColor( QColor(config.get('display', 'id_font_color'))) if self._display_mode == 0: if bold: self._text.setHtml('<b>S(' + str(self._id) + ')</b>') else: self._text.setHtml('S(' + str(self._id) + ')') self._graphics_item.setRect(rect.x() + 0.25 * rect.width(), rect.y() + 0.25 * rect.height(), rect.width() * 0.5, rect.height() * 0.5) self._graphics_carried.setRect(rect.x() + 0.325 * rect.width(), rect.y() + 0.325 * rect.height(), rect.width() * 0.35, rect.height() * 0.35) elif self._display_mode == 1: self._text.setPlainText('') self._graphics_item.setRect(rect.x() + 0.05 * rect.width(), rect.y() + 0.05 * rect.height(), rect.width() * 0.9, rect.height() * 0.9) self._graphics_carried.setRect(rect.x() + 0.125 * rect.width(), rect.y() + 0.125 * rect.height(), rect.width() * 0.75, rect.height() * 0.75) def set_carried(self, robot): if robot == self._carried: return temp = self._carried self._carried = robot if temp is not None: temp.set_carries(None) if self._carried is not None: self._graphics_carried.setParentItem(self._graphics_item) self._carried.set_carries(self) else: self._graphics_carried.setParentItem(None) def restart(self): super(self.__class__, self).restart() products = [] for product in self._products: products.append((product[0], product[1], 0)) self._products = products def to_init_str(self): s = super(self.__class__, self).to_init_str() for product in self._products: s += ('\ninit(object(product,' + str(product[0]) + '),value(on,(' + str(self._id) + ',' + str(product[1]) + '))).') return s def update_tooltip(self): tooltip = "shelf(" + str(self._id) + ")\nproducts:\n" for product in self._products: tooltip = tooltip + str(product) + "\n" self.setToolTip(tooltip) def find_product(self, product_id): for product in self._products: if str(product_id) == str(product[0]): return product return None def set_product_amount(self, product_id, amount): product = self.find_product(product_id) if product is None: self._products.append((product_id, amount, 0)) else: self._products.remove(product) self._products.append((product_id, amount, product[2])) self.update_tooltip() def add_product(self, product_id, amount): product = self.find_product(product_id) if product is None: if amount == 0: amount = 1 self._products.append((product_id, amount, 0)) else: if amount == 0: self._products.append((product_id, 0, 0)) else: self._products.append((product_id, product[1] + amount, 0)) self._products.remove(product) self.update_tooltip() def remove_product(self, product_id, amount): product = self.find_product(product_id) if product is not None: self._products.append( (product_id, product[1], product[2] + amount)) self._products.remove(product) def delete_product(self, product_id): product = self.find_product(product_id) if product is not None: self._products.remove(product) self.update_tooltip() def determine_color(self, number, count, pattern=None): color = calculate_color(self._colors[0], self._colors[1], (float)(number) / count) brush = QBrush(color) self._graphics_item.setBrush(brush) self._graphics_carried.setBrush(QBrush(self._colors[2])) def get_product_amount(self, product_id): product = self.find_product(product_id) if product is None: return 0 return product[1] - product[2] def get_rect(self): if self._display_mode == 0: rect = self._graphics_item.rect() width = rect.width() * 2 height = rect.height() * 2 rect.setLeft(rect.x() - 0.25 * width) rect.setTop(rect.y() - 0.25 * height) rect.setWidth(width) rect.setHeight(height) return rect elif self._display_mode == 1: rect = self._graphics_item.rect() width = rect.width() / 0.9 height = rect.height() / 0.9 rect.setLeft(rect.x() - 0.05 * width) rect.setTop(rect.y() - 0.05 * height) rect.setWidth(width) rect.setHeight(height) return rect def get_carried(self): return self._carried def iterate_products(self): for product in self._products: yield product def edit_position_to(self, x, y): if (x, y) == self._position: return if self._carried is not None: return item2 = self._model.filter_items(item_kind=self._kind_name, position=(x, y), return_first=True)[0] if item2 is not None: if item2.get_carried() is not None: return item2.set_position(self._position[0], self._position[1]) item2.set_starting_position(self._position[0], self._position[1]) self.set_position(x, y) self.set_starting_position(x, y) def mousePressEvent(self, event): if self._carried is not None: self._carried.mousePressEvent(event) else: super(self.__class__, self).mousePressEvent(event) def mouseMoveEvent(self, event): if self._carried is not None: self._carried.mouseMoveEvent(event) else: super(self.__class__, self).mouseMoveEvent(event) def mouseReleaseEvent(self, event): if self._carried is not None: self._carried.mouseReleaseEvent(event) else: super(self.__class__, self).mouseReleaseEvent(event)
def buildDiagram(self): """ Public method to build the class shapes of the class diagram. The algorithm is borrowed from Boa Constructor. """ import Utilities.ModuleParser self.allClasses = {} self.allModules = {} try: extensions = Preferences.getPython("PythonExtensions") + \ Preferences.getPython("Python3Extensions") + ['.rb'] module = Utilities.ModuleParser.readModule( self.file, extensions=extensions, caching=False) except ImportError: ct = QGraphicsTextItem(None) ct.setHtml( self.tr("The module <b>'{0}'</b> could not be found.") .format(self.file)) self.scene.addItem(ct) return if self.file not in self.allModules: self.allModules[self.file] = [] routes = [] nodes = [] todo = [module.createHierarchy()] classesFound = False while todo: hierarchy = todo[0] for className in hierarchy: classesFound = True cw = self.__getCurrentShape(className) if not cw and className.find('.') >= 0: cw = self.__getCurrentShape(className.split('.')[-1]) if cw: self.allClasses[className] = cw if className not in self.allModules[self.file]: self.allModules[self.file].append(className) if cw and cw.noAttrs != self.noAttrs: cw = None if cw and not (cw.external and (className in module.classes or className in module.modules)): if cw.scene() != self.scene: self.scene.addItem(cw) cw.setPos(10, 10) if className not in nodes: nodes.append(className) else: if className in module.classes: # this is a local class (defined in this module) self.__addLocalClass( className, module.classes[className], 0, 0) elif className in module.modules: # this is a local module (defined in this module) self.__addLocalClass( className, module.modules[className], 0, 0, True) else: self.__addExternalClass(className, 0, 0) nodes.append(className) if hierarchy.get(className): todo.append(hierarchy.get(className)) children = list(hierarchy.get(className).keys()) for child in children: if (className, child) not in routes: routes.append((className, child)) del todo[0] if classesFound: self.__arrangeClasses(nodes, routes[:]) self.__createAssociations(routes) self.umlView.autoAdjustSceneSize(limit=True) else: ct = QGraphicsTextItem(None) ct.setHtml(self.tr( "The module <b>'{0}'</b> does not contain any classes.") .format(self.file)) self.scene.addItem(ct)
class MyWinMap(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.initWidget() # 初始化组件 self.initLayout() # 初始化布局 self.initWindow(800, 700) # 初始化窗口 self.initMap() # 初始化地图 self.initSerial(STR_COM) # 初始化串口 self.show() '''----------------------------------------------''' def initWidget(self): '''地图显示控件''' self.gscene_map = QGraphicsScene() self.gview_map = QGraphicsView(self.gscene_map) '''设定节点及阈值区''' self.chb_mark = QCheckBox('进入标记模式') self.chb_mark.toggle() self.sp_thre = QSpinBox() self.sp_thre.setRange(0, 10) # 设置上界和下界 '''数据显示区''' def initLayout(self): '''箱组声明''' self.gpbx_map = QGroupBox('地图', self) self.gpbx_mark_and_thre = QGroupBox('设定节点及阈值', self) self.gpbx_data = QGroupBox('数据', self) '''箱组布局类型''' self.lot_v_map = QVBoxLayout() self.lot_g_mark_and_thre = QGridLayout() self.lot_g_data = QGridLayout() self.lot_v_all = QVBoxLayout() '''箱组map布局设置''' self.lot_v_map.addWidget(self.gview_map, alignment=Qt.AlignHCenter) self.gpbx_map.setLayout(self.lot_v_map) '''箱组mark and thre布局设置''' # _ __ __ _ _ # |_|__|__|_|_| self.lot_g_mark_and_thre.addWidget(self.chb_mark, 0, 1, 1, 1, Qt.AlignCenter) self.lot_g_mark_and_thre.addWidget(self.sp_thre, 0, 3, 1, 1, Qt.AlignCenter) self.lot_g_mark_and_thre.setColumnStretch(0, 1) self.lot_g_mark_and_thre.setColumnStretch(1, 2) self.lot_g_mark_and_thre.setColumnStretch(2, 2) self.lot_g_mark_and_thre.setColumnStretch(3, 1) self.lot_g_mark_and_thre.setColumnStretch(4, 1) self.gpbx_mark_and_thre.setLayout(self.lot_g_mark_and_thre) '''箱组data布局设置''' for i in range(NODE_NUM): # 数据框 le_temp = QLineEdit('*') le_temp.setReadOnly(True) le_temp.setAlignment(Qt.AlignHCenter) self.lot_g_data.addWidget(le_temp, 0, i) for i in range(NODE_NUM): # 节点号框 lb_temp = QLabel('<div style="color:#d648ac;"><b>' + str(i + 1) + '</b></div>') lb_temp.setAlignment(Qt.AlignCenter) self.lot_g_data.addWidget(lb_temp, 1, i) self.gpbx_data.setLayout(self.lot_g_data) '''总布局设置''' self.lot_v_all.addWidget(self.gpbx_map) self.lot_v_all.addWidget(self.gpbx_mark_and_thre) self.lot_v_all.addWidget(self.gpbx_data) self.setLayout(self.lot_v_all) def initWindow(self, w, h): '''获取屏幕居中点信息''' center_point = QDesktopWidget().availableGeometry().center() self.center_point_x = center_point.x() self.center_point_y = center_point.y() '''窗口初始化''' self.setGeometry(0, 0, w, h) self.max_w = (self.center_point_x - 10) * 2 # 窗口允许的最大宽 self.max_h = (self.center_point_y - 20) * 2 # 窗口允许的最大高 self.setMaximumSize(self.max_w, self.max_h) # 防止窗口尺寸过大 self.moveToCenter(w, h) self.win_name = GUI_NAME # 窗口标题 self.setWindowTitle(self.win_name) def moveToCenter(self, w, h): '''窗口过大则先进行调整''' if (w > self.max_w) or (h > self.max_h): self.adjustSize() '''窗口居中''' topleft_point_x = (int)(self.center_point_x - w / 2) topleft_point_y = (int)(self.center_point_y - h / 2) self.move(topleft_point_x, topleft_point_y) def initMap(self): try: # 地图加载部分 self.pixmap_map = QPixmap('平面图_走廊_房间.png') if self.pixmap_map.isNull(): # 空图处理 self.initMapErrorHandle() return self.pixmap_map = self.pixmap_map.scaled(700, 600, Qt.KeepAspectRatio, Qt.SmoothTransformation) self.gscene_map.addPixmap(self.pixmap_map) # 固定边界以禁用滑动条 self.f_pixmap_map_x = float(self.pixmap_map.rect().x()) self.f_pixmap_map_y = float(self.pixmap_map.rect().y()) self.f_pixmap_map_w = float(self.pixmap_map.rect().width()) self.f_pixmap_map_h = float(self.pixmap_map.rect().height()) self.gview_map.setSceneRect(self.f_pixmap_map_x, self.f_pixmap_map_y, self.f_pixmap_map_w, self.f_pixmap_map_h) # 地图加载成功的标志位 self.b_map_loaded = True # 复选框信号连接 self.chb_mark.stateChanged.connect(self.updateMap) # view视图鼠标响应 self.gview_map.mousePressEvent = self.markMap w = self.width() h = self.height() self.moveToCenter(w, h) # 节点相关部分 self.node_list = [] # 存储节点的坐标及邻域信息 except Exception as e: print(e) self.initMapErrorHandle() def initMapErrorHandle(self): self.b_map_loaded = False self.text_warning = '<div style="font:20px;\ color:red;\ text-align:center;">\ <b>⚠ WARNING ⚠</b><br /><br />\ 地图加载出错啦<br /><br />\ ::>﹏<::\ </div>' self.gtext_warning = QGraphicsTextItem() self.gtext_warning.setHtml(self.text_warning) self.gscene_map.addItem(self.gtext_warning) def markMap(self, event): if self.b_map_loaded: if self.chb_mark.isChecked(): self.node_pos = self.gview_map.mapToScene(event.pos()) # 左键创建标记 if event.button() == Qt.LeftButton: if len(self.node_list) < NODE_NUM: _is_near_init = False # 标记模式下,初始化无近邻rssi _append_iter = [self.node_pos, _is_near_init] # 用list存储复合信息 self.node_list.append(_append_iter) # 绘图部分 self.drawNode(len(self.node_list), _append_iter[0], _append_iter[1]) # 右键回退标记 if event.button() == Qt.RightButton: if len(self.node_list) > 0: self.node_list.pop() self.gscene_map.clear() # 清空scene self.gscene_map.addPixmap(self.pixmap_map) # 重新加载地图 for i in range(len(self.node_list)): self.drawNode(i + 1, self.node_list[i][0], self.node_list[i][1]) def updateMap(self): if self.b_map_loaded: if not self.chb_mark.isChecked(): self.timer_map_refresh = QTimer(self) # 设定地图刷新定时器 self.timer_map_refresh.timeout.connect(self.redrawMap) self.timer_map_refresh.start(REFRESH_TIME_MS) # 设置刷新时间为100毫秒 def redrawMap(self): self.gscene_map.clear() # 清空scene self.gscene_map.addPixmap(self.pixmap_map) # 重新加载地图 for i in range(len(self.node_list)): self.drawNode(i + 1, self.node_list[i][0], self.node_list[i][1]) '''----------------------------------------------''' def drawNode(self, index, node_pos, is_near): # 样式设置 node_draw_r = 15 node_draw_x = node_pos.x() - node_draw_r node_draw_y = node_pos.y() - node_draw_r # node_draw_pos = QPointF(node_draw_x, node_draw_y) node_draw_pen = QPen(QColor(204, 47, 105), 3, Qt.SolidLine) node_draw_brush = QBrush(QColor(255, 110, 151), Qt.SolidPattern) # 正式画圆 self.gellipse_node = self.gscene_map.addEllipse( node_draw_x, node_draw_y, 2 * node_draw_r, 2 * node_draw_r, node_draw_pen, node_draw_brush) # 索引号 self.text_index = '<div style=\"font:26px;color:black;font-weight:900;\">' + \ str(index) + '</div>' self.gtext_index = QGraphicsTextItem() self.gtext_index.setHtml(self.text_index) self.gtext_index.setParentItem(self.gellipse_node) self.gtext_index.setPos(node_draw_x + 4, node_draw_y - 2) if is_near: # 若附近rssi判断有效 node_draw_r = 20 node_draw_x = node_pos.x() - node_draw_r node_draw_y = node_pos.y() - node_draw_r node_draw_pen = QPen(QColor(245, 229, 143), 10, Qt.DashLine) self.gscene_map.addEllipse(node_draw_x, node_draw_y, 2 * node_draw_r, 2 * node_draw_r, node_draw_pen) '''----------------------------------------------''' def initSerial(self, str_com): self.data_zigbee_list = [] # 初始化串口 self.ser_data = QSerialPort(STR_COM, baudRate=QSerialPort.Baud115200, readyRead=self.receive) self.ser_data.open(QIODevice.ReadWrite) if self.ser_data.isOpen(): print('串口开启成功!') else: print('串口打开失败……') @pyqtSlot() def receive(self): _data = self.ser_data.readLine().data() # 读取数据 if _data != b'': self.data_zigbee_list = [] # 清空数据 self.data = _data[0:2 * NODE_NUM].decode("gbk") # 存储数据 for i in range(len(self.data) // 2): # 每两位存储,用tuple存储,只读 data_iter = (self.data[2 * i:2 * i + 1], self.data[2 * i + 1:2 * i + 2]) self.data_zigbee_list.append(data_iter) # print('data_zigbee_list:', self.data_zigbee_list) self.updateSerial() else: print('串口接收内容为空!') def updateSerial(self): if not self.chb_mark.isChecked(): for i in range(NODE_NUM): if i < len(self.node_list): value_update = self.data_zigbee_list[i][1] # 更新节点列表 self.node_list[i][1] = (True if value_update == '1' else False) else: value_update = '*' self.lot_g_data.itemAt(i).widget().setText(value_update)