def Paint(self): scene = QGraphicsScene() scene.setBackgroundBrush(Qt.transparent) scene.addLine(5, 5, 5, 213, QPen(self.settings["axis"])) scene.addLine(2, 210, 210, 210, QPen(self.settings["axis"])) mod_num = int(self.ui.moduleNum.currentText()) max_sim = max(self.points_sim, key=lambda x: x[mod_num])[mod_num] max_mm = max(self.points_mm, key=lambda x: x[mod_num])[mod_num] max_time = max(max_mm, max_sim) for i in range(10): scene.addLine(4, 210 - (i + 1) * 20, 6, 210 - (i + 1) * 20, QPen(self.settings["axis"])) font = QFont() font.setPointSize(6) if int(0.1*max_time*(i + 1)) != 0: t2 = scene.addText(str(int(0.1*max_time*(i + 1))), font) t2.setPos(-18, 200 - (i + 1) * 20) i = 1 x0 = 5 + 200 / self.num y0 = 210 - float(self.points_mm[0][mod_num]) / max_time * 200 for p in self.points_mm: x = 5 + i * 200 / self.num y = 210 - float(p[mod_num])/max_time * 200 scene.addLine(x0, y0, x, y, QPen(self.settings["mm"])) scene.addLine(x - 2, y - 2, x + 2, y + 2, QPen(self.settings["mm"])) scene.addLine(x + 2, y - 2, x - 2, y + 2, QPen(self.settings["mm"])) x0 = x y0 = y i += 1 i = 1 x0 = 5 + 200 / self.num y0 = 210 - float(self.points_sim[0][mod_num]) / max_time * 200 for p in self.points_sim: x = 5 + i * 200 / self.num y = 210 - float(p[mod_num])/max_time * 200 scene.addLine(x0, y0, x, y, QPen(self.settings["sim"])) scene.addLine(x - 2, y - 2, x + 2, y + 2, QPen(self.settings["sim"])) scene.addLine(x + 2, y - 2, x - 2, y + 2, QPen(self.settings["sim"])) x0 = x y0 = y i += 1 self.ui.graph.setScene(scene) self.ui.table.setRowCount(len(self.simplesystems)) self.simplesystems.sort(key = lambda x: x.simrel) for i in range(len(self.simplesystems)): self.ui.table.setItem(i, 0, QTableWidgetItem(self.simplesystems[i].id)) self.simplesystems.sort(key = lambda x: x.mmrel) for i in range(len(self.simplesystems)): self.ui.table.setItem(i, 1, QTableWidgetItem(self.simplesystems[i].id)) if self.ui.table.item(i, 0).text() != self.ui.table.item(i, 1).text(): self.ui.table.item(i, 0).setForeground(QBrush(QColor(255,0,0))) self.ui.table.item(i, 1).setForeground(QBrush(QColor(255,0,0))) else: self.ui.table.item(i, 0).setForeground(QBrush(QColor(0,255,0))) self.ui.table.item(i, 1).setForeground(QBrush(QColor(0,255,0))) self.simplesystems.sort(key = lambda x: x.rel) for i in range(len(self.simplesystems)): self.ui.table.setItem(i, 2, QTableWidgetItem(self.simplesystems[i].id))
class Level(QFrame): def __init__(self, parent): QFrame.__init__(self,parent) self.filename = QString() self.copiedItem = QByteArray() self.pasteOffset = 5 self.prevPoint = QPoint() self.addOffset = 5 self.screenSize = (320, 240) self.bgColor = QColor(244,244,244) '''0.Portrait 1.Landscape''' self.orientation = 0 self.currentItem = None self.printer = QPrinter(QPrinter.HighResolution) self.printer.setPageSize(QPrinter.Letter) '''1.Header''' self.levelBar = LevelBar(self) '''3.Tiler''' self.tiler = TileMapGrid(self)#Tiler(self) self.tiler.setMinimumHeight(100) #self.tiler.currentChanged.connect(self.closeDesigner) #self.tiler.setTabsClosable(True) #self.tiler.setTabShape(0) #self.tiler.hide() #self.levelLayout.addWidget(self.levelBar) '''2.view''' viewLayoutWidget = QFrame() viewLayoutWidget.setFrameShape(QFrame.StyledPanel) viewLayout = QHBoxLayout(viewLayoutWidget) #viewLayout.setMargin(10) self.view = LevelView(viewLayoutWidget) '''scene''' self.scene = QGraphicsScene(self) #self.scene.selectionChanged.connect(self.setConnect) #self.view.setStyleSheet("border: 1px solid red;") self.setBackgroundColor(self.bgColor) self.setScreenSize(self.screenSize) self.view.setScene(self.scene) self.view.setAlignment(Qt.AlignCenter) self.scroll_off = 1 self.setScrollBar() viewLayout.setMargin(0) viewLayout.addWidget(self.view) self.wrapped = [] # Needed to keep wrappers alive layout = QVBoxLayout(self) layout.addWidget(self.levelBar) layout.addWidget(viewLayoutWidget) layout.addWidget(self.tiler) layout.setMargin(0) self.setLayout(layout) def setScrollBar(self): if(self.scroll_off): self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scroll_off = 0 else: self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.scroll_off = 1 def setBackgroundColor(self,color): self.bgColor = color self.scene.setBackgroundBrush(QBrush(color)) def setScreenSize(self,size): self.screenSize = size self.setOrientation(self.orientation) def setOrientation(self,idx): self.orientation = idx if(idx == 0): self.view.setMaximumSize(self.screenSize[1], self.screenSize[0]) self.scene.setSceneRect(0, 0, self.screenSize[1], self.screenSize[0]) else: self.view.setMaximumSize(self.screenSize[0], self.screenSize[1]) self.scene.setSceneRect(0, 0, self.screenSize[0], self.screenSize[1]) def offerSave(self): if (Dirty and QMessageBox.question(self, "Designer - Unsaved Changes", "Save unsaved changes?", QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes): self.save() def position(self): point = self.mapFromGlobal(QCursor.pos()) if not self.view.geometry().contains(point): coord = random.randint(36, 144) point = QPoint(coord, coord) else: if point == self.prevPoint: point += QPoint(self.addOffset, self.addOffset) self.addOffset += 5 else: self.addOffset = 5 self.prevPoint = point return self.view.mapToScene(point) def selectedItem(self): items = self.scene.selectedItems() if len(items) == 1: return items[0] return None def current(self,item): self.scene.clearSelection() sceneItems = self.scene.items() for items in sceneItems: if(items != item): item.setSelected(False) if(item.isConnected()): self.propertyBar.disconnectText(item) item.setConnected(False) self.currentItem = item self.currentItem.setConnected(True) self.currentItem.setSelected(True) self.propertyBar.connectText(self.currentItem) self.propertyBar.initText(self.currentItem) def addText(self): item = TextItem("SomeText", self.position()) self.connect(item, SIGNAL("current"),self.current) self.connect(item, SIGNAL("copy"),self.copy) self.connect(item, SIGNAL("cut"),self.cut) self.connect(item, SIGNAL("paste"),self.paste) self.connect(item, SIGNAL("delete"),self.delete) #self.current(item) self.scene.addItem(item) def copy(self): item = self.selectedItem() if item is None: return self.copiedItem.clear() self.pasteOffset = 5 stream = QDataStream(self.copiedItem, QIODevice.WriteOnly) self.writeItemToStream(stream, item) def cut(self): item = self.selectedItem() if item is None: return self.copy() self.scene.removeItem(item) del item def paste(self): if self.copiedItem.isEmpty(): return stream = QDataStream(self.copiedItem, QIODevice.ReadOnly) item = self.readItemFromStream(stream, self.pasteOffset) self.pasteOffset += 5 #self.scene.addItem(item) def delete(self): items = self.scene.selectedItems() if (len(items) and QMessageBox.question(self, "Designer - Delete", "Delete {0} item{1}?".format(len(items), "s" if len(items) != 1 else ""), QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes): while items: item = items.pop() self.scene.removeItem(item) del item def readItemFromStream(self, stream, offset=0): type = QString() position = QPointF() matrix = QMatrix() stream >> type >> position >> matrix if offset: position += QPointF(offset, offset) if type == "Text": text = QString() font = QFont() stream >> text >> font self.scene.addItem(TextItem(text, position, font, matrix)) elif type == "Box": rect = QRectF() stream >> rect style = Qt.PenStyle(stream.readInt16()) self.scene.addItem(BoxItem(position, style, matrix)) elif type == "Pixmap": pixmap = QPixmap() stream >> pixmap self.scene.addItem(self.createPixmapItem(pixmap, position, matrix)) def writeItemToStream(self, stream, item): if isinstance(item, QGraphicsTextItem): stream << QString("Text") << item.pos() \ << item.matrix() << item.toPlainText() << item.font() elif isinstance(item, QGraphicsPixmapItem): stream << QString("Pixmap") << item.pos() \ << item.matrix() << item.pixmap() elif isinstance(item, BoxItem): stream << QString("Box") << item.pos() \ << item.matrix() << item.rect stream.writeInt16(item.style) def rotate(self): for item in self.scene.selectedItems(): item.rotate(30) def print_(self): dialog = QPrintDialog(self.printer) if dialog.exec_(): painter = QPainter(self.printer) painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.TextAntialiasing) self.scene.clearSelection() #self.removeBorders() self.scene.render(painter) #self.addBorders() def open(self): self.offerSave() path = (QFileInfo(self.filename).path() if not self.filename.isEmpty() else ".") fname = QFileDialog.getOpenFileName(self, "Page Designer - Open", path, "Page Designer Files (*.pgd)") if fname.isEmpty(): return self.filename = fname fh = None try: fh = QFile(self.filename) if not fh.open(QIODevice.ReadOnly): raise IOError, unicode(fh.errorString()) items = self.scene.items() while items: item = items.pop() self.scene.removeItem(item) del item self.addBorders() stream = QDataStream(fh) stream.setVersion(QDataStream.Qt_4_2) magic = stream.readInt32() if magic != MagicNumber: raise IOError, "not a valid .pgd file" fileVersion = stream.readInt16() if fileVersion != FileVersion: raise IOError, "unrecognised .pgd file version" while not fh.atEnd(): self.readItemFromStream(stream) except IOError, e: QMessageBox.warning(self, "Page Designer -- Open Error", "Failed to open {0}: {1}".format(self.filename, e)) finally:
class SelectByColorDlg(QDialog): def __init__(self, color, pieceItems): super().__init__() self._color = color self.resize(800, 800) self.scene = QGraphicsScene() layout = QVBoxLayout(self) self.view = _MyView(self) layout.addWidget(self.view) self.view.setScene(self.scene) self._view_widget = QGLWidget() self.view.setViewport(self._view_widget) self.view.setMouseTracking(True) gry = sum(color) / 3.0 if (gry < 168): bg = [224,]*3 else: bg = [128,]*3 self.scene.setBackgroundBrush(QBrush(QColor(*bg))) self.setup_scene(self.scene, pieceItems) d = self.piece_diag self.view.scale(60./d, 60./d) self._hover_radius = 1.0 self.selected_item_ids = [] def setup_scene(self, scene, pieceItems): root = self._rootitem = _RootItem(self._color) scene.addItem(root) # order piece items by color distance of the most similar color pairs = [(self._distance(item), item) for item in pieceItems] pairs.sort(key = lambda pair: pair[0]) phi_increment = 0.61803398874 * 2 * pi phi = 0.0 gamma = 1.0 # scale distance relative to average piece size if pairs: rect = pairs[0][1].boundingRect() diag = (rect.width()**2 + rect.height()**2) ** 0.5 # take the median piece idx = len(pairs) // 2 meddist = pairs[idx][0] meddist = max(meddist, .1) scale = 6*diag/(meddist) ** gamma self.piece_diag = diag else: scale = 1.0 self.piece_diag = 1.0 self.dist_and_id = [] for distance, orig_item in pairs: item = orig_item.copy_to(root, rotate=False) rr = item.boundingRect() item.setTransformOriginPoint(rr.center()) item.setRotation(item.angle_deg) item.setPos( scale * distance**gamma * cos(phi)-rr.width()*0.5, scale * distance**gamma * sin(phi)-rr.height()*0.5 ) self.dist_and_id.append((scale*distance**gamma, item.id)) phi += phi_increment self.updateSceneRect() def set_hover_radius(self, r): self._hover_radius = r self.selected_item_ids = [pair[1] for pair in self.dist_and_id if pair[0] < r] self._rootitem.sel_size = r self._rootitem.update() def confirm_result(self): self.accept() def _distance(self, pieceItem): color = self._color def dst(c1, c2): c1 = rgb2Lab(c1) c2 = rgb2Lab(c2) return sum((c1i-c2i)**2 for c1i, c2i in zip(c1, c2)) ** 0.5 if not pieceItem.dominant_colors: return 255.0 return min(dst(color, piececolor) for piececolor in pieceItem.dominant_colors[:4]) def updateSceneRect(self): r = self.scene.itemsBoundingRect() w, h = r.width(), r.height() a = .05 r = r.adjusted(-w*a, -h*a, w*a, h*a) self.scene.setSceneRect(r)
class ConductorGraph(Plugin): _deferred_fit_in_view=Signal() _client_list_update_signal=Signal() def __init__(self, context): self._context=context super(ConductorGraph, self).__init__(context) self.initialised=False self.setObjectName('Conductor Graph') self._current_dotcode=None self._node_items=None self._edge_items=None self._node_item_events={} self._edge_item_events={} self._client_info_list={} self._widget=QWidget() self.cur_selected_client_name = "" self.pre_selected_client_name = "" # factory builds generic dotcode items self.dotcode_factory=PydotFactory() # self.dotcode_factory=PygraphvizFactory() self.dotcode_generator=RosGraphDotcodeGenerator() self.dot_to_qt=DotToQtGenerator() self._graph=ConductorGraphInfo() self._graph._reg_event_callback(self._update_client_list) self._graph._reg_period_callback(self._set_network_statisics) rospack=rospkg.RosPack() ui_file=os.path.join(rospack.get_path('concert_conductor_graph'), 'ui', 'conductor_graph.ui') loadUi(ui_file, self._widget, {'InteractiveGraphicsView': InteractiveGraphicsView}) self._widget.setObjectName('ConductorGraphUi') if context.serial_number() > 1: self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number())) self._scene=QGraphicsScene() self._scene.setBackgroundBrush(Qt.white) self._widget.graphics_view.setScene(self._scene) #self._widget.refresh_graph_push_button.setIcon(QIcon.fromTheme('view-refresh')) self._widget.refresh_graph_push_button.setIcon(QIcon.fromTheme('window-new')) self._widget.refresh_graph_push_button.pressed.connect(self._update_conductor_graph) self._widget.highlight_connections_check_box.toggled.connect(self._redraw_graph_view) self._widget.auto_fit_graph_check_box.toggled.connect(self._redraw_graph_view) self._widget.fit_in_view_push_button.setIcon(QIcon.fromTheme('zoom-original')) self._widget.fit_in_view_push_button.pressed.connect(self._fit_in_view) self._deferred_fit_in_view.connect(self._fit_in_view, Qt.QueuedConnection) self._deferred_fit_in_view.emit() self._widget.tabWidget.currentChanged.connect(self._change_client_tab) self._client_list_update_signal.connect(self._update_conductor_graph) #rospy.Subscriber(concert_msgs.Strings.CONCERT_CLIENT_CHANGES, ConcertClients, self._update_client_list) context.add_widget(self._widget) def restore_settings(self, plugin_settings, instance_settings): self.initialised=True self._refresh_rosgraph() def shutdown_plugin(self): pass def _update_conductor_graph(self): # re-enable controls customizing fetched ROS graph self._refresh_rosgraph() self._update_client_tab() def _refresh_rosgraph(self): if not self.initialised: return self._update_graph_view(self._generate_dotcode()) def _generate_dotcode(self): return self.dotcode_generator.generate_dotcode(rosgraphinst=self._graph, dotcode_factory=self.dotcode_factory, orientation='LR' ) def _update_graph_view(self, dotcode): #if dotcode==self._current_dotcode: # return self._current_dotcode=dotcode self._redraw_graph_view() def _update_client_list(self): print "[conductor graph]: _update_client_list" self._client_list_update_signal.emit() pass def _start_service(self,node_name,service_name): service=self._graph._client_info_list[node_name]['gateway_name']+"/"+service_name info_text='' if service_name=='status': service_handle=rospy.ServiceProxy(service, Status) call_result=service_handle() info_text="<html>" info_text +="<p>-------------------------------------------</p>" info_text +="<p><b>application_namespace: </b>" +call_result.application_namespace+"</p>" info_text +="<p><b>remote_controller: </b>" +call_result.remote_controller+"</p>" info_text +="<p><b>application_status: </b>" +call_result.application_status+"</p>" info_text +="</html>" self._client_list_update_signal.emit() elif service_name=='platform_info': service_handle=rospy.ServiceProxy(service, GetPlatformInfo) call_result=service_handle() info_text = "<html>" info_text += "<p>-------------------------------------------</p>" info_text += "<p><b>rocon_uri: </b>" + call_result.platform_info.uri + "</p>" info_text += "<p><b>concert_version: </b>" + call_result.platform_info.version + "</p>" info_text += "</html>" self._client_list_update_signal.emit() elif service_name=='invite': #sesrvice service_handle=rospy.ServiceProxy(service, Invite) #dialog dlg=QDialog(self._widget) dlg.setMinimumSize(400,0) dlg.setMaximumSize(400,0) dlg.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Expanding) #dialog layout ver_layout=QVBoxLayout(dlg) ver_layout.setContentsMargins (0,0,0,0) dynamic_arg=[] dynamic_arg.append(DynamicArgumentLayer(ver_layout,'Remote Target Name',False,[('remote_target_name','string')])) dynamic_arg.append(DynamicArgumentLayer(ver_layout,'Application Namespace',False,[('application_namespace','string')])) dynamic_arg.append(DynamicArgumentLayer(ver_layout,'Cancel',False,[('cancel','bool')])) #button button_hor_sub_widget=QWidget() button_hor_layout=QHBoxLayout(button_hor_sub_widget) btn_call=QPushButton("Call") btn_cancel=QPushButton("cancel") btn_call.clicked.connect(lambda: dlg.done(0)) btn_call.clicked.connect(lambda : self._call_invite_service(service,service_handle,dynamic_arg)) btn_cancel.clicked.connect(lambda: dlg.done(0)) #add button button_hor_layout.addWidget(btn_call) button_hor_layout.addWidget(btn_cancel) #add button layout ver_layout.addWidget(button_hor_sub_widget) dlg.setVisible(True) elif service_name=='start_app': #sesrvice service_handle=rospy.ServiceProxy(service, StartApp) #dialog dlg=QDialog(self._widget) dlg.setMinimumSize(400,0) dlg.setMaximumSize(400,0) dlg.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Expanding) #dialog layout ver_layout=QVBoxLayout(dlg) ver_layout.setContentsMargins (0,0,0,0) dynamic_arg=[] dynamic_arg.append(DynamicArgumentLayer(ver_layout,'Name',False,[('name','string')])) dynamic_arg.append(DynamicArgumentLayer(ver_layout,'Remappings',True,[('remap to','string'),('remap from','string')])) #button button_hor_sub_widget=QWidget() button_hor_layout=QHBoxLayout(button_hor_sub_widget) btn_call=QPushButton("Call") btn_cancel=QPushButton("cancel") btn_call.clicked.connect(lambda: dlg.done(0)) btn_call.clicked.connect(lambda : self._call_start_app_service(service,service_handle,dynamic_arg)) btn_cancel.clicked.connect(lambda: dlg.done(0)) #add button button_hor_layout.addWidget(btn_call) button_hor_layout.addWidget(btn_cancel) #add button layout ver_layout.addWidget(button_hor_sub_widget) dlg.setVisible(True) elif service_name=='stop_app': service_handle=rospy.ServiceProxy(service, StopApp) call_result=service_handle() info_text="<html>" info_text +="<p>-------------------------------------------</p>" info_text +="<p><b>stopped: </b>" +str(call_result.stopped)+"</p>" info_text +="<p><b>error_code: </b>" +str(call_result.error_code)+"</p>" info_text +="<p><b>message: </b>" +call_result.message+"</p>" info_text +="</html>" self._update_client_tab() else: print 'has no service' return # display the result of calling service # get tab widget handle service_text_widget=None cur_tab_widget=self._widget.tabWidget.currentWidget() if cur_tab_widget==None: return object_name='services_text_widget' for k in cur_tab_widget.children(): if k.objectName().count(object_name) >=1 : service_text_widget=k break if service_text_widget==None: return service_text_widget.clear() service_text_widget.appendHtml(info_text) def _call_invite_service(self,service,service_handle,dynamic_arg): remote_target_name="" application_namespace="" cancel=False for k in dynamic_arg: if k.name=='Remote Target Name': item_widget=k._get_param_list()[0][0][1] remote_target_name=item_widget.toPlainText() elif k.name=='Application Namespace': item_widgetwidget=k._get_param_list()[0][0][1] application_namespace=item_widget.toPlainText() elif k.name=='Cancel': item_widget=k._get_param_list()[0][0][1] cancel=item_widget.itemData(item_widget.currentIndex()) #calling service call_result=service_handle(remote_target_name,application_namespace,cancel) #status update self._client_list_update_signal.emit() # display the result of calling service info_text="<html>" info_text +="<p>-------------------------------------------</p>" info_text +="<p><b>result: </b>" +str(call_result.result)+"</p>" info_text +="<p><b>error_code: </b>" +str(call_result.error_code)+"</p>" info_text +="<p><b>message: </b>" +call_result.message+"</p>" info_text +="</html>" # get tab widget handle service_text_widget=None cur_tab_widget=self._widget.tabWidget.currentWidget() if cur_tab_widget==None: return object_name='services_text_widget' for k in cur_tab_widget.children(): if k.objectName().count(object_name) >=1 : service_text_widget=k break if service_text_widget==None: return service_text_widget.clear() service_text_widget.appendHtml(info_text) pass def _call_start_app_service(self,service,service_handle,dynamic_arg): name="" remappings=[] for k in dynamic_arg: if k.name=='Name': name=k._get_param_list()[0][0][1].toPlainText() elif k.name=='Remappings': for l in k._get_param_list(): remap_to=l[0][1].toPlainText() remap_from=l[1][1].toPlainText() remappings.append(Remapping(remap_to,remap_from)) #calling service call_result=service_handle(name,remappings) #status update self._client_list_update_signal.emit() # display the result of calling service info_text = '' info_text="<html>" info_text +="<p>-------------------------------------------</p>" info_text +="<p><b>started: </b>" +str(call_result.started)+"</p>" info_text +="<p><b>error_code: </b>" +str(call_result.error_code)+"</p>" info_text +="<p><b>message: </b>" +call_result.message+"</p>" info_text +="<p><b>app_namespace: </b>" +call_result.app_namespace+"</p>" info_text +="</html>" # get tab widget handle service_text_widget=None cur_tab_widget=self._widget.tabWidget.currentWidget() if cur_tab_widget==None: return object_name='services_text_widget' for k in cur_tab_widget.children(): if k.objectName().count(object_name) >=1 : service_text_widget=k break if service_text_widget==None: return service_text_widget.clear() service_text_widget.appendHtml(info_text) pass def _update_client_tab(self): print '[_update_client_tab]' self.pre_selected_client_name = self.cur_selected_client_name self._widget.tabWidget.clear() for k in self._graph._client_info_list.values(): main_widget=QWidget() ver_layout=QVBoxLayout(main_widget) ver_layout.setContentsMargins (9,9,9,9) ver_layout.setSizeConstraint (ver_layout.SetDefaultConstraint) #button layout sub_widget=QWidget() sub_widget.setAccessibleName('sub_widget') btn_grid_layout=QGridLayout(sub_widget) btn_grid_layout.setContentsMargins (9,9,9,9) btn_grid_layout.setColumnStretch (1, 0) btn_grid_layout.setRowStretch (2, 0) invite_btn=QPushButton("Invite") platform_info_btn=QPushButton("Get Platform Info") status_btn=QPushButton("Get Status") start_app_btn=QPushButton("Start App") stop_app_btn=QPushButton("Stop App") invite_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"invite")) platform_info_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"platform_info")) status_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"status")) start_app_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"start_app")) stop_app_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"stop_app")) btn_grid_layout.addWidget(invite_btn) btn_grid_layout.addWidget(platform_info_btn) btn_grid_layout.addWidget(status_btn) btn_grid_layout.addWidget(start_app_btn) btn_grid_layout.addWidget(stop_app_btn) ver_layout.addWidget(sub_widget) #client information layout context_label = QLabel() context_label.setText("Client information") ver_layout.addWidget(context_label) app_context_widget=QPlainTextEdit() app_context_widget.setObjectName(k["name"]+'_'+'app_context_widget') app_context_widget.setAccessibleName('app_context_widget') app_context_widget.appendHtml(k["app_context"]) app_context_widget.setReadOnly(True) cursor = app_context_widget.textCursor() cursor.movePosition(QTextCursor.Start,QTextCursor.MoveAnchor,0) app_context_widget.setTextCursor(cursor) ver_layout.addWidget(app_context_widget) #service layout context_label = QLabel() context_label.setText("Service result") ver_layout.addWidget(context_label) services_text_widget=QPlainTextEdit() services_text_widget.setObjectName(k["name"]+'_'+'services_text_widget') services_text_widget.setReadOnly(True) cursor = services_text_widget.textCursor() cursor.movePosition(QTextCursor.Start,QTextCursor.MoveAnchor,0) services_text_widget.setTextCursor(cursor) ver_layout.addWidget(services_text_widget) # new icon path="" if k["is_new"]==True: path=os.path.join(os.path.dirname(os.path.abspath(__file__)),"../../resources/images/new.gif") #add tab self._widget.tabWidget.addTab(main_widget,QIcon(path), k["name"]); #set previous selected tab for k in range(self._widget.tabWidget.count()): tab_text=self._widget.tabWidget.tabText(k) if tab_text == self.pre_selected_client_name: self._widget.tabWidget.setCurrentIndex(k) def _change_client_tab(self,index): self.cur_selected_client_name = self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()) if self._widget.tabWidget.widget(index) !=None: for k in self._widget.tabWidget.widget(index).children(): if k.objectName().count("services_text_widget"): k.clear() pass def _set_network_statisics(self): if self._edge_items == None: return else: for edge_items in self._edge_items.itervalues(): for edge_item in edge_items: edge_dst_name=edge_item.to_node._label.text() edge_item.setToolTip(str(self._graph._client_info_list[edge_dst_name]['conn_stats'])) def _redraw_graph_view(self): self._scene.clear() self._node_item_events={} self._edge_item_events={} self._node_items=None self._edge_items=None if self._widget.highlight_connections_check_box.isChecked(): highlight_level=3 else: highlight_level=1 highlight_level=3 if self._widget.highlight_connections_check_box.isChecked() else 1 # layout graph and create qt items (nodes, edges)=self.dot_to_qt.dotcode_to_qt_items(self._current_dotcode, highlight_level=highlight_level, same_label_siblings=True) self._node_items=nodes self._edge_items=edges # if we wish to make special nodes, do that here (maybe subclass GraphItem, just like NodeItem does) #node for node_item in nodes.itervalues(): # set the color of conductor to orange if node_item._label.text()==self._graph._concert_conductor_name: royal_blue=QColor(65, 105, 255) node_item._default_color=royal_blue node_item.set_color(royal_blue) # redefine mouse event self._node_item_events[node_item._label.text()]=GraphEventHandler(self._widget.tabWidget,node_item,node_item.mouseDoubleClickEvent); node_item.mouseDoubleClickEvent=self._node_item_events[node_item._label.text()].NodeEvent; self._scene.addItem(node_item) #edge for edge_items in edges.itervalues(): for edge_item in edge_items: #redefine the edge hover event self._edge_item_events[edge_item._label.text()]=GraphEventHandler(self._widget.tabWidget,edge_item,edge_item._label.hoverEnterEvent); edge_item._label.hoverEnterEvent =self._edge_item_events[edge_item._label.text()].EdgeEvent; #self._edge_item_events[edge_item._label.text()]=GraphEventHandler(self._widget.tabWidget,edge_item,edge_item.mouseDoubleClickEvent); #edge_item.mouseDoubleClickEvent=self._edge_item_events[edge_item._label.text()].EdgeEvent; edge_item.add_to_scene(self._scene) #set the color of node as connection strength one of red, yellow, green edge_dst_name=edge_item.to_node._label.text() if edge_dst_name in self._graph._client_info_list.keys(): connection_strength=self._graph._client_info_list[edge_dst_name]['connection_strength'] if connection_strength=='very_strong': green=QColor(0, 255, 0) edge_item._default_color=green edge_item.set_color(green) elif connection_strength=='strong': green_yellow=QColor(125, 255,0) edge_item._default_color=green_yellow edge_item.set_color(green_yellow) elif connection_strength=='normal': yellow=QColor(238, 238,0) edge_item._default_color=yellow edge_item.set_color(yellow) elif connection_strength=='weak': yellow_red=QColor(255, 125,0) edge_item._default_color=yellow_red edge_item.set_color(yellow_red) elif connection_strength=='very_weak': red=QColor(255, 0,0) edge_item._default_color=red edge_item.set_color(red) #set the tooltip about network information edge_item.setToolTip(str(self._graph._client_info_list[edge_dst_name]['conn_stats'])) self._scene.setSceneRect(self._scene.itemsBoundingRect()) if self._widget.auto_fit_graph_check_box.isChecked(): self._fit_in_view() def _fit_in_view(self): self._widget.graphics_view.fitInView(self._scene.itemsBoundingRect(), Qt.KeepAspectRatio)
class TreeDialog(QDialog): def __init__(self): import treedialog QDialog.__init__(self) self.ui = treedialog.Ui_Dialog() self.ui.setupUi(self) self.ui.draw_buton.clicked.connect(self.new_anim) self.scene = QGraphicsScene() self.ui.image.setScene(self.scene) self.ui.image.setRenderHints(QPainter.HighQualityAntialiasing) def get_params(self): params = dict() params["branch_split"] = self.ui.branch_split.value() params["branch_after_range"] = (self.ui.branch_after_min.value(), self.ui.branch_after_max.value()) params["branch_split_var"] = self.ui.branch_split_var.value() params["gravity"] = self.ui.gravity.value() params["down_die_probability"] = self.ui.down_die_probability.value() params["down_damping_x"] = self.ui.down_damping_x.value() params["down_damping_y"] = self.ui.down_damping_x.value() params["start_branches"] = self.ui.start_branches.value() params["keep_central"] = self.ui.keep_central.value() params["color"] = QColor(self.ui.r.value() * 255, self.ui.g.value() * 255, self.ui.b.value() * 255) params["color_speed"] = self.ui.color_speed.value() params["painter_thickness"] = self.ui.painter_thickness.value() params["painter_generations"] = self.ui.painter_generations.value() start_rand = [random.uniform(-1, 1) * self.ui.v_start_var.value() for i in range(2)] params["v_start"] = complex(self.ui.v_start_x.value()+start_rand[0], self.ui.v_start_y.value()+start_rand[1]) return params def new_anim(self): image = None painter_id = random.randint(0, 2**32) self.active_painer = painter_id index = 0 every = self.ui.repaint.value() self.scene.clear() tree_count = self.ui.tree_count.value() need_spacing = 65 used_locations = [] for tree_index in range(tree_count): z_range = 80 base_z = random.uniform(-z_range, z_range) def make_base(): return complex(10 + random.uniform(-350 + 150*tree_count, 350 + 150*tree_count), base_z) def closest_distance_to_used(base): return min([np.abs(np.real(base - item)) for item in used_locations]) base_location = make_base() while not len(used_locations) == 0 and closest_distance_to_used(base_location) < need_spacing: base_location = make_base() used_locations.append(base_location) scale = 1.0 + 0.75 * ((z_range - base_z) / (2*z_range)) ** 2 self.tree = Tree(self.get_params(), base_location=base_location, scale=scale) for iteration in self.tree.grow_iterations(self.ui.generations.value(), yield_every=every): self.tree.draw(self.scene, incremental=True) self.ui.progress.setText("Working ... displayed frame: {0}".format(index)) gradient = QLinearGradient(self.scene.itemsBoundingRect().topLeft(), self.scene.itemsBoundingRect().bottomLeft()) gradient.setColorAt(0.4, QColor(0, 0, 0)) gradient.setColorAt(0, QColor(25, 25, 25)) self.scene.setBackgroundBrush(QBrush(gradient)) self.ui.image.repaint() QApplication.processEvents() index += every if self.active_painer != painter_id: return self.ui.image.fitInView(self.scene.itemsBoundingRect(), 1) d = GrassDrawer(self.ui.image) d.draw_some_grass(150 + 75*tree_count) #self.ui.image.fitInView(self.scene.itemsBoundingRect(), 1) self.ui.progress.setText("Done. Displayed frame: {0}".format(index))
class View(QGraphicsView): TEXT_COLOR = QColor(1,1,1) BOLDISH = QFont("Times", 30, QFont.Bold) NORMALISH = QFont("Times", 30, QFont.Normal) def __init__(self): QGraphicsView.__init__(self) self.resize(1024, 768) self.qtscene = None self.references = [] def display_question(self, question, answers, selected_index = None, correct = None): self._init_scene() x = 50 y = 25 item = QGraphicsSimpleTextItem(question) item.setBrush(self.TEXT_COLOR) item.setFont(self.BOLDISH) item.setX(x) item.setY(y) self.qtscene.addItem(item) self.references.append(item) y += 75 for index, answer in enumerate(answers): index += 1 item = QGraphicsSimpleTextItem("%s) %s" % (index, answer)) item.setBrush(self.TEXT_COLOR) item.setFont(self.NORMALISH) item.setX(x) item.setY(y) item.setAcceptHoverEvents(True) self.qtscene.addItem(item) self.references.append(item) #TODO: do not register click but do show check or not if not selected_index: item.hoverEnterEvent = partial(self.on_hover_answer, item) item.hoverLeaveEvent = partial(self.on_unhover_answer, item) item.mousePressEvent = partial(self.on_click_answer, index) elif selected_index == index: if correct: item = QGraphicsSimpleTextItem(u"\u2713") item.setBrush(QBrush(QColor(0,150,0))) item.setX(0) else: item = QGraphicsSimpleTextItem("X") item.setBrush(QBrush(QColor(255,0,0))) item.setX(3) item.setFont(self.BOLDISH) item.setY(y) self.qtscene.addItem(item) self.references.append(item) y += 50 return x, y def display_answer(self, question, answers, correct_answer, description, selected_index, correct): x, y = self.display_question(question, answers, selected_index, correct) #TODO pass what to check and if right or wrong y += 50 item = QGraphicsSimpleTextItem("Correct Answer: %s" % correct_answer) item.setBrush(self.TEXT_COLOR) font = QFont(self.BOLDISH) font.setUnderline(True) item.setFont(font) item.setX(x) item.setY(y) self.qtscene.addItem(item) self.references.append(item) y += 60 item = QGraphicsSimpleTextItem(make_pretty(description, 55)) item.setBrush(self.TEXT_COLOR) item.setFont(self.NORMALISH) item.setX(x) item.setY(y) self.qtscene.addItem(item) self.references.append(item) item = QPushButton('Next') item.clicked.connect(self.on_next) item.setFont(self.BOLDISH) item.move(x+700, y) self.qtscene.addWidget(item) self.references.append(item) def _init_scene(self): self.qtscene = QGraphicsScene(self) self.qtscene.setSceneRect(QRectF(0, 0, 1000, 750)) brush = QBrush(QColor(240,245,250)) self.qtscene.setBackgroundBrush(brush) self.setScene(self.qtscene) self.references = [] def on_next(self, event): self.next() def on_hover_answer(self, item, event): item.setBrush(QBrush(QColor(100,1,1))) def on_unhover_answer(self, item, event): item.setBrush(self.TEXT_COLOR) def on_click_answer(self, answer_index, event): self.select_answer(answer_index) def keyPressEvent(self, ev): if ev.key() == Qt.Key_Escape: self.quit() def quit(self): qApp.quit()
class Window(QWidget): ''' The MainWindow widget ''' def __init__(self, game): super().__init__() self.game = game self.game.ui = self self.setWindowTitle('WordJuggler') self.resize(800, 600) self.setStyleSheet('QGroupBox { border:0; font:bold;' + 'padding:20px 10px; min-width:220px; }') self.board = BoardItem(game.width, game.height) self.rack = RackItem(game.rack_size, game.width, game.height) self.scene = QGraphicsScene() self.scene.setBackgroundBrush(QBrush(QColor('#f9ece0'))) self.scene.addItem(self.board) self.scene.addItem(self.rack) self.scene.setSceneRect(self.scene.itemsBoundingRect()) self.view = BoardView(self.scene, self) self.view.letterChanged.connect(self.letterChanged) self.ranking = QGroupBox('Rankings') self.rankings = QLabel() rankings = QVBoxLayout() rankings.addWidget(self.rankings) self.ranking.setLayout(rankings) self.statistic = QGroupBox('Statistics') self.statistics = QLabel() statistics = QVBoxLayout() statistics.addWidget(self.statistics) self.statistic.setLayout(statistics) self.move = QGroupBox('Last 10 Moves') self.moves = QLabel() moves = QVBoxLayout() moves.addWidget(self.moves) self.move.setLayout(moves) self.buttons = QVBoxLayout() self.buttons.setSpacing(3) self.continue_button = QPushButton('Place &Word') self.continue_button.setEnabled(False) self.continue_button.setFixedSize(130, 25) self.continue_button.clicked.connect(self.continueClicked) self.pass_button = QPushButton('&Pass') self.pass_button.setEnabled(False) self.pass_button.setFixedSize(130, 25) self.pass_button.clicked.connect(self.passClicked) self.exchange_button = QPushButton('&Exchange') self.exchange_button.setEnabled(False) self.exchange_button.setFixedSize(130, 25) self.exchange_button.clicked.connect(self.exchangeClicked) self.buttons.addWidget(self.exchange_button, alignment=Qt.AlignCenter) self.buttons.addWidget(self.pass_button, alignment=Qt.AlignCenter) self.buttons.addWidget(self.continue_button, alignment=Qt.AlignCenter) information = QVBoxLayout() information.setMargin(20) information.setSpacing(20) information.addWidget(self.ranking) information.addWidget(self.statistic) information.addWidget(self.move) information.addStretch() information.addLayout(self.buttons) layout = QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.view) layout.addLayout(information) self.setLayout(layout) self.show() for player in self.game.players: player.played_cb = self.playerDone self.playerNext() def update(self, *args, **kwargs): self.rankings.setText( '<br>'.join('%i. <font color=%s>%s</font> (%i points)' % (i + 1, player.color, player.name, player.score) for i,player in enumerate(sorted(self.game.players, reverse=True, key=attrgetter('score'))))) self.statistics.setText(('Total Players: %i\n' + 'Placed Words: %i\n' + 'Remaining Letters: %i') % (len(self.game.players), len(list(self.game.board.get_words())), self.game.letters.remaining_letters)) moves = [] for i,(player,move) in list(enumerate(self.game.moves))[-10:]: if move[0] == Player.PASS: desc = 'Pass' elif move[0] == Player.EXCHANGE_LETTERS: desc = 'Exchange (%s,%s)' % move[1:] else: desc = 'Word (%i,%i,%s,%s,%i)' % move[1:] moves.append('%i. <font color=%s>%s</font>' % (i + 1, player.color, desc)) self.moves.setText('<br>'.join(moves)) super().update(*args, **kwargs) def letterChanged(self): ''' As soon as a letter changes we need to en/disable all controls ''' self.exchange_button.setEnabled(False) self.exchange_button.setText('Exchange') if self.game.letters.remaining_letters >= self.game.rack_size: selected = ''.join(l.char for l in self.scene.items() if type(l) is LetterItem and l.selected) if selected: self.exchange_button.setText('Exchange: %s' % selected) self.exchange_button.setEnabled(True) self.pass_button.setEnabled(True) self.continue_button.setEnabled(True if self.board.validNewWord() else False) def playerNext(self): player = self.game.next_player() self.letterChanged() self.update() player.update_letters() self.rack.name = self.game.current_player.name self.rack.color = self.game.current_player.color for i,letter in enumerate(player.letters): item = LetterItem(letter, self.game.letters.get_score(letter), player.color) item.own(self.rack, i, move=False) self.scene.addItem(item) self.update() player.played_cb = self.playerDone player.play() def continueClicked(self): if type(self.game.current_player) is Human: self.game.current_player.continue_cb() def passClicked(self): if type(self.game.current_player) is Human: self.game.current_player.pass_cb() def exchangeClicked(self): if type(self.game.current_player) is Human: self.game.current_player.exchange_cb() def playerDone(self, player, move, *args): self.exchange_button.setEnabled(False) self.exchange_button.setText('Exchange') self.pass_button.setEnabled(False) self.continue_button.setEnabled(False) for item in self.scene.items(): if type(item) is LetterItem and not item.is_safe and \ not item.deleted: item.own(None) item.fade() for x,y,letter in self.game.board: if not self.board.getLetter(x, y): item = LetterItem(letter.char, self.game.letters.get_score(letter), letter.player.color, safe=True) item.own(self.board, x, y, move=False) self.scene.addItem(item) self.update() if self.game.state() == self.game.RUNNING: self.game.current_player.update_letters() self.playerNext() else: self.game.finish_score() self.update() self.gameOver() def getLetters(self, count, msg=''): print('random letters: %s' % self.game.get_letters_old(count)) while True: text,ok = QInputDialog.getText(self, 'New Letters', 'Player: <font color=%s>%s</font><br>' % ( self.game.current_player.color, self.game.current_player.name) + msg + 'Tell me %i new letters in order to continue..' % count) text = ''.join(filter(lambda x: x in self.game.letters.letters, text.lower())) if len(text) == count and all(self.game.letters.available(c) for c in text): return text def gameOver(self): winner = sorted(self.game.players, reverse=True, key=attrgetter('score'))[0] self.dialog = QMessageBox(QMessageBox.Information, 'Game Over', ('<b>Game Over!</b><br><br>The player ' + '<b><font color=%s>%s</font></b> has won!') % (winner.color, winner.name), QMessageBox.Ok, self) self.dialog.show()