def __undo_redo(self): """Undo list settings. + Undo stack. + Undo view widget. + Hot keys. """ self.command_stack = QUndoStack(self) self.command_stack.setUndoLimit(self.undo_limit_option.value()) self.undo_limit_option.valueChanged.connect( self.command_stack.setUndoLimit) self.command_stack.indexChanged.connect(self.command_reload) self.undo_view = QUndoView(self.command_stack) self.undo_view.setEmptyLabel("~ Start Pyslvs") self.undo_redo_layout.addWidget(self.undo_view) self.action_redo = self.command_stack.createRedoAction(self, "Redo") self.action_undo = self.command_stack.createUndoAction(self, "Undo") self.action_redo.setShortcuts([ QKeySequence("Ctrl+Shift+Z"), QKeySequence("Ctrl+Y"), ]) self.action_redo.setStatusTip("Backtracking undo action.") self.action_redo.setIcon(QIcon(QPixmap(":/icons/redo.png"))) self.action_undo.setShortcut("Ctrl+Z") self.action_undo.setStatusTip("Recover last action.") self.action_undo.setIcon(QIcon(QPixmap(":/icons/undo.png"))) self.menu_edit.addAction(self.action_undo) self.menu_edit.addAction(self.action_redo)
def build_actions(self): self.toolBar.addAction(QIcon(QPixmap(':/core/icons/open-icon.png')), "Openfile") self.toolBar.addAction(QIcon(QPixmap(':/core/icons/save-icon.png')), "Savefile") self.toolBar.addAction( QIcon(QPixmap(':/core/icons/Settings-icon.png')), "Setting") self.toolBar.addAction( QIcon(QPixmap(':/core/icons/Actions-process-stop-icon.png')), "Stop")
def __init__( self, vpoints: List[VPoint], vlinks: List[VLink], pos: bool, parent: QWidget, ): """Input data reference from main window. + Needs VPoints and VLinks information. + If row is false: Create action. """ super(EditPointDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) icon = self.windowIcon() self.link_icon = QIcon(QPixmap(":/icons/link.png")) self.vpoints = vpoints self.vlinks = vlinks vpoints_count = len(vpoints) for i, e in enumerate(color_names): self.color_box.insertItem(i, color_icon(e), e) for vlink in vlinks: self.noSelected.addItem(QListWidgetItem(self.link_icon, vlink.name)) if pos is False: self.name_box.addItem(icon, f'Point{vpoints_count}') self.name_box.setEnabled(False) self.color_box.setCurrentIndex(self.color_box.findText('Green')) else: for i in range(vpoints_count): self.name_box.insertItem(i, icon, f'Point{i}') self.name_box.setCurrentIndex(pos)
def __init__(self, points: List[VPoint], links: List[VLink], pos: bool = False, parent=None): super(EditPointDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) icon = self.windowIcon() self.LinkIcon = QIcon(QPixmap(":/icons/link.png")) self.points = points self.links = links for i, e in enumerate(colorName): self.Color.insertItem(i, colorIcons(e), e) for vlink in links: self.noSelected.addItem(QListWidgetItem(self.LinkIcon, vlink.name)) if pos is False: self.Point.addItem(icon, 'Point{}'.format(len(points))) self.Point.setEnabled(False) self.Color.setCurrentIndex(self.Color.findText('Green')) else: for i in range(len(points)): self.Point.insertItem(i, icon, 'Point{}'.format(i)) self.Point.setCurrentIndex(pos)
def __free_move(self): """Menu of free move mode.""" free_move_mode_menu = QMenu(self) def free_move_mode_func(j: int, icon_qt: QIcon): @Slot() def func() -> None: self.free_move_button.setIcon(icon_qt) self.main_canvas.set_free_move(j) self.entities_tab.setCurrentIndex(0) self.inputs_widget.variable_stop.click() return func for i, (text, icon, tip) in enumerate([ ("View mode", "free_move_off", "Disable free move mode."), ("Translate mode", "translate", "Edit by 2 DOF moving."), ("Rotate mode", "rotate", "Edit by 1 DOF moving."), ("Reflect mode", "reflect", "Edit by flip axis."), ]): action = QAction(QIcon(QPixmap(f":/icons/{icon}.png")), text, self) action.triggered.connect(free_move_mode_func(i, action.icon())) action.setShortcut(QKeySequence(f"Ctrl+{i + 1}")) action.setShortcutContext(Qt.WindowShortcut) action.setStatusTip(tip) free_move_mode_menu.addAction(action) if i == 0: self.free_move_disable = action self.free_move_button.setMenu(free_move_mode_menu) # "Link adjust" function self.link_free_move_confirm.clicked.connect( self.main_canvas.emit_free_move_all)
def __free_move(self): """Menu of free move mode.""" free_move_mode_menu = QMenu(self) def free_move_mode_func(j: int, icon_qt: QIcon): @pyqtSlot() def func(): self.free_move_button.setIcon(icon_qt) self.MainCanvas.setFreeMove(j) self.EntitiesTab.setCurrentIndex(0) self.InputsWidget.variable_stop.click() return func for i, (text, icon, tip) in enumerate(( ("View mode", "free_move_off", "Disable free move mode."), ("Translate mode", "translate", "Edit by 2 DOF moving."), ("Rotate mode", "rotate", "Edit by 1 DOF moving."), ("Reflect mode", "reflect", "Edit by flip axis."), )): action = QAction(QIcon(QPixmap(f":/icons/{icon}.png")), text, self) action.triggered.connect(free_move_mode_func(i, action.icon())) action.setShortcut(QKeySequence(f"Ctrl+{i + 1}")) action.setShortcutContext(Qt.WindowShortcut) action.setStatusTip(tip) free_move_mode_menu.addAction(action) if i == 0: self.free_move_disable = action self.free_move_button.setMenu(free_move_mode_menu) # Link free move by expression table. self.link_free_move_slider.sliderReleased.connect( self.MainCanvas.emit_free_move_all)
def __init__(self, vpoints: List[VPoint], vlinks: List[VLink], row: Union[int, bool], parent: QWidget): """Input data reference from main window. + Needs VPoints and VLinks information. + If row is false: Create action. """ super(EditLinkDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.vpoints = vpoints self.vlinks = vlinks icon = self.windowIcon() self.point_icon = QIcon(QPixmap(":/icons/bearing.png")) for i, e in enumerate(colorNames): self.color_box.insertItem(i, color_icon(e), e) for i in range(len(self.vpoints)): self.noSelected.addItem( QListWidgetItem(self.point_icon, f'Point{i}')) if row is False: self.name_box.addItem(icon, "New link") self.name_box.setEnabled(False) self.color_box.setCurrentIndex(self.color_box.findText('Blue')) else: for i, vlink in enumerate(self.vlinks): self.name_box.insertItem(i, icon, vlink.name) self.name_box.setCurrentIndex(row) self.name_edit.textChanged.connect(self.__is_ok) self.__is_ok()
def __addResult(self, result: Dict[str, Any]): """Add result items, except add to the list.""" item = QListWidgetItem(result['Algorithm']) interrupt = result['interrupted'] if interrupt == 'False': item.setIcon(QIcon(QPixmap(":/icons/task-completed.png"))) elif interrupt == 'N/A': item.setIcon(QIcon(QPixmap(":/icons/question-mark.png"))) else: item.setIcon(QIcon(QPixmap(":/icons/interrupted.png"))) text = "{} ({})".format( result['Algorithm'], "No interrupt." if interrupt == 'False' else "Interrupt at {}".format(interrupt)) if interrupt == 'N/A': text += "\n※Completeness is not clear." item.setToolTip(text) self.Result_list.addItem(item)
def __add_macro(self, name: str, code: Union[int, Hashable]): """Add macro button.""" for action in self.macros_toolbar.actions(): if action.text() == name: break else: action = self.macros_toolbar.addAction(QIcon(QPixmap(":icons/python.png")), name) action.triggered.connect(lambda: self.__exec_script(code))
def graph(G: Graph, width: int, engine: [str, Dict[int, Tuple[float, float]]], node_mode: bool = False, except_node: int = None) -> QIcon: """Draw a linkage graph.""" try: pos = engine_picker(G, engine, node_mode) except EngineError as e: raise e width_ = -inf for x, y in pos.values(): if abs(x) > width_: width_ = x if abs(y) > width_: width_ = y width_ *= 2 * 1.2 image = QImage(QSize(width_, width_), QImage.Format_ARGB32_Premultiplied) image.fill(Qt.transparent) painter = QPainter(image) painter.translate(image.width() / 2, image.height() / 2) pen = QPen() r = width_ / 50 pen.setWidth(r) painter.setPen(pen) if node_mode: for l1, l2 in G.edges: painter.drawLine(QPointF(pos[l1][0], -pos[l1][1]), QPointF(pos[l2][0], -pos[l2][1])) else: painter.setBrush(QBrush(QColor(226, 219, 190, 150))) for link in G.nodes: if link == except_node: continue #Distance sorted function from canvas painter.drawPolygon(*convex_hull([(pos[n][0], -pos[n][1]) for n, edge in edges_view(G) if link in edge])) for k, (x, y) in pos.items(): if node_mode: color = colorNum(len(list(G.neighbors(k))) - 1) else: if except_node in tuple(G.edges)[k]: color = colorQt('Green') else: color = colorQt('Blue') pen.setColor(color) painter.setPen(pen) painter.setBrush(QBrush(color)) painter.drawEllipse(QPointF(x, -y), r, r) painter.end() icon = QIcon(QPixmap.fromImage(image).scaledToWidth(width)) return icon
def __init__(self, parent: 'mw.MainWindow'): """Reference names: + IO functions from main window. + Table data from PMKS expression. + Graph data function from main window. """ super(StructureSynthesis, self).__init__(parent) self.setupUi(self) self.save_edges_auto_label.setStatusTip( self.save_edges_auto.statusTip()) # Function references self.outputTo = parent.outputTo self.saveReplyBox = parent.saveReplyBox self.inputFrom = parent.inputFrom self.jointDataFunc = parent.EntitiesPoint.dataTuple self.linkDataFunc = parent.EntitiesLink.dataTuple self.getGraph = parent.getGraph # Splitters self.splitter.setStretchFactor(0, 2) self.splitter.setStretchFactor(1, 15) # Answer list. self.answer: List[Graph] = [] # Signals self.NL_input.valueChanged.connect(self.__adjust_structure_data) self.NJ_input.valueChanged.connect(self.__adjust_structure_data) self.graph_engine.addItems(engines) self.structure_list.customContextMenuRequested.connect( self.__topologic_result_context_menu) """Context menu + Add to collections + Copy edges + Copy image """ self.pop_menu_topo = QMenu(self) self.add_collection = QAction( QIcon(QPixmap(":/icons/collections.png")), "Add to collections", self) self.copy_edges = QAction("Copy edges", self) self.copy_image = QAction("Copy image", self) self.pop_menu_topo.addActions( [self.add_collection, self.copy_edges, self.copy_image]) self.NL_input_old_value = 0 self.NJ_input_old_value = 0 self.clear()
def __init__(self, parent): super(NumberAndTypeSynthesis, self).__init__(parent) self.setupUi(self) self.outputTo = parent.outputTo self.saveReplyBox = parent.saveReplyBox self.inputFrom = parent.inputFrom self.splitter.setStretchFactor(0, 2) self.splitter.setStretchFactor(1, 15) self.answer = [] self.save_edges_auto_label.setStatusTip(self.save_edges_auto.statusTip()) self.NL_input.valueChanged.connect(self.adjust_NJ_NL_dof) self.NJ_input.valueChanged.connect(self.adjust_NJ_NL_dof) self.graph_engine.addItems(EngineList) self.graph_engine.setCurrentIndex(2) self.graph_link_as_node.clicked.connect(self.on_reload_atlas_clicked) self.graph_engine.currentIndexChanged.connect( self.on_reload_atlas_clicked ) self.Topologic_result.customContextMenuRequested.connect( self.Topologic_result_context_menu ) """Context menu + Add to collections + Copy edges + Copy image """ self.popMenu_topo = QMenu(self) self.add_collection = QAction( QIcon(QPixmap(":/icons/collections.png")), "Add to collections", self ) self.copy_edges = QAction("Copy edges", self) self.copy_image = QAction("Copy image", self) self.popMenu_topo.addActions([ self.add_collection, self.copy_edges, self.copy_image ]) self.jointDataFunc = parent.Entities_Point.data self.linkDataFunc = parent.Entities_Link.data self.clear()
def __init__(self, format_name: str, format_icon: str, assembly_description: str, frame_description: str, env: str, file_name: str, vpoints: Sequence[VPoint], v_to_slvs: Callable[[], Sequence[Tuple[int, int]]], parent: QWidget): """Comes in environment variable and workbook name.""" super(_OutputDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.setWindowTitle(f"Export {format_name} module project") self.setWindowIcon(QIcon(QPixmap(f":/icons/{format_icon}"))) self.assembly_label.setText(assembly_description) self.frame_label.setText(frame_description) self.path_edit.setPlaceholderText(env) self.filename_edit.setPlaceholderText(file_name) self.vpoints = vpoints self.v_to_slvs = v_to_slvs
def __init__(self, parent=None): super(Collections, self).__init__(parent) layout = QVBoxLayout(self) tabWidget = QTabWidget(self) layout.addWidget(tabWidget) self.setWindowIcon(QIcon(QPixmap(":/icons/collections.png"))) self.CollectionsStructure = CollectionsStructure(parent) self.CollectionsTriangularIteration = CollectionsTriangularIteration( parent) self.CollectionsTriangularIteration.addToCollection = self.CollectionsStructure.addCollection tabWidget.addTab(self.CollectionsStructure, self.CollectionsStructure.windowIcon(), "Structure") tabWidget.addTab(self.CollectionsTriangularIteration, self.CollectionsTriangularIteration.windowIcon(), "Triangular iteration") self.CollectionsStructure.triangle_button.clicked.connect( lambda: tabWidget.setCurrentIndex(1)) self.CollectionsStructure.layout_sender.connect( self.CollectionsTriangularIteration.setGraph)
def __init__(self, parent: QWidget): """Create two widget page and using main window to make their parent.""" super(Collections, self).__init__(parent) layout = QVBoxLayout(self) tab_widget = QTabWidget(self) layout.addWidget(tab_widget) self.setWindowIcon(QIcon(QPixmap(":/icons/collections.png"))) self.StructureWidget = StructureWidget(parent) self.TriangularIterationWidget = TriangularIterationWidget( self.StructureWidget.addCollection, parent) tab_widget.addTab(self.StructureWidget, self.StructureWidget.windowIcon(), "Structures") tab_widget.addTab(self.TriangularIterationWidget, self.TriangularIterationWidget.windowIcon(), "Triangular iteration") self.StructureWidget.triangle_button.clicked.connect( lambda: tab_widget.setCurrentIndex(1)) self.StructureWidget.layout_sender.connect( self.TriangularIterationWidget.setGraph)
def __add_result(self, result: Dict[str, Any]): """Add result items, except add to the list.""" item = QListWidgetItem(result['Algorithm']) interrupt = result['interrupted'] if interrupt == 'False': interrupt_icon = "task_completed.png" elif interrupt == 'N/A': interrupt_icon = "question.png" else: interrupt_icon = "interrupted.png" item.setIcon(QIcon(QPixmap(f":/icons/{interrupt_icon}"))) if interrupt == 'False': interrupt_text = "No interrupt." else: interrupt_text = f"Interrupt at: {interrupt}" text = f"{result['Algorithm']} ({interrupt_text})" if interrupt == 'N/A': text += "\n※Completeness is unknown." item.setToolTip(text) self.result_list.addItem(item)
def __init__(self, parent: MainWindowBase): """Create two widget page and using main window to make their parent.""" super(Collections, self).__init__(parent) layout = QVBoxLayout(self) self.tab_widget = QTabWidget(self) layout.addWidget(self.tab_widget) self.setWindowIcon(QIcon(QPixmap(":/icons/collections.png"))) self.structure_widget = StructureWidget(parent) self.configure_widget = ConfigureWidget( self.structure_widget.add_collection, parent) self.tab_widget.addTab(self.structure_widget, self.structure_widget.windowIcon(), "Structures") self.tab_widget.addTab(self.configure_widget, self.configure_widget.windowIcon(), "Configuration") self.structure_widget.configure_button.clicked.connect( lambda: self.tab_widget.setCurrentIndex(1)) self.structure_widget.layout_sender.connect( self.configure_widget.set_graph)
def __init__(self, Points, Links, pos=False, parent=None): super(edit_link_show, self).__init__(parent) self.setupUi(self) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.Points = Points self.Links = Links icon = self.windowIcon() self.PointIcon = QIcon(QPixmap(":/icons/bearing.png")) for i, e in enumerate(colorName()): self.Color.insertItem(i, colorIcons(e), e) for i in range(len(self.Points)): self.noSelected.addItem( QListWidgetItem(self.PointIcon, 'Point{}'.format(i))) if pos is False: self.Link.addItem(icon, "New link") self.Link.setEnabled(False) self.Color.setCurrentIndex(self.Color.findText('Blue')) else: for vlink in self.Links: self.Link.insertItem(i, icon, vlink.name) self.Link.setCurrentIndex(pos) self.name_edit.textChanged.connect(self.isOk) self.isOk()
def undo(self): """Create a new item and recover expression.""" item = QListWidgetItem(self.name) item.expr = self.mechanism item.setIcon(QIcon(QPixmap(":/icons/mechanism.png"))) self.widget.insertItem(self.row, item)
def to_graph( g: Graph, width: int, engine: Union[str, Pos], node_mode: bool, show_label: bool, monochrome: bool, *, except_node: Optional[int] = None ) -> QIcon: """Draw a generalized chain graph.""" pos: Pos = engine_picker(g, engine, node_mode) if not pos: pixmap = QPixmap(width, width) pixmap.fill(Qt.transparent) return QIcon(pixmap) width_bound = -float('inf') for x, y in pos.values(): if abs(x) > width_bound: width_bound = x if abs(y) > width_bound: width_bound = y width_bound *= 2.5 image = QImage( QSize(int(width_bound), int(width_bound)), QImage.Format_ARGB32_Premultiplied ) image.fill(Qt.transparent) painter = QPainter(image) painter.translate(image.width() / 2, image.height() / 2) pen = QPen() r = int(width_bound / 50) pen.setWidth(r) painter.setPen(pen) _font.setPixelSize(r * 6) painter.setFont(_font) # Draw edges. if node_mode: for l1, l2 in g.edges: if except_node in {l1, l2}: pen.setColor(Qt.gray) else: pen.setColor(Qt.black) painter.setPen(pen) painter.drawLine( QPointF(pos[l1][0], -pos[l1][1]), QPointF(pos[l2][0], -pos[l2][1]) ) else: if monochrome: color = QColor(Qt.darkGray) else: color = QColor(226, 219, 190) color.setAlpha(150) painter.setBrush(QBrush(color)) for link in g.nodes: if link == except_node: pen.setColor(Qt.gray) else: pen.setColor(Qt.black) painter.setPen(pen) painter.drawPolygon(*convex_hull([ (pos[n][0], -pos[n][1]) for n, edge in edges_view(g) if link in edge ], as_qpoint=True)) # Draw nodes. for k, (x, y) in pos.items(): if node_mode: color = color_num(len(list(g.neighbors(k))) - 1) if k == except_node: color.setAlpha(150) else: if monochrome: color = Qt.black elif except_node in dict(edges_view(g))[k]: color = color_qt('Green') else: color = color_qt('Blue') pen.setColor(color) painter.setPen(pen) painter.setBrush(QBrush(color)) point = QPointF(x, -y) painter.drawEllipse(point, r, r) if show_label: pen.setColor(Qt.darkMagenta) painter.setPen(pen) painter.drawText(point, str(k)) painter.end() return QIcon(QPixmap.fromImage(image).scaledToWidth(width))
def __init__(self, id_int: int, parent: QWidget): super(LoadCommitButton, self).__init__(QIcon(QPixmap(":icons/data_update.png")), f" # {id_int}", parent) self.setToolTip(f"Reset to commit # {id_int}.") self.id = id_int
def __set_chart(self, tab_name: str, pos_x: int, pos_y: int): """Setting charts by data index. pos_x / pos_y: [0], [1], [2] time_fitness: List[List[Tuple[gen, fitness, time]]] """ axis_x = QCategoryAxis() axis_y = QValueAxis() axis_x.setLabelsPosition(QCategoryAxis.AxisLabelsPositionOnValue) axis_x.setMin(0) axis_y.setTickCount(11) if self.__algorithm_data: # Just copy references from algorithm data. plot = [data['time_fitness'] for data in self.__algorithm_data] # X max. max_x = int(max([max([tnf[pos_x] for tnf in data]) for data in plot]) * 100) axis_x.setMax(max_x) i10 = int(max_x / 10) if i10: for i in range(0, max_x + 1, i10): axis_x.append(str(i / 100), i) else: for i in range(0, 1000, 100): axis_x.append(str(i / 100), i) # Y max. max_y = max(max([tnf[pos_y] for tnf in data]) for data in plot) + 10 else: plot = None # Y max. max_y = 100 max_y -= max_y % 10 axis_y.setRange(0., max_y) chart = DataChart(self.__title, axis_x, axis_y) # Append data set. for i, data in enumerate(self.__algorithm_data): line = QLineSeries() scatter = QScatterSeries() line.setName(f"{i}: {data['Algorithm']}") scatter.setMarkerSize(7) scatter.setColor(QColor(110, 190, 30)) for e in plot[self.__algorithm_data.index(data)]: y = e[pos_y] x = e[pos_x] * 100 line.append(QPointF(x, y)) scatter.append(QPointF(x, y)) for series in (line, scatter): chart.addSeries(series) series.attachAxis(axis_x) series.attachAxis(axis_y) chart.legend().markers(scatter)[0].setVisible(False) # Add chart into tab widget widget = QWidget() self.tabWidget.addTab(widget, QIcon(), tab_name) layout = QVBoxLayout(widget) layout.setContentsMargins(2, 2, 2, 2) chart_view = QChartView(chart) chart_view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) layout.addWidget(chart_view)
def setChart(self, tabName: str, posX: int, posY: int): '''Setting charts by data index. posX / posY: [0] / [1] / [2] TimeAndFitness: List[List[Tuple[gen, fitness, time]]] ''' if self.mechanism_data: if type(self.mechanism_data[0]['TimeAndFitness'][0]) == float: TimeAndFitness = [[ (data['lastGen'] * i / len(data['TimeAndFitness']), Tnf, 0) for i, Tnf in enumerate(data['TimeAndFitness']) ] for data in self.mechanism_data] else: #Just copy from mechanism_data TimeAndFitness = [[Tnf for Tnf in data['TimeAndFitness']] for data in self.mechanism_data] axisX = QCategoryAxis() axisY = QValueAxis() axisX.setLabelsPosition(QCategoryAxis.AxisLabelsPositionOnValue) axisX.setMin(0) axisY.setTickCount(11) #X maxima if self.mechanism_data: maximaX = int( max([ max([Tnf[posX] for Tnf in data]) for data in TimeAndFitness ]) * 100) axisX.setMax(maximaX) i10 = int(maximaX / 10) if i10: for i in range(0, maximaX + 1, i10): axisX.append(str(i / 100), i) else: for i in range(0, 1000, 100): axisX.append(str(i / 100), i) #Y maxima if self.mechanism_data: maximaY = max( [max([Tnf[posY] for Tnf in data]) for data in TimeAndFitness]) + 10 else: maximaY = 100 maximaY -= maximaY % 10 axisY.setRange(0., maximaY) chart = DataChart(self.Title, axisX, axisY) #Append datasets for data in self.mechanism_data: line = QLineSeries() scatter = QScatterSeries() gen = data['lastGen'] Tnf = TimeAndFitness[self.mechanism_data.index(data)] points = Tnf[:-1] if Tnf[-1] == Tnf[-2] else Tnf line.setName("{}({} gen): {}".format(data['Algorithm'], gen, data['Expression'])) scatter.setMarkerSize(7) scatter.setColor(QColor(110, 190, 30)) for i, e in enumerate(points): y = e[posY] x = e[posX] * 100 line.append(QPointF(x, y)) scatter.append(QPointF(x, y)) for series in [line, scatter]: chart.addSeries(series) series.attachAxis(axisX) series.attachAxis(axisY) chart.legend().markers(scatter)[0].setVisible(False) #Add chart into tab widget widget = QWidget() self.tabWidget.addTab(widget, QIcon(), tabName) layout = QVBoxLayout(widget) layout.setContentsMargins(2, 2, 2, 2) chartView = QChartView(chart) chartView.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) layout.addWidget(chartView)
def __appearance(self): """Start up and initialize custom widgets.""" # Version label self.version_label.setText(f"v{_major}.{_minor}.{_build} ({_label})") # Entities tables. self.EntitiesTab.tabBar().setStatusTip( "Switch the tabs to change to another view mode.") self.EntitiesPoint = PointTableWidget(self.EntitiesPoint_widget) self.EntitiesPoint.cellDoubleClicked.connect(self.editPoint) self.EntitiesPoint.deleteRequest.connect(self.deletePoints) self.EntitiesPoint_layout.addWidget(self.EntitiesPoint) self.EntitiesLink = LinkTableWidget(self.EntitiesLink_widget) self.EntitiesLink.cellDoubleClicked.connect(self.editLink) self.EntitiesLink.deleteRequest.connect(self.deleteLinks) self.EntitiesLink_layout.addWidget(self.EntitiesLink) self.EntitiesExpr = ExprTableWidget(self.EntitiesExpr_widget) self.EntitiesExpr.reset.connect(self.link_free_move_widget.setEnabled) self.EntitiesExpr.free_move_request.connect(self.setLinkFreeMove) self.EntitiesExpr_layout.insertWidget(0, self.EntitiesExpr) # Link free mode slide bar. self.link_free_move_slider.valueChanged.connect( self.link_free_move_spinbox.setValue) self.link_free_move_spinbox.valueChanged.connect( self.link_free_move_slider.setValue) self.link_free_move_slider.rangeChanged.connect( self.link_free_move_spinbox.setRange) # Select all button on the Point and Link tab as corner widget. select_all_button = QPushButton() select_all_button.setIcon(QIcon(QPixmap(":/icons/select_all.png"))) select_all_button.setToolTip("Select all") select_all_button.setStatusTip("Select all item of point table.") @pyqtSlot() def table_select_all(): """Distinguish table by tab index.""" tables = (self.EntitiesPoint, self.EntitiesLink, self.EntitiesExpr) tables[self.EntitiesTab.currentIndex()].selectAll() select_all_button.clicked.connect(table_select_all) self.EntitiesTab.setCornerWidget(select_all_button) select_all_action = QAction("Select all point", self) select_all_action.triggered.connect(table_select_all) select_all_action.setShortcut("Ctrl+A") select_all_action.setShortcutContext(Qt.WindowShortcut) self.addAction(select_all_action) # QPainter canvas window self.MainCanvas = DynamicCanvas(self) self.EntitiesTab.currentChanged.connect( self.MainCanvas.setSelectionMode) @pyqtSlot(tuple, bool) def table_set_selection(selections: Tuple[int], key_detect: bool): """Distinguish table by tab index.""" tables = (self.EntitiesPoint, self.EntitiesLink, self.EntitiesExpr) tables[self.EntitiesTab.currentIndex()].setSelections( selections, key_detect) self.MainCanvas.selected.connect(table_set_selection) self.EntitiesPoint.rowSelectionChanged.connect( self.MainCanvas.setSelection) @pyqtSlot() def table_clear_selection(): """Distinguish table by tab index.""" tables = (self.EntitiesPoint, self.EntitiesLink, self.EntitiesExpr) tables[self.EntitiesTab.currentIndex()].clearSelection() self.MainCanvas.noselected.connect(table_clear_selection) clean_selection_action = QAction("Clean selection", self) clean_selection_action.triggered.connect(table_clear_selection) clean_selection_action.setShortcut("Esc") clean_selection_action.setShortcutContext(Qt.WindowShortcut) self.addAction(clean_selection_action) self.MainCanvas.free_moved.connect(self.setFreeMove) self.MainCanvas.alt_add.connect(self.qAddNormalPoint) self.MainCanvas.doubleclick_edit.connect(self.editPoint) self.MainCanvas.zoom_changed.connect(self.ZoomBar.setValue) self.MainCanvas.tracking.connect(self.setMousePos) self.canvasSplitter.insertWidget(0, self.MainCanvas) self.canvasSplitter.setSizes([600, 10, 30]) # Selection label on status bar right side. selection_label = SelectionLabel(self) self.EntitiesPoint.selectionLabelUpdate.connect( selection_label.updateSelectPoint) self.MainCanvas.browse_tracking.connect( selection_label.updateMousePosition) self.status_bar.addPermanentWidget(selection_label) # FPS label on status bar right side. fps_label = FPSLabel(self) self.MainCanvas.fps_updated.connect(fps_label.updateText) self.status_bar.addPermanentWidget(fps_label) # Inputs widget. self.InputsWidget = InputsWidget(self) self.inputs_tab_layout.addWidget(self.InputsWidget) self.free_move_button.toggled.connect( self.InputsWidget.variableValueReset) self.InputsWidget.aboutToResolve.connect(self.resolve) @pyqtSlot(tuple, bool) def inputs_set_selection(selections: Tuple[int], _: bool): """Distinguish table by tab index.""" self.InputsWidget.clearSelection() if self.EntitiesTab.currentIndex() == 0: self.InputsWidget.setSelection(selections) self.MainCanvas.selected.connect(inputs_set_selection) self.MainCanvas.noselected.connect(self.InputsWidget.clearSelection) self.InputsWidget.update_preview_button.clicked.connect( self.MainCanvas.updatePreviewPath) # Number and type synthesis. self.StructureSynthesis = StructureSynthesis(self) self.SynthesisTab.addTab(self.StructureSynthesis, self.StructureSynthesis.windowIcon(), "Structural") # Synthesis collections self.CollectionTabPage = Collections(self) self.SynthesisTab.addTab(self.CollectionTabPage, self.CollectionTabPage.windowIcon(), "Collections") self.StructureSynthesis.addCollection = ( self.CollectionTabPage.StructureWidget.addCollection) # Dimensional synthesis self.DimensionalSynthesis = DimensionalSynthesis(self) self.MainCanvas.set_target_point.connect( self.DimensionalSynthesis.setPoint) self.SynthesisTab.addTab(self.DimensionalSynthesis, self.DimensionalSynthesis.windowIcon(), "Dimensional") # File widget settings. self.DatabaseWidget = DatabaseWidget(self) self.SCMLayout.addWidget(self.DatabaseWidget) self.DatabaseWidget.commit_add.clicked.connect(self.commit) self.DatabaseWidget.branch_add.clicked.connect(self.commit_branch) self.action_stash.triggered.connect(self.DatabaseWidget.stash) # YAML editor. self.YamlEditor = YamlEditor(self) # Console dock will hide when startup. self.ConsoleWidget.hide() # Connect to GUI button switching. self.console_disconnect_button.setEnabled(not ARGUMENTS.debug_mode) self.console_connect_button.setEnabled(ARGUMENTS.debug_mode) # Splitter stretch factor. self.MainSplitter.setStretchFactor(0, 4) self.MainSplitter.setStretchFactor(1, 15) self.MechanismPanelSplitter.setSizes([500, 200]) self.synthesis_splitter.setSizes([100, 500]) # Enable mechanism menu actions when shows. self.menu_Mechanism.aboutToShow.connect(self.enableMechanismActions) # Start a new window. @pyqtSlot() def new_main_window(): run = self.__class__() run.show() self.action_new_window.triggered.connect(new_main_window)
def __appearance(self): """Start up and initialize custom widgets.""" # Version label self.version_label.setText(__version__) # Entities tables self.entities_tab.tabBar().setStatusTip( "Switch the tabs to change to another view mode.") self.entities_point = PointTableWidget(self.entities_point_widget) self.entities_point.cellDoubleClicked.connect(self.edit_point) self.entities_point.delete_request.connect(self.delete_selected_points) self.entities_point_layout.addWidget(self.entities_point) self.entities_link = LinkTableWidget(self.entities_link_widget) self.entities_link.cellDoubleClicked.connect(self.edit_link) self.entities_link.delete_request.connect(self.delete_selected_links) self.entities_link_layout.addWidget(self.entities_link) self.entities_expr = ExprTableWidget(self.EntitiesExpr_widget) self.entities_expr_layout.insertWidget(0, self.entities_expr) # Select all button on the Point and Link tab as corner widget. select_all_button = QPushButton() select_all_button.setIcon(QIcon(QPixmap(":/icons/select_all.png"))) select_all_button.setToolTip("Select all") select_all_button.setStatusTip("Select all item of point table.") @Slot() def table_select_all(): """Distinguish table by tab index.""" tables: List[BaseTableWidget] = [ self.entities_point, self.entities_link, self.entities_expr, ] tables[self.entities_tab.currentIndex()].selectAll() select_all_button.clicked.connect(table_select_all) self.entities_tab.setCornerWidget(select_all_button) select_all_action = QAction("Select all point", self) select_all_action.triggered.connect(table_select_all) select_all_action.setShortcut("Ctrl+A") select_all_action.setShortcutContext(Qt.WindowShortcut) self.addAction(select_all_action) # QPainter canvas window self.main_canvas = DynamicCanvas(self) select_tips = QLabel(self, Qt.ToolTip) self.entities_tab.currentChanged.connect( self.main_canvas.set_selection_mode) @Slot(QPoint, str) def show_select_tips(pos: QPoint, text: str): select_tips.setText(text) select_tips.move(pos - QPoint(0, select_tips.height())) select_tips.show() self.main_canvas.selected_tips.connect(show_select_tips) self.main_canvas.selected_tips_hide.connect(select_tips.hide) @Slot(tuple, bool) def table_set_selection(selections: Sequence[int], key_detect: bool): """Distinguish table by tab index.""" tables: List[BaseTableWidget] = [ self.entities_point, self.entities_link, self.entities_expr, ] tables[self.entities_tab.currentIndex()].set_selections( selections, key_detect) self.main_canvas.selected.connect(table_set_selection) self.entities_point.row_selection_changed.connect( self.main_canvas.set_selection) @Slot() def table_clear_selection(): """Distinguish table by tab index.""" tables: List[BaseTableWidget] = [ self.entities_point, self.entities_link, self.entities_expr, ] tables[self.entities_tab.currentIndex()].clearSelection() self.main_canvas.noselected.connect(table_clear_selection) clean_selection_action = QAction("Clean selection", self) clean_selection_action.triggered.connect(table_clear_selection) clean_selection_action.setShortcut("Esc") clean_selection_action.setShortcutContext(Qt.WindowShortcut) self.addAction(clean_selection_action) self.main_canvas.free_moved.connect(self.set_free_move) self.main_canvas.alt_add.connect(self.q_add_normal_point) self.main_canvas.doubleclick_edit.connect(self.edit_point) self.main_canvas.zoom_changed.connect(self.zoom_bar.setValue) self.main_canvas.tracking.connect(self.set_mouse_pos) self.canvas_splitter.insertWidget(0, self.main_canvas) self.canvas_splitter.setSizes([600, 10, 30]) # Selection label on status bar right side selection_label = SelectionLabel(self) self.entities_point.selectionLabelUpdate.connect( selection_label.update_select_point) self.main_canvas.browse_tracking.connect( selection_label.update_mouse_position) self.status_bar.addPermanentWidget(selection_label) # FPS label on status bar right side fps_label = FPSLabel(self) self.main_canvas.fps_updated.connect(fps_label.update_text) self.status_bar.addPermanentWidget(fps_label) # Inputs widget self.inputs_widget = InputsWidget(self) self.inputs_tab_layout.addWidget(self.inputs_widget) self.free_move_button.toggled.connect( self.inputs_widget.variable_value_reset) self.inputs_widget.about_to_resolve.connect(self.resolve) @Slot(tuple, bool) def inputs_set_selection(selections: Sequence[int], _: bool): """Distinguish table by tab index.""" self.inputs_widget.clear_selection() if self.entities_tab.currentIndex() == 0: self.inputs_widget.set_selection(selections) self.main_canvas.selected.connect(inputs_set_selection) self.main_canvas.noselected.connect(self.inputs_widget.clear_selection) self.inputs_widget.update_preview_button.clicked.connect( self.main_canvas.update_preview_path) # Number and type synthesis self.structure_synthesis = StructureSynthesis(self) self.synthesis_tab_widget.addTab(self.structure_synthesis, self.structure_synthesis.windowIcon(), "Structural") # Synthesis collections self.collection_tab_page = Collections(self) self.synthesis_tab_widget.addTab(self.collection_tab_page, self.collection_tab_page.windowIcon(), "Collections") self.structure_synthesis.addCollection = ( self.collection_tab_page.structure_widget.add_collection) # Dimensional synthesis self.dimensional_synthesis = DimensionalSynthesis(self) self.main_canvas.set_target_point.connect( self.dimensional_synthesis.set_point) self.synthesis_tab_widget.addTab( self.dimensional_synthesis, self.dimensional_synthesis.windowIcon(), "Dimensional") @Slot() def set_design_progress(): """Synthesis progress bar.""" pos = self.synthesis_tab_widget.currentIndex() if pos == 1: pos += self.collection_tab_page.tab_widget.currentIndex() elif pos == 2: pos += 1 self.synthesis_progress.setValue(pos) self.synthesis_tab_widget.currentChanged.connect(set_design_progress) self.collection_tab_page.tab_widget.currentChanged.connect( set_design_progress) # File widget settings self.database_widget = DatabaseWidget(self) self.vc_layout.addWidget(self.database_widget) self.database_widget.commit_add.clicked.connect(self.commit) self.database_widget.branch_add.clicked.connect(self.commit_branch) self.action_stash.triggered.connect(self.database_widget.stash) # YAML editor self.yaml_editor = YamlEditor(self) # Console dock will hide when startup self.console_widget.hide() # Connect to GUI button self.console_disconnect_button.setEnabled(not ARGUMENTS.debug_mode) self.console_connect_button.setEnabled(ARGUMENTS.debug_mode) # Splitter stretch factor self.main_splitter.setStretchFactor(0, 4) self.main_splitter.setStretchFactor(1, 15) self.mechanism_panel_splitter.setSizes([500, 200]) # Enable mechanism menu actions when shows. self.menu_mechanism.aboutToShow.connect(self.enable_mechanism_actions) @Slot() def new_main_window(): """Start a new window.""" run = self.__class__() run.show() self.action_new_window.triggered.connect(new_main_window)
def __init__(self, id, parent=None): super(LoadCommitButton, self).__init__(QIcon(QPixmap(":icons/dataupdate.png")), " #{}".format(id), parent) self.setToolTip("Reset to commit #{}.".format(id)) self.id = id
def file_icon(file_type: str) -> QIcon: """Return icon by file format.""" return QIcon(QPixmap(f":/icons/{file_type}.png"))
def redo(self): """Add mechanism expression to 'expr' attribute.""" item = QListWidgetItem(self.name) item.expr = self.mechanism item.setIcon(QIcon(QPixmap(":/icons/mechanism.png"))) self.widget.addItem(item)
def to_graph(graph: Graph, width: int, engine: Union[str, Dict[int, Tuple[float, float]]], node_mode: bool = False, except_node: int = None) -> QIcon: """Draw a generalized chain graph.""" pos: Pos = engine_picker(graph, engine, node_mode) width_bound = -float('inf') for x, y in pos.values(): if abs(x) > width_bound: width_bound = x if abs(y) > width_bound: width_bound = y width_bound *= 2.2 image = QImage(QSize(int(width_bound), int(width_bound)), QImage.Format_ARGB32_Premultiplied) image.fill(Qt.transparent) painter = QPainter(image) painter.translate(image.width() / 2, image.height() / 2) pen = QPen() r = width_bound / 50 pen.setWidth(int(r)) painter.setPen(pen) # Draw edges. if node_mode: for l1, l2 in graph.edges: if except_node in {l1, l2}: pen.setColor(color_qt('Gray')) else: pen.setColor(color_qt('Black')) painter.setPen(pen) painter.drawLine(QPointF(pos[l1][0], -pos[l1][1]), QPointF(pos[l2][0], -pos[l2][1])) else: painter.setBrush(QBrush(QColor(226, 219, 190, 150))) for link in graph.nodes: if link == except_node: pen.setColor(color_qt('Gray')) else: pen.setColor(color_qt('Black')) painter.setPen(pen) painter.drawPolygon(*convex_hull([(pos[n][0], -pos[n][1]) for n, edge in edges_view(graph) if link in edge], as_qpoint=True)) # Draw nodes. for k, (x, y) in pos.items(): if node_mode: color = color_num(len(list(graph.neighbors(k))) - 1) if k == except_node: color.setAlpha(150) else: if except_node in dict(edges_view(graph))[k]: color = color_qt('Green') else: color = color_qt('Blue') pen.setColor(color) painter.setPen(pen) painter.setBrush(QBrush(color)) painter.drawEllipse(QPointF(x, -y), r, r) painter.end() icon = QIcon(QPixmap.fromImage(image).scaledToWidth(width)) return icon
def colorIcons(name: str, size: int = 20) -> QIcon: """Get color block as QIcon by name.""" colorBlock = QPixmap(QSize(size, size)) colorBlock.fill(colorQt(name)) return QIcon(colorBlock)