def func_wrapper(plugin, workspace, *args, **kwargs): """ Wrapper function that, when called, causes the plugin to be loaded into a specific workspace. """ if workspace is None: return parent = workspace.main_tool_bar action = QAction(parent) action.setText(name) if icon is not None: action.setIcon(icon) if location is not None and isinstance(location, str): for level in location.split('/'): parent = self.get_action(parent, level) if isinstance(location, int): parent.insertAction(parent.actions()[location], action) else: parent.addAction(action) action.triggered.connect(lambda: func(plugin, *args, **kwargs))
def add(self, recent): remove_action = None for a in self.qactions: if a.recent == recent: remove_action = a break a = QAction("1: " + recent, self.filemenu, triggered=(lambda r=recent : lambda :self.open_wrapper(r))()) a.recent = recent self.filemenu.insertAction (self.next_element, a) self.qactions.insert(0, a) self.next_element = a if remove_action: self.qactions.remove(remove_action) self.filemenu.removeAction(remove_action) for i, a in enumerate(self.qactions, 1): a.setText("%d: %s" % (i, a.recent)) recent_lst = self.parent.load_setting('recent_lst', "").split(";") recent_lst.insert(0, recent) self.parent.save_setting('recent_lst', ";".join(recent_lst[:3])) if len(self.qactions) > self.max: a = self.qactions.pop() self.filemenu.removeAction(a)
def func_wrapper(plugin, workspace, *args, **kwargs): """ Wrapper function that, when called, causes the plugin to be loaded into a specific workspace. """ if workspace is None: return if workspace.current_plot_window is None: return parent = workspace.current_plot_window.tool_bar action = QAction(parent) action.setText(name) if icon is not None: action.setIcon(icon) if location is not None and isinstance(location, str): for level in location.split('/'): parent = self.get_action(parent, level) before_action = [x for x in parent.actions() if x.isSeparator()].pop(-2) parent.insertAction(before_action, action) action.triggered.connect(lambda: func(plugin, *args, **kwargs))
def _init_toolbar(self): a = QAction(getIcon('ruler'), 'Scale bar', self) a.setToolTip('Add scale bar') a.setCheckable(True) a.triggered.connect(self.scalebar) self._actions['scalebar'] = a self.insertAction(self._actions['configure_subplots'], a)
def _init_toolbar(self): a = QAction(getIcon('color-wheel'), 'Color bar', self) a.setToolTip('Add color bar') a.setCheckable(True) a.triggered.connect(self.colorbar) self._actions['colorbar'] = a self.insertAction(self._actions['configure_subplots'], a)
def _init_toolbar(self): a = QAction(getIcon('snap'), 'Snap', self) a.setCheckable(True) a.setToolTip('Snap to data') a.triggered.connect(self.snap) self._actions['snap'] = a self.insertAction(self._actions['pan'], a)
def __init__(self, parent, filemenu, open_func, next_element, max=10): self.parent = parent self.filemenu = filemenu self.open_func = open_func self.next_element = next_element self.max = max self.qactions = [] for i, recent in enumerate([r for r in self.parent.load_setting('recent_lst', "").split(";") if r], 1): a = QAction("%d: %s" % (i, recent), self.filemenu, triggered=(lambda r=recent : lambda :self.open_wrapper(r))()) a.recent = recent self.qactions.append(a) self.filemenu.insertAction (self.next_element, a) if self.qactions: self.next_element = self.qactions[0]
def help_menu(): """Create help submenu""" self.help_sub_menu = self.menubar.addMenu('Help') self.about_action = QAction('About', self) self.about_action.setStatusTip('About the application.') self.about_action.setShortcut('CTRL+H') self.about_action.triggered.connect(self.about_dialog.exec_) self.help_sub_menu.addAction(self.about_action)
def file_menu(): """Create a file submenu""" self.file_sub_menu = self.menubar.addMenu('File') self.open_action = QAction('Open File', self) self.open_action.setStatusTip('Open a new design') self.open_action.setShortcut('CTRL+O') # self.open_action.triggered.connect(self.open_file) self.exit_action = QAction('Exit', self) self.exit_action.setStatusTip('Exit the application.') self.exit_action.setShortcut('CTRL+Q') self.exit_action.triggered.connect(QApplication.quit) self.file_sub_menu.addAction(self.open_action) self.file_sub_menu.addAction(self.exit_action)
def _init_menu_buttons(self): """ Add the two menu buttons to the tool bar. Currently two are defined: View - for changing the view of the active window Data Processing - for applying a data processing step to the data. :return: """ self._option_buttons = [ self.ui.view_option_button, self.ui.cube_option_button ] # Create the View Menu view_menu = self._dict_to_menu(OrderedDict([ ('Hide Axes', ['checkable', self._toggle_viewer_axes]), ('Hide Toolbars', ['checkable', self._toggle_toolbars]), ('Hide Spaxel Value Tooltip', ['checkable', self._toggle_hover_value]), ('Hide Stats', ['checkable', self._toggle_stats_display]), ('Flux Units', OrderedDict([ ('Convert Displayed Units', lambda: self._open_dialog('Convert Displayed Units', None)), ('Convert Data Values', lambda: self._open_dialog('Convert Data Values', None)), ]) ), ('Wavelength Units/Redshift', lambda: self._open_dialog('Wavelength Units/Redshift', None)) ])) # Add toggle RA-DEC format: format_menu = view_menu.addMenu("RA-DEC Format") format_action_group = QActionGroup(format_menu) self.ra_dec_format_menu = format_menu # Make sure to change all instances of the the names # of the formats if modifications are made to them. for format_name in ["Sexagesimal", "Decimal Degrees"]: act = QAction(format_name, format_menu) act.triggered.connect(self._toggle_all_coords_in_degrees) act.setActionGroup(format_action_group) act.setCheckable(True) act.setChecked(True) if format == "Sexagesimal" else act.setChecked(False) format_menu.addAction(act) self.ui.view_option_button.setMenu(view_menu) # Create the Data Processing Menu cube_menu = self._dict_to_menu(OrderedDict([ ('Collapse Cube', lambda: self._open_dialog('Collapse Cube', None)), ('Spatial Smoothing', lambda: self._open_dialog('Spatial Smoothing', None)), ('Moment Maps', lambda: self._open_dialog('Moment Maps', None)), ('Arithmetic Operations', lambda: self._open_dialog('Arithmetic Operations', None)) ])) self.ui.cube_option_button.setMenu(cube_menu)
def _dict_to_menu(self, menu_dict, menu_widget=None): '''Stolen shamelessly from specviz. Thanks!''' if not menu_widget: menu_widget = QMenu() for k, v in menu_dict.items(): if isinstance(v, dict): new_menu = menu_widget.addMenu(k) self._dict_to_menu(v, menu_widget=new_menu) else: act = QAction(k, menu_widget) if isinstance(v, list): if v[0] == 'checkable': v = v[1] act.setCheckable(True) act.setChecked(False) act.triggered.connect(v) menu_widget.addAction(act) return menu_widget
class SpyderAction(QAction): """Spyder QAction class wrapper to handle cross platform patches.""" def __init__(self, *args, **kwargs): """Spyder QAction class wrapper to handle cross platform patches.""" super(SpyderAction, self).__init__(*args, **kwargs) self._action_no_icon = None if sys.platform == 'darwin': self._action_no_icon = QAction(*args, **kwargs) self._action_no_icon.setIcon(QIcon()) self._action_no_icon.triggered.connect(self.triggered) self._action_no_icon.toggled.connect(self.toggled) self._action_no_icon.changed.connect(self.changed) self._action_no_icon.hovered.connect(self.hovered) else: self._action_no_icon = self def __getattribute__(self, name): """Intercept method calls and apply to both actions, except signals.""" attr = super(SpyderAction, self).__getattribute__(name) if hasattr(attr, '__call__') and name not in ['triggered', 'toggled', 'changed', 'hovered']: def newfunc(*args, **kwargs): result = attr(*args, **kwargs) if name not in ['setIcon']: action_no_icon = self.__dict__['_action_no_icon'] attr_no_icon = super(QAction, action_no_icon).__getattribute__(name) attr_no_icon(*args, **kwargs) return result return newfunc else: return attr @property def no_icon_action(self): """Return the action without an Icon.""" return self._action_no_icon
def create_menus(self): exit_action = QAction('&Exit', self) # exitAction = QtGui.QAction(QtGui.QIcon('exit.png'), '&Exit', self) exit_action.setShortcut('Ctrl+Q') exit_action.setStatusTip('Exit application') exit_action.triggered.connect(qApp.quit) menubar = self.menuBar() file_menu = menubar.addMenu('&File') open_menu = file_menu.addMenu('&Open') open_file_action = QAction('&File', self) open_file_action.triggered.connect(self.openFile) open_dir_action = QAction('&Directory', self) open_dir_action.triggered.connect(self.openDirDialog) open_menu.addAction(open_file_action) open_menu.addAction(open_dir_action) file_menu.addAction(exit_action)
def __init__(self, *args, **kwargs): QMainWindow.__init__(self, *args, **kwargs) QtGuiApplication.__init__(self, self) QtUI.__init__(self, self) self.menubar = self.menuBar() self.fileMenu = self.menubar.addMenu('&File') openAction = QAction(QIcon('open.png'), '&Open...', self) openAction.setShortcut('Ctrl+O') openAction.setStatusTip('Open...') openAction.triggered.connect(self.actionOpen) exitAction = QAction("&Exit", self, shortcut='Ctrl+Q', statusTip='Exit', triggered=app.exit) self.fileMenu.addAction(openAction) self.fileMenu.addSeparator() sep = self.fileMenu.addSeparator() self.fileMenu.addAction(exitAction) self.recentInMenu = RecentInMenu(self, self.fileMenu, self.open, sep) self.show()
def __init__(self, *args, **kwargs): """Spyder QAction class wrapper to handle cross platform patches.""" super(SpyderAction, self).__init__(*args, **kwargs) self._action_no_icon = None if sys.platform == 'darwin': self._action_no_icon = QAction(*args, **kwargs) self._action_no_icon.setIcon(QIcon()) self._action_no_icon.triggered.connect(self.triggered) self._action_no_icon.toggled.connect(self.toggled) self._action_no_icon.changed.connect(self.changed) self._action_no_icon.hovered.connect(self.hovered) else: self._action_no_icon = self
def set_context_menu_actions(self, table): """ Sets up the context menu actions for the table :type table: QTableView :param table: The table whose context menu actions will be set up. :param ws_read_function: The read function used to efficiently retrieve data directly from the workspace """ copy_action = QAction(self.COPY_ICON, "Copy", table) # sets the first (table) parameter of the copy action callback # so that each context menu can copy the data from the correct table decorated_copy_action_with_correct_table = partial(self.presenter.action_copy_cells, table) copy_action.triggered.connect(decorated_copy_action_with_correct_table) table.setContextMenuPolicy(Qt.ActionsContextMenu) table.addAction(copy_action) horizontalHeader = table.horizontalHeader() horizontalHeader.setContextMenuPolicy(Qt.ActionsContextMenu) horizontalHeader.setSectionResizeMode(QHeaderView.Fixed) copy_bin_values = QAction(self.COPY_ICON, "Copy", horizontalHeader) copy_bin_values.triggered.connect(partial(self.presenter.action_copy_bin_values, table)) plot_bin_action = QAction(self.GRAPH_ICON, "Plot bin (values only)", horizontalHeader) plot_bin_action.triggered.connect(partial(self.presenter.action_plot_bin, table)) plot_bin_with_errors_action = QAction(self.GRAPH_ICON, "Plot bin (values + errors)", horizontalHeader) plot_bin_with_errors_action.triggered.connect(partial(self.presenter.action_plot_bin_with_errors, table)) separator1 = QAction(horizontalHeader) separator1.setSeparator(True) horizontalHeader.addAction(copy_bin_values) horizontalHeader.addAction(separator1) horizontalHeader.addAction(plot_bin_action) horizontalHeader.addAction(plot_bin_with_errors_action) verticalHeader = table.verticalHeader() verticalHeader.setContextMenuPolicy(Qt.ActionsContextMenu) verticalHeader.setSectionResizeMode(QHeaderView.Fixed) copy_spectrum_values = QAction(self.COPY_ICON, "Copy", verticalHeader) copy_spectrum_values.triggered.connect( partial(self.presenter.action_copy_spectrum_values, table)) plot_spectrum_action = QAction(self.GRAPH_ICON, "Plot spectrum (values only)", verticalHeader) plot_spectrum_action.triggered.connect(partial(self.presenter.action_plot_spectrum, table)) plot_spectrum_with_errors_action = QAction(self.GRAPH_ICON, "Plot spectrum (values + errors)", verticalHeader) plot_spectrum_with_errors_action.triggered.connect( partial(self.presenter.action_plot_spectrum_with_errors, table)) separator1 = QAction(verticalHeader) separator1.setSeparator(True) verticalHeader.addAction(copy_spectrum_values) verticalHeader.addAction(separator1) verticalHeader.addAction(plot_spectrum_action) verticalHeader.addAction(plot_spectrum_with_errors_action)
def get_action(parent, level=None): """ Creates nested menu actions depending on the user-created plugin decorator location values. """ for action in parent.actions(): if action.text() == level: if isinstance(parent, QToolBar): button = parent.widgetForAction(action) button.setPopupMode(QToolButton.InstantPopup) elif isinstance(parent, QMenu): button = action if button.menu(): menu = button.menu() else: menu = QMenu(parent) button.setMenu(menu) return menu else: action = QAction(parent) action.setText(level) if isinstance(parent, QToolBar): parent.addAction(action) button = parent.widgetForAction(action) button.setPopupMode(QToolButton.InstantPopup) elif isinstance(parent, QMenu): parent.addAction(action) button = action menu = QMenu(parent) button.setMenu(menu) return menu
def __init__(self): super(TourTestWindow, self).__init__() self.setGeometry(300, 100, 400, 600) self.setWindowTitle('Exploring QMainWindow') self.exit = QAction('Exit', self) self.exit.setStatusTip('Exit program') # create the menu bar menubar = self.menuBar() file_ = menubar.addMenu('&File') file_.addAction(self.exit) # create the status bar self.statusBar() # QWidget or its instance needed for box layout self.widget = QWidget(self) self.button = QPushButton('test') self.button1 = QPushButton('1') self.button2 = QPushButton('2') effect = QGraphicsOpacityEffect(self.button2) self.button2.setGraphicsEffect(effect) self.anim = QPropertyAnimation(effect, to_binary_string("opacity")) self.anim.setStartValue(0.01) self.anim.setEndValue(1.0) self.anim.setDuration(500) lay = QVBoxLayout() lay.addWidget(self.button) lay.addStretch() lay.addWidget(self.button1) lay.addWidget(self.button2) self.widget.setLayout(lay) self.setCentralWidget(self.widget) self.button.clicked.connect(self.action1) self.button1.clicked.connect(self.action2) self.tour = AnimatedTour(self)
def __init__(self, parent=None): super(ManiWindow, self).__init__(parent) self.canvas = qtViewer3d(self) # self.setWindowTitle("pythonOCC-%s 3d viewer" % VERSION) self.canvas.InitDriver() bar = self.menuBar() file = bar.addMenu("&File") _new = QAction(QIcon('icons/exit.png'), '&New', self) _new.setStatusTip("New application") _new.triggered.connect(self.my_process) # self.connect(_new, SIGNAL("triggered()"), self.my_process) file.addAction(_new) _exit = QAction(QIcon('icons/exit.png'), '&Exit', self) _exit.setShortcut('Ctrl+Q') _exit.setStatusTip('Exit application') _exit.triggered.connect(qApp.quit) file.addAction(_exit) self.statusBar() self.setCentralWidget(self.canvas) self.resize(800, 600)
def __init__(self, rootnode: JsonNode, parent): super().__init__(parent) self.mainwindow = parent self.setModel(JsonDataModel(rootnode, self.mainwindow)) self.model().dataChanged.connect(self.data_changed) self.setItemDelegate(MyItemDelegate()) self.setDragDropMode(QTreeView.DragDrop) self.setDragEnabled(True) self.setAcceptDrops(True) self.setDropIndicatorShown(True) self.doubleClicked.connect(self.double_clicked) # context menu self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_contextmenu) # actions # properties action self.propertiesAction = QAction(self.tr("properties"), self) self.propertiesAction.setIcon(QIcon(pixmap("document_properties.png"))) self.propertiesAction.triggered.connect(self.show_properties) # edit action self.editAction = QAction(self.tr("edit value"), self) self.editAction.setShortcut("F2") self.editAction.setIcon(QIcon(pixmap("edit.png"))) self.editAction.triggered.connect(self.edit_value) # edit key action self.editkeyAction = QAction(self.tr("edit key"), self) self.editkeyAction.setIcon(QIcon(pixmap("kgpg_key1_kgpg.png"))) self.editkeyAction.triggered.connect(self.edit_key) # insert item action self.insertitemAction = QAction(self.tr("insert item"), self) self.insertitemAction.setIcon(QIcon(pixmap("list_add.png"))) self.insertitemAction.triggered.connect(self.insert_item) # insert node action self.insertnodeAction = QAction(self.tr("insert node"), self) self.insertnodeAction.setIcon(QIcon(pixmap("list_add.png"))) self.insertnodeAction.triggered.connect(self.insert_node) # remove item action self.removeitemAction = QAction(self.tr("remove"), self) self.removeitemAction.setIcon(QIcon(pixmap("list_remove"))) self.removeitemAction.triggered.connect(self.remove_item)
def create_action(parent, text, on_triggered=None, shortcut=None, shortcut_context=None, icon_name=None): """Create a QAction based on the give properties :param parent: The parent object :param text: Text string to display :param on_triggered: An optional slot to call on the triggered signal :param shortcut: An optional shortcut :param shortcut_context: An optional context for the supplied shortcut. Only applies if a shortcut has been given :param icon_name: The name of the qt awesome uri for an icon. :return: A new QAction object """ action = QAction(text, parent) if on_triggered is not None: action.triggered.connect(on_triggered) if shortcut is not None: action.setShortcut(shortcut) if shortcut_context is not None: action.setShortcutContext(shortcut_context) if icon_name is not None: action.setIcon(get_icon(icon_name)) return action
def _make_sort_button(self): """ Make the sort button, with separate groups for ascending and descending, sorting by name or last shown :return: The sort menu button """ sort_button = QPushButton("Sort") sort_menu = QMenu() ascending_action = QAction("Ascending", sort_menu, checkable=True) ascending_action.setChecked(True) ascending_action.toggled.connect(self.presenter.set_sort_order) descending_action = QAction("Descending", sort_menu, checkable=True) order_group = QActionGroup(sort_menu) order_group.addAction(ascending_action) order_group.addAction(descending_action) number_action = QAction("Number", sort_menu, checkable=True) number_action.setChecked(True) number_action.toggled.connect(lambda: self.presenter.set_sort_type(Column.Number)) name_action = QAction("Name", sort_menu, checkable=True) name_action.toggled.connect(lambda: self.presenter.set_sort_type(Column.Name)) last_active_action = QAction("Last Active", sort_menu, checkable=True) last_active_action.toggled.connect(lambda: self.presenter.set_sort_type(Column.LastActive)) sort_type_group = QActionGroup(sort_menu) sort_type_group.addAction(number_action) sort_type_group.addAction(name_action) sort_type_group.addAction(last_active_action) sort_menu.addAction(ascending_action) sort_menu.addAction(descending_action) sort_menu.addSeparator() sort_menu.addAction(number_action) sort_menu.addAction(name_action) sort_menu.addAction(last_active_action) sort_button.setMenu(sort_menu) return sort_button
def create_action(parent, text, shortcut=None, icon=None, tip=None, toggled=None, triggered=None, data=None, menurole=None, context=Qt.WindowShortcut): """Create a QAction""" action = QAction(text, parent) if triggered is not None: action.triggered.connect(triggered) if toggled is not None: action.toggled.connect(toggled) action.setCheckable(True) if icon is not None: if is_text_string(icon): icon = get_icon(icon) action.setIcon(icon) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if data is not None: action.setData(to_qvariant(data)) if menurole is not None: action.setMenuRole(menurole) # Workround for Mac because setting context=Qt.WidgetShortcut # there doesn't have any effect if sys.platform == 'darwin': action._shown_shortcut = None if context == Qt.WidgetShortcut: if shortcut is not None: action._shown_shortcut = shortcut else: # This is going to be filled by # main.register_shortcut action._shown_shortcut = 'missing' else: if shortcut is not None: action.setShortcut(shortcut) action.setShortcutContext(context) else: if shortcut is not None: action.setShortcut(shortcut) action.setShortcutContext(context) return action
class StructureSynthesis(QWidget, Ui_Form): """Number and type synthesis widget. Calculate the combinations of mechanism family and show the atlas. """ assortment: Dict[Assortment, List[Assortment]] answer: List[Graph] def __init__(self, parent: MainWindowBase): """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) header = self.link_assortment_list.header() header.setSectionResizeMode(QHeaderView.ResizeToContents) # Function references self.output_to = parent.output_to self.save_reply_box = parent.save_reply_box self.input_from_multiple = parent.input_from_multiple self.vpoints = parent.vpoint_list self.vlinks = parent.vlink_list self.get_graph = parent.get_graph self.prefer = parent.prefer self.add_collection = parent.collections.structure_widget.add_collection # Answer list self.assortment = {} self.answer = [] # 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.__structure_list_context_menu) # Context menu self.pop_menu_topo = QMenu(self) self.to_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.to_collection, self.copy_edges, self.copy_image, ]) self.nl_input_old_value = 0 self.nj_input_old_value = 0 self.clear() def clear(self) -> None: """Clear all sub-widgets.""" self.edges_text.clear() self.__clear_assortment() self.__clear_structure_list() self.nl_input.setValue(0) self.nj_input.setValue(0) self.nl_input_old_value = 0 self.nj_input_old_value = 0 self.dof.setValue(1) @Slot(name='on_assortment_clear_button_clicked') def __clear_assortment(self) -> None: """Clear the number synthesis list.""" self.link_assortment_list.clear() self.assortment.clear() @Slot(name='on_structure_list_clear_button_clicked') def __clear_structure_list(self) -> None: """Clear the structure list.""" self.answer.clear() self.structure_list.clear() self.time_label.setText("") @Slot(name='on_from_mechanism_button_clicked') def __from_mechanism(self) -> None: """From a generalized mechanism of main canvas.""" if self.vpoints and self.vlinks: graph, _, _, _, _, _ = self.get_graph() else: graph = Graph([]) if graph.edges: self.edges_text.setText(str(list(graph.edges))) else: self.edges_text.setText("") keep_dof_checked = self.keep_dof.isChecked() self.keep_dof.setChecked(False) self.nl_input.setValue(len(graph.vertices)) self.nj_input.setValue(len(graph.edges)) self.keep_dof.setChecked(keep_dof_checked) # Show attributes QMessageBox.information( self, "Generalization", f"Link assortment:\n{link_assortment(graph)}\n" f"Contracted link assortment:\n{contracted_link_assortment(graph)}" if graph.edges else "Is a empty graph.") def __adjust_structure_data(self) -> None: """Update NJ and NL values. If user don't want to keep the DOF: Change the DOF then exit. """ if not self.keep_dof.isChecked(): self.dof.setValue(3 * (self.nl_input.value() - 1) - 2 * self.nj_input.value()) return # N2: Get the user's adjusted value. # NL_func: Get the another value of parameters (N1) by degrees of freedom formula. # is_above: Is value increase or decrease? if self.sender() is self.nj_input: n2 = self.nj_input.value() def nl_func() -> float: return (self.dof.value() + 2 * n2) / 3 + 1 is_above = n2 > self.nj_input_old_value else: n2 = self.nl_input.value() def nl_func() -> float: return (3 * (n2 - 1) - self.dof.value()) / 2 is_above = n2 > self.nl_input_old_value n1 = nl_func() while not n1.is_integer(): n2 += 1 if is_above else -1 n1 = nl_func() if n1 == 0 or n2 == 0: break n1 = int(n1) n2 = int(n2) # Return the result values # + Value of widgets. # + Setting old value record. if self.sender() is self.nl_input: self.nj_input.setValue(n1) self.nl_input.setValue(n2) self.nj_input_old_value = n1 self.nl_input_old_value = n2 else: self.nj_input.setValue(n2) self.nl_input.setValue(n1) self.nj_input_old_value = n2 self.nl_input_old_value = n1 @Slot(name='on_number_synthesis_button_clicked') def __number_synthesis(self) -> None: """Synthesis of link assortment.""" self.__clear_assortment() nl = self.nl_input.value() nj = self.nj_input.value() dlg = SynthesisProgressDialog( "Link assortment", f"Number of links: {nl}\n" f"Number of joints: {nj}", 1, self) @Slot(dict) def update_result( assortment: Dict[Assortment, List[Assortment]]) -> None: """Update results.""" self.assortment.update(assortment) for la, cla_list in assortment.items(): la_item = QTreeWidgetItem([ ", ".join(f"NL{i + 2} = {a}" for i, a in enumerate(la)), "N/A" ]) for cla in cla_list: la_item.addChild( QTreeWidgetItem([ ", ".join(f"NC{i + 1} = {a}" for i, a in enumerate(cla)), "N/A" ])) self.link_assortment_list.addTopLevelItem(la_item) first_item = self.link_assortment_list.topLevelItem(0) self.link_assortment_list.setCurrentItem(first_item) dlg.deleteLater() work = LinkThread(nl, nj, dlg) work.progress_update.connect(dlg.setValue) work.size_update.connect(dlg.setMaximum) work.result.connect(update_result) dlg.show() work.start() def __set_time_count(self, t: float, count: int) -> None: """Set time and count digit to label.""" self.time_label.setText(f"{t:.04f} s ({count})") def __set_paint_time(self, t: float) -> None: """Set painting time of atlas.""" self.paint_time_label.setText(f"{t:.04f}s") @Slot(name='on_structure_synthesis_button_clicked') def __structure_synthesis(self) -> None: """Structural synthesis - find by contracted links.""" self.__clear_structure_list() item = self.link_assortment_list.currentItem() if item is None: self.__number_synthesis() item = self.link_assortment_list.currentItem() root = item.parent() if root is None: # Find by link assortment try: # Test assortment_eval(item.text(0)) except ValueError: return jobs = [item.child(i) for i in range(item.childCount())] else: # Find by contracted link assortment jobs = [item] self.__structural_combine(jobs) @Slot(name='on_structure_synthesis_all_button_clicked') def __structure_synthesis_all(self) -> None: """Structural synthesis - find all.""" self.__clear_structure_list() jobs = [] for i in range(self.link_assortment_list.topLevelItemCount()): root = self.link_assortment_list.topLevelItem(i) for j in range(root.childCount()): jobs.append(root.child(j)) self.__structural_combine(jobs) def __structural_combine(self, jobs: Sequence[QTreeWidgetItem]) -> None: """Structural combine by iterator.""" t0 = process_time() dlg = SynthesisProgressDialog("Structural Synthesis", f"Number of cases: {len(jobs)}", len(jobs), self) @Slot(QTreeWidgetItem, int) def update_count(item: QTreeWidgetItem, count: int) -> None: """Update the number of graphs.""" item.setText(1, f"{count}") @Slot(list) def update_result(answer: List[Graph]) -> None: """Update the result of atlas.""" self.answer = answer dlg.deleteLater() for i in range(self.link_assortment_list.topLevelItemCount()): root = self.link_assortment_list.topLevelItem(i) count = 0 for j in range(root.childCount()): item = root.child(j) try: count += int(item.text(1)) except ValueError: pass root.setText(1, f"{count}") self.__set_time_count(process_time() - t0, len(self.answer)) self.__reload_atlas() work = GraphThread(jobs, self.graph_degenerate.currentIndex(), dlg) work.count_update.connect(update_count) work.progress_update.connect(dlg.setValue) work.result.connect(update_result) dlg.show() work.start() @Slot(name='on_reload_atlas_clicked') @Slot(bool, name='on_graph_link_as_node_toggled') @Slot(bool, name='on_graph_show_label_toggled') @Slot(int, name='on_graph_engine_currentIndexChanged') def __reload_atlas(self, *_) -> None: """Reload the atlas.""" scroll_bar: QScrollBar = self.structure_list.verticalScrollBar() scroll_pos = scroll_bar.sliderPosition() index = self.structure_list.currentRow() self.structure_list.clear() if not self.answer: return dlg = SynthesisProgressDialog( "Structural Synthesis", f"Drawing atlas ({len(self.answer)}) ...", len(self.answer), self) dlg.show() t0 = process_time() for i, G in enumerate(self.answer): QCoreApplication.processEvents() if dlg.wasCanceled(): return if self.__draw_atlas(i, G): dlg.setValue(i + 1) else: break self.__set_paint_time(process_time() - t0) dlg.setValue(dlg.maximum()) dlg.deleteLater() scroll_bar.setSliderPosition(scroll_pos) self.structure_list.setCurrentRow(index) def __draw_atlas(self, i: int, g: Graph) -> bool: """Draw atlas and return True if done.""" item = QListWidgetItem(f"No. {i + 1}") item.setIcon( graph2icon(g, self.structure_list.iconSize().width(), self.graph_link_as_node.isChecked(), self.graph_show_label.isChecked(), self.prefer.monochrome_option, engine=self.graph_engine.currentText())) item.setToolTip( f"Edge Set: {list(g.edges)}\n" f"Link assortment: {link_assortment(g)}\n" f"Contracted Link assortment: {contracted_link_assortment(g)}\n" f"Degree code: {g.degree_code()}") self.structure_list.addItem(item) return True def __atlas_image(self, row: Optional[int] = None) -> QImage: """Capture a result item icon to image.""" if row is None: item = self.structure_list.currentItem() else: item = self.structure_list.item(row) return item.icon().pixmap(self.structure_list.iconSize()).toImage() @Slot(QPoint) def __structure_list_context_menu(self, point) -> None: """Context menu for the type synthesis results.""" index = self.structure_list.currentIndex().row() self.to_collection.setEnabled(index > -1) self.copy_edges.setEnabled(index > -1) self.copy_image.setEnabled(index > -1) action = self.pop_menu_topo.exec_( self.structure_list.mapToGlobal(point)) if not action: return clipboard = QApplication.clipboard() if action == self.to_collection: self.add_collection(self.answer[index].edges) elif action == self.copy_edges: clipboard.setText(str(self.answer[index].edges)) elif action == self.copy_image: # Turn the transparent background to white image1 = self.__atlas_image() image2 = QImage(image1.size(), image1.format()) image2.fill(Qt.white) painter = QPainter(image2) painter.drawImage(QPointF(0, 0), image1) painter.end() clipboard.setPixmap(QPixmap.fromImage(image2)) @Slot(name='on_expr_copy_clicked') def __copy_expr(self) -> None: """Copy expression button.""" string = self.edges_text.text() if string: QApplication.clipboard().setText(string) self.edges_text.selectAll() @Slot(name='on_expr_add_collection_clicked') def __add_collection(self) -> None: """Add this expression to collections widget.""" string = self.edges_text.text() if string: self.add_collection(eval(string)) @Slot(name='on_save_atlas_clicked') def __save_atlas(self) -> None: """Saving all the atlas to image file. We should turn transparent background to white first. Then using QImage class to merge into one image. """ count = self.structure_list.count() if count < 1: return lateral = self.__save_atlas_ask() if not lateral: return file_name = self.output_to("atlas image", qt_image_format) if not file_name: return width = self.structure_list.iconSize().width() image_main = QImage( QSize(lateral * width if count > lateral else count * width, ((count // lateral) + bool(count % lateral)) * width), self.__atlas_image(0).format()) image_main.fill(Qt.transparent) painter = QPainter(image_main) for row in range(count): image = self.__atlas_image(row) painter.drawImage( QPointF(row % lateral, row // lateral) * width, image) painter.end() pixmap = QPixmap.fromImage(image_main) pixmap.save(file_name) self.save_reply_box("Atlas", file_name) def __save_atlas_ask(self) -> int: """Ask when saving the atlas.""" lateral, ok = QInputDialog.getInt(self, "Atlas", "The number of lateral:", 5, 1) if not ok: return 0 return lateral @Slot(name='on_save_edges_clicked') def __save_edges(self) -> None: """Saving all the atlas to text file.""" file_name = "" count = self.structure_list.count() if count < 1: return if not file_name: file_name = self.output_to("atlas edges expression", ["Text file (*.txt)"]) if not file_name: return with open(file_name, 'w+', encoding='utf-8') as f: f.write('\n'.join(str(G.edges) for G in self.answer)) self.save_reply_box("edges expression", file_name) @Slot(name='on_edges2atlas_button_clicked') def __edges2atlas(self) -> None: """Turn the text files into a atlas image. This operation will load all edges to list widget first. """ file_names = self.input_from_multiple("edges data", ["Text file (*.txt)"]) if not file_names: return read_data = [] for file_name in file_names: with open(file_name, 'r', encoding='utf-8') as f: for line in f: read_data.append(line) answer = [] for edges in read_data: try: g = Graph(eval(edges)) except (SyntaxError, TypeError): QMessageBox.warning(self, "Wrong format", "Please check text format.") else: answer.append(g) if not answer: QMessageBox.information(self, "No data", "The graph data is empty.") return self.answer = answer self.__set_time_count(0, len(answer)) self.__reload_atlas() self.__save_atlas()
def print(self): action = QAction(self.app.ui.print_icon, "Print") action.setToolTip("Print") action.setStatusTip("Print, Shortcuts : Ctrl+P") action.setShortcuts(["Ctrl+P"]) return action
def exit(self): action = QAction(self.app.ui.exit_icon, "E&xit") action.setToolTip("Exit") action.setStatusTip("Exit, Shortcuts : Esc") action.setShortcuts(["Escape"]) return action
def _add_plugins_menu(self): """Add 'Plugins' menu to app menubar.""" self.plugins_menu = self.main_menu.addMenu('&Plugins') list_plugins_action = QAction("List Installed Plugins...", self._qt_window) list_plugins_action.setStatusTip('List installed plugins') list_plugins_action.triggered.connect(self._show_plugin_list) self.plugins_menu.addAction(list_plugins_action) pip_install_action = QAction("Install/Uninstall Package(s)...", self._qt_window) pip_install_action.triggered.connect(self._show_pip_install_dialog) self.plugins_menu.addAction(pip_install_action) order_plugin_action = QAction("Plugin Call Order...", self._qt_window) order_plugin_action.setStatusTip('Change call order for plugins') order_plugin_action.triggered.connect(self._show_plugin_sorter) self.plugins_menu.addAction(order_plugin_action) report_plugin_action = QAction("Plugin Errors...", self._qt_window) report_plugin_action.setStatusTip( 'Review stack traces for plugin exceptions and notify developers') report_plugin_action.triggered.connect(self._show_plugin_err_reporter) self.plugins_menu.addAction(report_plugin_action)
def _update_file_menu(self): """ Set up the File menu and update the menu with recent files """ self.file_menu.clear() newAction = QAction("&New Reduction...", self) newAction.setShortcut("Ctrl+N") newAction.setStatusTip("Start a new reduction") newAction.triggered.connect(self._new) openAction = QAction("&Open...", self) openAction.setShortcut("Ctrl+O") openAction.setStatusTip( "Open an XML file containing reduction parameters") openAction.triggered.connect(self._file_open) saveAsAction = QAction("Save as...", self) saveAsAction.setStatusTip("Save the reduction parameters to XML") saveAsAction.triggered.connect(self._save_as) saveAction = QAction("&Save...", self) saveAction.setShortcut("Ctrl+S") saveAction.setStatusTip("Save the reduction parameters to XML") saveAction.triggered.connect(self._save) exportAction = QAction("&Export...", self) exportAction.setShortcut("Ctrl+E") exportAction.setStatusTip("Export to python script for Mantid") exportAction.triggered.connect(self._export) quitAction = QAction("&Quit", self) quitAction.setShortcut("Ctrl+Q") quitAction.triggered.connect(self.close) self.file_menu.addAction(newAction) self.file_menu.addAction(openAction) self.file_menu.addAction(saveAction) self.file_menu.addAction(saveAsAction) self.file_menu.addAction(exportAction) self.file_menu.addSeparator() if self.general_settings.debug: clearAction = QAction("&Clear settings and quit", self) clearAction.setStatusTip( "Restore initial application settings and close the application" ) clearAction.triggered.connect(self._clear_and_close) self.file_menu.addAction(clearAction) self.file_menu.addAction(quitAction) # TOOLS menu instrAction = QAction("Change &instrument...", self) instrAction.setShortcut("Ctrl+I") instrAction.setStatusTip("Select a new instrument") instrAction.triggered.connect(self._change_instrument) debug_menu_item_str = "Turn debug mode ON" if self.general_settings.debug: debug_menu_item_str = "Turn debug mode OFF" debugAction = QAction(debug_menu_item_str, self) debugAction.setStatusTip(debug_menu_item_str) debugAction.triggered.connect(self._debug_mode) self.tools_menu.clear() self.tools_menu.addAction(instrAction) self.tools_menu.addAction(debugAction) recent_files = [] for fname in self._recent_files: if fname != self._filename and QFile.exists( fname) and fname not in recent_files: recent_files.append(fname) if len(recent_files) > 0: self.file_menu.addSeparator() for i, fname in enumerate(recent_files): action = QAction( "&%d %s" % (i + 1, QFileInfo(fname).fileName()), self) action.setData(fname) action.triggered.connect(self.open_file) self.file_menu.addAction(action)
class TourTestWindow(QMainWindow): """ """ sig_resized = Signal("QResizeEvent") sig_moved = Signal("QMoveEvent") def __init__(self): super(TourTestWindow, self).__init__() self.setGeometry(300, 100, 400, 600) self.setWindowTitle('Exploring QMainWindow') self.exit = QAction('Exit', self) self.exit.setStatusTip('Exit program') # create the menu bar menubar = self.menuBar() file_ = menubar.addMenu('&File') file_.addAction(self.exit) # create the status bar self.statusBar() # QWidget or its instance needed for box layout self.widget = QWidget(self) self.button = QPushButton('test') self.button1 = QPushButton('1') self.button2 = QPushButton('2') effect = QGraphicsOpacityEffect(self.button2) self.button2.setGraphicsEffect(effect) self.anim = QPropertyAnimation(effect, to_binary_string("opacity")) self.anim.setStartValue(0.01) self.anim.setEndValue(1.0) self.anim.setDuration(500) lay = QVBoxLayout() lay.addWidget(self.button) lay.addStretch() lay.addWidget(self.button1) lay.addWidget(self.button2) self.widget.setLayout(lay) self.setCentralWidget(self.widget) self.button.clicked.connect(self.action1) self.button1.clicked.connect(self.action2) self.tour = AnimatedTour(self) def action1(self): """ """ frames = get_tour('test') index = 0 dic = {'last': 0, 'tour': frames} self.tour.set_tour(index, dic, self) self.tour.start_tour() def action2(self): """ """ self.anim.start() def resizeEvent(self, event): """Reimplement Qt method""" QMainWindow.resizeEvent(self, event) self.sig_resized.emit(event) def moveEvent(self, event): """Reimplement Qt method""" QMainWindow.moveEvent(self, event) self.sig_moved.emit(event)
def rotate_right(self): action = QAction(self.app.ui.rotate_right_icon, "Rotate Clockwise") action.setToolTip("Rotate clockwise") action.setStatusTip("Rotate image clockwise, Shortcuts : Alt+Right") action.setShortcuts(["Alt+Right"]) return action
class SPToolBar(NavigationToolbar): def __init__(self, canvas, parent, coordinates=True): self._idPick = None self.point_cursor = None self.annotation = None self.line = None super(SPToolBar, self).__init__(canvas, parent, coordinates=True) def _init_toolbar(self): super(SPToolBar, self)._init_toolbar() self.logAction = QAction(QIcon(":/TSResource/images/log.png"), "Log", self) self.logAction.setToolTip("Logarithic axises") self.logAction.setCheckable(True) self.addAction(self.logAction) self.legendAction = QAction( QIcon(":/TSResource/images/legend_pick.png"), "Items", self) self.legendAction.setToolTip("Click legend to set item visible") self.legendAction.setCheckable(True) self.addAction(self.legendAction) self.annotationAction = QAction( QIcon(":/TSResource/images/tooltip.png"), "Annotation", self) self.annotationAction.setToolTip("Show annotation") self.annotationAction.setCheckable(True) self.addAction(self.annotationAction) self.logAction.triggered.connect(self._click_logAction) self.legendAction.triggered.connect(self._click_legendAction) self.annotationAction.triggered.connect(self._click_annotationAction) def _click_logAction(self, flag): for ax in self.canvas.figure.get_axes(): if flag: ax.set_xscale("log", nonposx='clip') ax.set_yscale("log", nonposy='clip') ax.relim() else: ax.set_xscale("linear") ax.set_yscale("linear") self.canvas.draw_idle() def _click_legendAction(self, flag): if flag: self.legend_pickable_connection() else: self.legend_pickable_disconnection() def _click_annotationAction(self, flag): if not flag and self.annotation: self.annotation.remove() self.annotation = None self.canvas.draw_idle() def legend_pickable_connection(self): if self._idPress is not None: self.canvas.mpl_disconnect(self._idPress) if self._idRelease is not None: self.canvas.mpl_disconnect(self._idRelease) if self._idDrag is not None: self.canvas.mpl_disconnect(self._idDrag) self._idPress = self.canvas.mpl_connect("button_press_event", self.highlight_press) self._idDrag = self.canvas.mpl_connect("motion_notify_event", self.legend_on_hover) def legend_pickable_disconnection(self): self._idPick = self.canvas.mpl_disconnect(self._idPick) self._idDrag = self.canvas.mpl_disconnect(self._idDrag) if self.annotation: self.annotation = self.annotation.remove() for ax in self.canvas.figure.get_axes(): for line in ax.lines: if line.get_linewidth() != 1.0: line.set_linewidth(1.0) if line.get_alpha() != 1.0: line.set_alpha(1.0) self.canvas.draw_idle() def legend_on_hover(self, event): ax = event.inaxes if ax not in self.canvas.figure.get_axes(): return for line in ax.lines: res = line.contains(event) if res[0]: self.line = line self.highlight(ax, line) if self.annotationAction.isChecked(): x, y = line.get_xydata()[res[1]['ind'][0]] label = ax.get_xlabel() if ax.get_xlabel() else 'x =' ylabel = ax.get_ylabel() if ax.get_ylabel() else 'y =' if self.annotation: self.annotation.set_visible(True) self.annotation.xy = x, y self.annotation.set_position = (x, y) self.annotation.set_text("%s %.4f\n%s %.4f" % (label, x, ylabel, y)) else: self.annotation = ax.annotate( ("%s %.4f\n%s %.4f" % (label, x, ylabel, y)), xy=(x, y), xycoords='data', xytext=(x + 20, y), textcoords='offset points', ha='left', va='bottom', fontsize=10, color="white", zorder=10, bbox=dict(boxstyle='square', fc='grey', alpha=1, ec='grey'), arrowprops=dict(arrowstyle='->', color='grey', connectionstyle='arc3,rad=0')) break else: if self.annotation: self.annotation.set_visible(False) self.highlight(ax, None) def highlight(self, ax, target): need_redraw = False if target is None: for line in ax.lines: if line.get_linewidth() != 1.0: line.set_linewidth(1.0) need_redraw = True else: for line in ax.lines: if line == target: line.set_linewidth(2.0) need_redraw = True if need_redraw: self.canvas.draw_idle() def highlight_press(self, event): ax = event.inaxes for line in ax.lines: if line == self.cursor_line: continue if line == self.line and self.line: line.set_alpha(1.0) else: line.set_alpha(0.2) # ax.legend(loc='best') self.canvas.draw()
def zoom_out(self): action = QAction(self.app.ui.zoom_out_icon, "Zoom out") action.setToolTip("Zoom out") action.setStatusTip("Zoom out, Shortcuts : Ctrl+Down, Ctrl+-") action.setShortcuts(["Ctrl+Down", "Ctrl+-", "Ctrl+_"]) return action
def zoom_in(self): action = QAction(self.app.ui.zoom_in_icon, "Zoom in") action.setToolTip("Zoom in") action.setStatusTip("Zoom in, Shortcuts : Ctrl+Up, Ctrl++") action.setShortcuts(["Ctrl+Up", "Ctrl++", "Ctrl+="]) return action
def next(self): action = QAction(self.app.ui.next_icon, "Next") action.setToolTip("Next") action.setStatusTip("View next image, Shortcuts : Right, PgDown") action.setShortcuts(["Right", "PgDown"]) return action
def _update_file_menu(self): """ Set up the File menu and update the menu with recent files """ self.file_menu.clear() newAction = QAction("&New Reduction...", self) newAction.setShortcut("Ctrl+N") newAction.setStatusTip("Start a new reduction") newAction.triggered.connect(self._new) openAction = QAction("&Open...", self) openAction.setShortcut("Ctrl+O") openAction.setStatusTip("Open an XML file containing reduction parameters") openAction.triggered.connect(self._file_open) saveAsAction = QAction("Save as...", self) saveAsAction.setStatusTip("Save the reduction parameters to XML") saveAsAction.triggered.connect(self._save_as) saveAction = QAction("&Save...", self) saveAction.setShortcut("Ctrl+S") saveAction.setStatusTip("Save the reduction parameters to XML") saveAction.triggered.connect(self._save) exportAction = QAction("&Export...", self) exportAction.setShortcut("Ctrl+E") exportAction.setStatusTip("Export to python script for Mantid") exportAction.triggered.connect(self._export) quitAction = QAction("&Quit", self) quitAction.setShortcut("Ctrl+Q") quitAction.triggered.connect(self.close) self.file_menu.addAction(newAction) self.file_menu.addAction(openAction) self.file_menu.addAction(saveAction) self.file_menu.addAction(saveAsAction) self.file_menu.addAction(exportAction) self.file_menu.addSeparator() if self.general_settings.debug: clearAction = QAction("&Clear settings and quit", self) clearAction.setStatusTip("Restore initial application settings and close the application") clearAction.triggered.connect(self._clear_and_close) self.file_menu.addAction(clearAction) self.file_menu.addAction(quitAction) # TOOLS menu instrAction = QAction("Change &instrument...", self) instrAction.setShortcut("Ctrl+I") instrAction.setStatusTip("Select a new instrument") instrAction.triggered.connect(self._change_instrument) debug_menu_item_str = "Turn debug mode ON" if self.general_settings.debug: debug_menu_item_str = "Turn debug mode OFF" debugAction = QAction(debug_menu_item_str, self) debugAction.setStatusTip(debug_menu_item_str) debugAction.triggered.connect(self._debug_mode) self.tools_menu.clear() self.tools_menu.addAction(instrAction) self.tools_menu.addAction(debugAction) recent_files = [] for fname in self._recent_files: if fname != self._filename and QFile.exists(fname) and fname not in recent_files: recent_files.append(fname) if len(recent_files)>0: self.file_menu.addSeparator() for i, fname in enumerate(recent_files): action = QAction("&%d %s" % (i+1, QFileInfo(fname).fileName()), self) action.setData(fname) action.triggered.connect(self.open_file) self.file_menu.addAction(action)
def _add_file_menu(self): """Add 'File' menu to app menubar.""" open_images = QAction('Open File(s)...', self._qt_window) open_images.setShortcut('Ctrl+O') open_images.setStatusTip('Open file(s)') open_images.triggered.connect(self.qt_viewer._open_files_dialog) open_stack = QAction('Open Files as Stack...', self._qt_window) open_stack.setShortcut('Ctrl+Alt+O') open_stack.setStatusTip('Open files') open_stack.triggered.connect( self.qt_viewer._open_files_dialog_as_stack_dialog) open_folder = QAction('Open Folder...', self._qt_window) open_folder.setShortcut('Ctrl+Shift+O') open_folder.setStatusTip('Open a folder') open_folder.triggered.connect(self.qt_viewer._open_folder_dialog) save_selected_layers = QAction('Save Selected Layer(s)...', self._qt_window) save_selected_layers.setShortcut('Ctrl+S') save_selected_layers.setStatusTip('Save selected layers') save_selected_layers.triggered.connect( lambda: self.qt_viewer._save_layers_dialog(selected=True)) save_all_layers = QAction('Save All Layers...', self._qt_window) save_all_layers.setShortcut('Ctrl+Shift+S') save_all_layers.setStatusTip('Save all layers') save_all_layers.triggered.connect( lambda: self.qt_viewer._save_layers_dialog(selected=False)) screenshot = QAction('Save Screenshot...', self._qt_window) screenshot.setShortcut('Alt+S') screenshot.setStatusTip( 'Save screenshot of current display, default .png') screenshot.triggered.connect(self.qt_viewer._screenshot_dialog) screenshot_wv = QAction('Save Screenshot with Viewer...', self._qt_window) screenshot_wv.setShortcut('Alt+Shift+S') screenshot_wv.setStatusTip( 'Save screenshot of current display with the viewer, default .png') screenshot_wv.triggered.connect(self._screenshot_dialog) # OS X will rename this to Quit and put it in the app menu. exitAction = QAction('Exit', self._qt_window) exitAction.setShortcut('Ctrl+Q') exitAction.setMenuRole(QAction.QuitRole) def handle_exit(): # if the event loop was started in gui_qt() then the app will be # named 'napari'. Since the Qapp was started by us, just close it. if QApplication.applicationName() == 'napari': QApplication.closeAllWindows() QApplication.quit() # otherwise, something else created the QApp before us (such as # %gui qt IPython magic). If we quit the app in this case, then # *later* attempts to instantiate a napari viewer won't work until # the event loop is restarted with app.exec_(). So rather than # quit just close all the windows (and clear our app icon). else: QApplication.setWindowIcon(QIcon()) self.close() if perf.USE_PERFMON: # Write trace file before exit, if we were writing one. # Is there a better place to make sure this is done on exit? perf.timers.stop_trace_file() exitAction.triggered.connect(handle_exit) self.file_menu = self.main_menu.addMenu('&File') self.file_menu.addAction(open_images) self.file_menu.addAction(open_stack) self.file_menu.addAction(open_folder) self.file_menu.addSeparator() self.file_menu.addAction(save_selected_layers) self.file_menu.addAction(save_all_layers) self.file_menu.addAction(screenshot) self.file_menu.addAction(screenshot_wv) self.file_menu.addSeparator() self.file_menu.addAction(exitAction)
class Tool: def __init__( self, name, help_link="", icon=None, enabled=True, checkable=False, popup_menu=False, ): super().__init__() self.__icon = icon self.__name = name self.__parent = None self.__enabled = enabled self.__checkable = checkable self.__help_link = help_link self.__is_popup_menu = popup_menu self.__action = QAction(self.getIcon(), self.getName(), None) self.__action.setIconText(self.getName()) self.__action.setEnabled(self.isEnabled()) self.__action.setCheckable(checkable) self.__action.triggered.connect(self.trigger) def getIcon(self): return self.__icon def getName(self): return self.__name def trigger(self): raise NotImplementedError() def setParent(self, parent): self.__parent = parent self.__action.setParent(parent) def parent(self): return self.__parent def isEnabled(self): return self.__enabled def getHelpLink(self): return self.__help_link def getAction(self): return self.__action def setVisible(self, visible): self.__action.setVisible(visible) def setEnabled(self, enabled): self.__action.setEnabled(enabled) def isPopupMenu(self): return self.__is_popup_menu
def maximize(self): action = QAction(self.app.ui.maximize_icon, "Maximize") action.setToolTip("Maximize") action.setStatusTip("Maximize") return action
def about(self): action = QAction(self.app.ui.about_icon, "About") action.setToolTip("About") action.setToolTip("About this application, Shortcuts : F2") action.setShortcuts(["F2"]) return action
def _add_view_menu(self): """Add 'View' menu to app menubar.""" toggle_visible = QAction('Toggle Menubar Visibility', self._qt_window) toggle_visible.setShortcut('Ctrl+M') toggle_visible.setStatusTip('Hide Menubar') toggle_visible.triggered.connect(self._toggle_menubar_visible) toggle_theme = QAction('Toggle Theme', self._qt_window) toggle_theme.setShortcut('Ctrl+Shift+T') toggle_theme.setStatusTip('Toggle theme') toggle_theme.triggered.connect(self.qt_viewer.viewer._toggle_theme) self.view_menu = self.main_menu.addMenu('&View') self.view_menu.addAction(toggle_visible) self.view_menu.addAction(toggle_theme) self.view_menu.addSeparator() # Add axes menu axes_menu = QMenu('Axes', parent=self._qt_window) axes_visible_action = QAction( 'Visible', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.axes.visible, ) axes_visible_action.triggered.connect(self._toggle_axes_visible) axes_colored_action = QAction( 'Colored', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.axes.colored, ) axes_colored_action.triggered.connect(self._toggle_axes_colored) axes_dashed_action = QAction( 'Dashed', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.axes.dashed, ) axes_dashed_action.triggered.connect(self._toggle_axes_dashed) axes_arrows_action = QAction( 'Arrows', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.axes.arrows, ) axes_arrows_action.triggered.connect(self._toggle_axes_arrows) axes_menu.addAction(axes_visible_action) axes_menu.addAction(axes_colored_action) axes_menu.addAction(axes_dashed_action) axes_menu.addAction(axes_arrows_action) self.view_menu.addMenu(axes_menu) # Add scale bar menu scale_bar_menu = QMenu('Scale Bar', parent=self._qt_window) scale_bar_visible_action = QAction( 'Visible', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.scale_bar.visible, ) scale_bar_visible_action.triggered.connect( self._toggle_scale_bar_visible) scale_bar_colored_action = QAction( 'Colored', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.scale_bar.colored, ) scale_bar_colored_action.triggered.connect( self._toggle_scale_bar_colored) scale_bar_ticks_action = QAction( 'Ticks', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.scale_bar.ticks, ) scale_bar_ticks_action.triggered.connect(self._toggle_scale_bar_ticks) scale_bar_menu.addAction(scale_bar_visible_action) scale_bar_menu.addAction(scale_bar_colored_action) scale_bar_menu.addAction(scale_bar_ticks_action) self.view_menu.addMenu(scale_bar_menu) self.view_menu.addSeparator()
def settings(self): action = QAction(self.app.ui.settings_icon, "Settings") action.setToolTip("Setting window") action.setToolTip("Show setting window, Shortcuts : Ctrl+,") action.setShortcuts(["Ctrl+,"]) return action
def _add_help_menu(self): """Add 'Help' menu to app menubar.""" self.help_menu = self.main_menu.addMenu('&Help') about_action = QAction("napari Info", self._qt_window) about_action.setShortcut("Ctrl+/") about_action.setStatusTip('About napari') about_action.triggered.connect( lambda e: QtAbout.showAbout(self.qt_viewer)) self.help_menu.addAction(about_action) about_key_bindings = QAction("Show Key Bindings", self._qt_window) about_key_bindings.setShortcut("Ctrl+Alt+/") about_key_bindings.setShortcutContext(Qt.ApplicationShortcut) about_key_bindings.setStatusTip('key_bindings') about_key_bindings.triggered.connect( self.qt_viewer.show_key_bindings_dialog) self.help_menu.addAction(about_key_bindings)
class TyphonSidebarItem(ptypes.ParameterItem): """ Class to display a Device or Tool in the sidebar """ def __init__(self, param, depth): super().__init__(param, depth) # Configure a QToolbar self.toolbar = QToolBar() self.toolbar.setToolButtonStyle(Qt.ToolButtonIconOnly) self.toolbar.setIconSize(QSize(15, 15)) # Setup the action to open the widget self.open_action = QAction(qta.icon('fa.square', color='green'), 'Open', self.toolbar) self.open_action.triggered.connect(self.open_requested) # Setup the action to embed the widget self.embed_action = QAction(qta.icon('fa.th-large', color='yellow'), 'Embed', self.toolbar) self.embed_action.triggered.connect(self.embed_requested) # Setup the action to hide the widget self.hide_action = QAction(qta.icon('fa.times-circle', color='red'), 'Close', self.toolbar) self.hide_action.triggered.connect(self.hide_requested) self.hide_action.setEnabled(False) # Add actions to toolbars self.toolbar.addAction(self.open_action) self.toolbar.addAction(self.hide_action) if self.param.embeddable: self.toolbar.insertAction(self.hide_action, self.embed_action) def open_requested(self, triggered): """Request to open display for sidebar item""" self.param.sigOpen.emit(self) self._mark_shown() def embed_requested(self, triggered): """Request to open embedded display for sidebar item""" self.param.sigEmbed.emit(self) self._mark_shown() def hide_requested(self, triggered): """Request to hide display for sidebar item""" self.param.sigHide.emit(self) self._mark_hidden() def _mark_shown(self): self.open_action.setEnabled(False) self.embed_action.setEnabled(False) self.hide_action.setEnabled(True) def _mark_hidden(self): self.open_action.setEnabled(True) self.embed_action.setEnabled(True) self.hide_action.setEnabled(False) def treeWidgetChanged(self): """Update the widget when add to a QTreeWidget""" super().treeWidgetChanged() tree = self.treeWidget() if tree is None: return tree.setItemWidget(self, 1, self.toolbar)
def drawLayout(self): """ Draws the GUI layout. """ self.widgetslist = [[ 'pair', 'show', 'Instrument', 'combo', self.instruments, self.setInstrument, 'InstrumentCombo' ], [ 'pair', 'show', 'Chopper', 'combo', '', self.setChopper, 'ChopperCombo' ], [ 'pair', 'show', 'Frequency', 'combo', '', self.setFreq, 'FrequencyCombo' ], [ 'pair', 'hide', 'Pulse remover chopper freq', 'combo', '', self.setFreq, 'PulseRemoverCombo' ], [ 'pair', 'show', 'Ei', 'edit', '', self.setEi, 'EiEdit' ], [ 'pair', 'hide', 'Chopper 2 phase delay time', 'edit', '5', self.setFreq, 'Chopper2Phase' ], ['spacer'], [ 'single', 'show', 'Calculate and Plot', 'button', self.calc_callback, 'CalculateButton' ], [ 'single', 'show', 'Hold current plot', 'check', lambda: None, 'HoldCheck' ], [ 'single', 'show', 'Show multi-reps', 'check', lambda: None, 'MultiRepCheck' ], ['spacer'], [ 'single', 'show', 'Show data ascii window', 'button', self.showText, 'ShowAsciiButton' ], [ 'single', 'show', 'Save data as ascii', 'button', self.saveText, 'SaveAsciiButton' ]] self.droplabels = [] self.dropboxes = [] self.singles = [] self.widgets = {} self.leftPanel = QVBoxLayout() self.rightPanel = QVBoxLayout() self.tabs = QTabWidget(self) self.fullWindow = QGridLayout() self.n_indep_phase = -1 idx = 0 for widget in self.widgetslist: if widget[-1] == 'Chopper2Phase': self.phase_index = idx continue if 'pair' in widget[0]: self.droplabels.append(QLabel(widget[2])) if 'combo' in widget[3]: self.dropboxes.append(QComboBox(self)) self.dropboxes[-1].activated['QString'].connect(widget[5]) for item in widget[4]: self.dropboxes[-1].addItem(item) self.widgets[widget[-1]] = { 'Combo': self.dropboxes[-1], 'Label': self.droplabels[-1] } elif 'edit' in widget[3]: self.dropboxes.append(QLineEdit(self)) self.dropboxes[-1].returnPressed.connect(widget[5]) self.widgets[widget[-1]] = { 'Edit': self.dropboxes[-1], 'Label': self.droplabels[-1] } else: raise RuntimeError( 'Bug in code - widget %s is not recognised.' % (widget[3])) self.leftPanel.addWidget(self.droplabels[-1]) self.leftPanel.addWidget(self.dropboxes[-1]) idx += 2 if 'hide' in widget[1]: self.droplabels[-1].hide() self.dropboxes[-1].hide() elif 'single' in widget[0]: if 'check' in widget[3]: self.singles.append(QCheckBox(widget[2], self)) self.singles[-1].stateChanged.connect(widget[4]) elif 'button' in widget[3]: self.singles.append(QPushButton(widget[2])) self.singles[-1].clicked.connect(widget[4]) else: raise RuntimeError( 'Bug in code - widget %s is not recognised.' % (widget[3])) self.leftPanel.addWidget(self.singles[-1]) idx += 1 if 'hide' in widget[1]: self.singles[-1].hide() self.widgets[widget[-1]] = self.singles[-1] elif 'spacer' in widget[0]: self.leftPanel.addItem(QSpacerItem(0, 35)) idx += 1 else: raise RuntimeError( 'Bug in code - widget class %s is not recognised.' % (widget[0])) # Right panel, matplotlib figures self.resfig = Figure() self.resfig.patch.set_facecolor('white') self.rescanvas = FigureCanvas(self.resfig) self.resaxes = self.resfig.add_subplot(111) self.resaxes.axhline(color='k') self.resaxes.set_xlabel('Energy Transfer (meV)') self.resaxes.set_ylabel(r'$\Delta$E (meV FWHM)') self.resfig_controls = NavigationToolbar(self.rescanvas, self) self.restab = QWidget(self.tabs) self.restabbox = QVBoxLayout() self.restabbox.addWidget(self.rescanvas) self.restabbox.addWidget(self.resfig_controls) self.restab.setLayout(self.restabbox) self.flxfig = Figure() self.flxfig.patch.set_facecolor('white') self.flxcanvas = FigureCanvas(self.flxfig) self.flxaxes1 = self.flxfig.add_subplot(121) self.flxaxes1.set_xlabel('Incident Energy (meV)') self.flxaxes1.set_ylabel('Flux (n/cm$^2$/s)') self.flxaxes2 = self.flxfig.add_subplot(122) self.flxaxes2.set_xlabel('Incident Energy (meV)') self.flxaxes2.set_ylabel('Elastic Resolution FWHM (meV)') self.flxfig_controls = NavigationToolbar(self.flxcanvas, self) self.flxsldfg = Figure() self.flxsldfg.patch.set_facecolor('white') self.flxsldcv = FigureCanvas(self.flxsldfg) self.flxsldax = self.flxsldfg.add_subplot(111) self.flxslder = Slider(self.flxsldax, 'Ei (meV)', 0, 100, valinit=100) self.flxslder.valtext.set_visible(False) self.flxslder.on_changed(self.update_slider) self.flxedt = QLineEdit() self.flxedt.setText('1000') self.flxedt.returnPressed.connect(self.update_slider) self.flxtab = QWidget(self.tabs) self.flxsldbox = QHBoxLayout() self.flxsldbox.addWidget(self.flxsldcv) self.flxsldbox.addWidget(self.flxedt) self.flxsldwdg = QWidget() self.flxsldwdg.setLayout(self.flxsldbox) sz = self.flxsldwdg.maximumSize() sz.setHeight(50) self.flxsldwdg.setMaximumSize(sz) self.flxtabbox = QVBoxLayout() self.flxtabbox.addWidget(self.flxcanvas) self.flxtabbox.addWidget(self.flxsldwdg) self.flxtabbox.addWidget(self.flxfig_controls) self.flxtab.setLayout(self.flxtabbox) self.frqfig = Figure() self.frqfig.patch.set_facecolor('white') self.frqcanvas = FigureCanvas(self.frqfig) self.frqaxes1 = self.frqfig.add_subplot(121) self.frqaxes1.set_xlabel('Chopper Frequency (Hz)') self.frqaxes1.set_ylabel('Flux (n/cm$^2$/s)') self.frqaxes2 = self.frqfig.add_subplot(122) self.frqaxes1.set_xlabel('Chopper Frequency (Hz)') self.frqaxes2.set_ylabel('Elastic Resolution FWHM (meV)') self.frqfig_controls = NavigationToolbar(self.frqcanvas, self) self.frqtab = QWidget(self.tabs) self.frqtabbox = QVBoxLayout() self.frqtabbox.addWidget(self.frqcanvas) self.frqtabbox.addWidget(self.frqfig_controls) self.frqtab.setLayout(self.frqtabbox) self.repfig = Figure() self.repfig.patch.set_facecolor('white') self.repcanvas = FigureCanvas(self.repfig) self.repaxes = self.repfig.add_subplot(111) self.repaxes.axhline(color='k') self.repaxes.set_xlabel(r'TOF ($\mu$sec)') self.repaxes.set_ylabel('Distance (m)') self.repfig_controls = NavigationToolbar(self.repcanvas, self) self.repfig_nframe_label = QLabel('Number of frames to plot') self.repfig_nframe_edit = QLineEdit('1') self.repfig_nframe_button = QPushButton('Replot') self.repfig_nframe_button.clicked.connect(lambda: self.plot_frame()) self.repfig_nframe_rep1only = QCheckBox('First Rep Only') self.repfig_nframe_box = QHBoxLayout() self.repfig_nframe_box.addWidget(self.repfig_nframe_label) self.repfig_nframe_box.addWidget(self.repfig_nframe_edit) self.repfig_nframe_box.addWidget(self.repfig_nframe_button) self.repfig_nframe_box.addWidget(self.repfig_nframe_rep1only) self.reptab = QWidget(self.tabs) self.repfig_nframe = QWidget(self.reptab) self.repfig_nframe.setLayout(self.repfig_nframe_box) self.repfig_nframe.setSizePolicy( QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)) self.reptabbox = QVBoxLayout() self.reptabbox.addWidget(self.repcanvas) self.reptabbox.addWidget(self.repfig_nframe) self.reptabbox.addWidget(self.repfig_controls) self.reptab.setLayout(self.reptabbox) self.qefig = Figure() self.qefig.patch.set_facecolor('white') self.qecanvas = FigureCanvas(self.qefig) self.qeaxes = self.qefig.add_subplot(111) self.qeaxes.axhline(color='k') self.qeaxes.set_xlabel(r'$|Q| (\mathrm{\AA}^{-1})$') self.qeaxes.set_ylabel('Energy Transfer (meV)') self.qefig_controls = NavigationToolbar(self.qecanvas, self) self.qetabbox = QVBoxLayout() self.qetabbox.addWidget(self.qecanvas) self.qetabbox.addWidget(self.qefig_controls) self.qetab = QWidget(self.tabs) self.qetab.setLayout(self.qetabbox) self.scrtab = QWidget(self.tabs) self.scredt = QTextEdit() self.scrcls = QPushButton("Clear") self.scrcls.clicked.connect(lambda: self.scredt.clear()) self.scrbox = QVBoxLayout() self.scrbox.addWidget(self.scredt) self.scrbox.addWidget(self.scrcls) self.scrtab.setLayout(self.scrbox) self.scrtab.hide() self.tabs.addTab(self.restab, 'Resolution') self.tabs.addTab(self.flxtab, 'Flux-Ei') self.tabs.addTab(self.frqtab, 'Flux-Freq') self.tabs.addTab(self.reptab, 'Time-Distance') self.tdtabID = 3 self.tabs.setTabEnabled(self.tdtabID, False) self.tabs.addTab(self.qetab, 'Q-E') self.qetabID = 4 self.tabs.setTabEnabled(self.qetabID, False) self.scrtabID = 5 self.rightPanel.addWidget(self.tabs) self.menuLoad = QMenu('Load') self.loadAct = QAction('Load YAML', self.menuLoad) self.loadAct.triggered.connect(self.loadYaml) self.menuLoad.addAction(self.loadAct) self.menuOptions = QMenu('Options') self.instSciAct = QAction('Instrument Scientist Mode', self.menuOptions, checkable=True) self.instSciAct.triggered.connect(self.instSciCB) self.menuOptions.addAction(self.instSciAct) self.eiPlots = QAction('Press Enter in Ei box updates plots', self.menuOptions, checkable=True) self.menuOptions.addAction(self.eiPlots) self.overwriteload = QAction('Always overwrite instruments in memory', self.menuOptions, checkable=True) self.menuOptions.addAction(self.overwriteload) self.menuBar().addMenu(self.menuLoad) self.menuBar().addMenu(self.menuOptions) self.leftPanelWidget = QWidget() self.leftPanelWidget.setLayout(self.leftPanel) self.leftPanelWidget.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)) self.fullWindow.addWidget(self.leftPanelWidget, 0, 0) self.fullWindow.addLayout(self.rightPanel, 0, 1) self.helpbtn = QPushButton("?", self) self.helpbtn.setMaximumWidth(30) self.helpbtn.clicked.connect(self.onHelp) self.fullWindow.addWidget(self.helpbtn, 1, 0, 1, -1) self.mainWidget = QWidget() self.mainWidget.setLayout(self.fullWindow) self.setCentralWidget(self.mainWidget) self.setWindowTitle('PyChopGUI') self.show()
def make_separator(self, horizontalHeader): separator1 = QAction(horizontalHeader) separator1.setSeparator(True) return separator1
def delete_item(self): action = QAction(self.app.ui.delete_icon, "Delete") action.setToolTip("Delete") action.setStatusTip("Delete, Shortcuts : Delete") action.setShortcuts(["Del"]) return action
def InitMenu(self): mainMenu = self.menuBar fileMenu = mainMenu.addMenu('File') SaveRec1Action = QAction('Save Rec1 as', self) SaveRec1Action.setStatusTip('Save a copy of Rec1 and Evens') SaveRec1Action.triggered.connect(self.SaveRec1) fileMenu.addAction(SaveRec1Action) SaveJoinRecAction = QAction('Join Rec1 and Rec2 as', self) SaveJoinRecAction.setStatusTip( 'Save a copy of Rec1 and Rec2 with Tstart') SaveJoinRecAction.triggered.connect(self.SaveJoinRec) fileMenu.addAction(SaveJoinRecAction) SaveFigAction = QAction('Save Figures', self) SaveFigAction.setShortcut('Ctrl+s') SaveFigAction.setStatusTip('Save all open figures') SaveFigAction.triggered.connect(self.SaveFigures) fileMenu.addAction(SaveFigAction) CloseFigsAction = QAction('Close Figures', self) CloseFigsAction.setStatusTip('Close all open figures') CloseFigsAction.triggered.connect(self.CloseFigures) fileMenu.addAction(CloseFigsAction)
def setup_menu(self): menubar = self.menuBar() file_menu = menubar.addMenu('&Archivo') refresh_action = QAction(qta.icon('fa5s.sync'), '&Actualizar', self) refresh_action.setShortcut('Ctrl+A') refresh_action.setStatusTip( 'Actualizando Base de Datos de Artículos....') refresh_action.triggered.connect( scraper.scrapeAll) # Llamar al método de scrapper file_menu.addAction(refresh_action) exit_action = QAction(qta.icon('fa5.times-circle'), '&Salir', self) exit_action.setShortcut('Ctrl+Q') exit_action.setStatusTip('Saliendo de la aplicación....') exit_action.triggered.connect(QApplication.instance().closeAllWindows) file_menu.addAction(exit_action) help_menu = menubar.addMenu('&Ayuda') about_action = QAction(qta.icon('fa5s.info-circle'), '&Acerca de', self) about_action.setShortcut('Ctrl+I') about_action.setStatusTip('Acerca de...') about_action.triggered.connect(self.show_about_dialog) help_menu.addAction(about_action)
def setup_menu_actions(self): # flow designs light_themes_menu = QMenu('light') for d in self.session.design.flow_themes: design_action = QAction(d.name, self) if d.type_ == 'dark': self.ui.menuFlow_Design_Style.addAction(design_action) else: light_themes_menu.addAction(design_action) design_action.triggered.connect(self.on_design_action_triggered) self.flow_view_theme_actions.append(design_action) self.ui.menuFlow_Design_Style.addMenu(light_themes_menu) self.ui.actionImport_Nodes.triggered.connect(self.on_import_nodes_triggered) self.ui.actionSave_Project.triggered.connect(self.on_save_project_triggered) self.ui.actionEnableInfoMessages.triggered.connect(self.on_enable_info_msgs_triggered) self.ui.actionDisableInfoMessages.triggered.connect(self.on_disable_info_msgs_triggered) self.ui.actionSave_Pic_Viewport.triggered.connect(self.on_save_scene_pic_viewport_triggered) self.ui.actionSave_Pic_Whole_Scene_scaled.triggered.connect(self.on_save_scene_pic_whole_triggered) # performance mode self.ac_perf_mode_fast = QAction('Fast', self) self.ac_perf_mode_fast.setCheckable(True) self.ac_perf_mode_pretty = QAction('Pretty', self) self.ac_perf_mode_pretty.setCheckable(True) perf_mode_ag = QActionGroup(self) perf_mode_ag.addAction(self.ac_perf_mode_fast) perf_mode_ag.addAction(self.ac_perf_mode_pretty) self.ac_perf_mode_fast.setChecked(self.session.design.performance_mode == 'fast') self.ac_perf_mode_pretty.setChecked(self.session.design.performance_mode == 'pretty') perf_mode_ag.triggered.connect(self.on_performance_mode_changed) perf_menu = QMenu('Performance Mode', self) perf_menu.addAction(self.ac_perf_mode_fast) perf_menu.addAction(self.ac_perf_mode_pretty) self.ui.menuView.addMenu(perf_menu) # animations self.ac_anims_active = QAction('Enabled', self) self.ac_anims_active.setCheckable(True) self.ac_anims_inactive = QAction('Disabled', self) self.ac_anims_inactive.setCheckable(True) anims_ag = QActionGroup(self) anims_ag.addAction(self.ac_anims_active) anims_ag.addAction(self.ac_anims_inactive) self.ac_anims_active.setChecked(self.session.design.animations_enabled) self.ac_anims_inactive.setChecked(not self.session.design.animations_enabled) anims_ag.triggered.connect(self.on_animation_enabling_changed) animations_menu = QMenu('Animations', self) animations_menu.addAction(self.ac_anims_active) animations_menu.addAction(self.ac_anims_inactive) self.ui.menuView.addMenu(animations_menu)
def create_action(parent, text, shortcut=None, icon=None, tip=None, toggled=None, triggered=None, data=None, menurole=None, context=Qt.WindowShortcut): """Create a QAction""" action = QAction(text, parent) if triggered is not None: action.triggered.connect(triggered) if toggled is not None: action.toggled.connect(toggled) action.setCheckable(True) if icon is not None: if is_text_string(icon): icon = get_icon(icon) action.setIcon(icon) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if data is not None: action.setData(to_qvariant(data)) if menurole is not None: action.setMenuRole(menurole) #TODO: Hard-code all shortcuts and choose context=Qt.WidgetShortcut # (this will avoid calling shortcuts from another dockwidget # since the context thing doesn't work quite well with these widgets) action.setShortcutContext(context) return action
class MainWindow(QMainWindow): def __init__(self, config, window_theme: WindowTheme): super(MainWindow, self).__init__() self.session = None self.theme = window_theme self.node_packages = {} # {Node: str} self.script_UIs = [] # SESSION self.session = rc.Session(node_class=NodeBase) self.session.flow_view_created.connect(self.script_created) self.session.script_renamed.connect(self.script_renamed) self.session.script_deleted.connect(self.script_deleted) # LOAD DESIGN AND FLOW THEME self.session.design.load_from_config('design_config.json') if self.theme.name == 'dark': self.session.design.set_flow_theme(name='pure dark') else: # 'light' self.session.design.set_flow_theme(name='pure light') # UI self.setup_ui() self.flow_view_theme_actions = [] self.setup_menu_actions() self.setWindowTitle('Ryven') self.setWindowIcon(QIcon('../resources/pics/Ryven_icon.png')) self.ui.scripts_tab_widget.removeTab(0) # remove placeholder tab # SHORTCUTS save_shortcut = QShortcut(QKeySequence.Save, self) save_shortcut.activated.connect(self.on_save_project_triggered) import_nodes_shortcut = QShortcut(QKeySequence('Ctrl+i'), self) import_nodes_shortcut.activated.connect(self.on_import_nodes_triggered) # TEMP FOLDER if not os.path.exists('../temp'): os.mkdir('../temp') for f in os.listdir('../temp'): os.remove('temp/'+f) # PROJECT SETUP if 'info_msgs' in sys.argv: rc.InfoMsgs.enable() # SETUP MAIN CONSOLE MainConsole.instance.session = self.session MainConsole.instance.reset_interpreter() NodeBase.main_console = MainConsole.instance # REGISTER BUILT-IN NODES self.import_nodes(path=join(dirname(__file__), 'nodes/built_in/')) # LOAD PROJECT if config['config'] == 'create plain new project': self.session.create_script(title='hello world') elif config['config'] == 'open project': print('importing packages...') self.import_packages(config['required packages']) print('loading project...') self.session.load(config['content']) print('finished') self.resize(1500, 800) # self.showMaximized() def print_info(self): print(''' CONTROLS place: right mouse select: left mouse pan: right mouse save: ctrl+s import: ctrl+i ''') # UI def setup_ui(self): self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.statusBar.hide() # # nodes tree # self.nodes_tree_widget = NodesTreeListWidget(self, self.session) # self.ui.bottom_splitter.addWidget(self.nodes_tree_widget) # # node details widget # self.node_details_widget = NodeDetailsWidget(self, self.nodes_tree_widget) # self.ui.bottom_splitter.addWidget(self.node_details_widget) # main console if MainConsole.instance is not None: self.ui.bottom_splitter.addWidget(MainConsole.instance) # self.ui.right_vertical_splitter.setSizes([600, 0]) # splitter sizes # self.ui.left_vertical_splitter.setSizes([350, 350]) self.ui.main_vertical_splitter.setSizes([700, 0]) self.scripts_list_widget = rc.GUI.ScriptsList(self.session) self.scripts_list_widget.create_script_button.setProperty('class', 'small_button') self.scripts_list_widget.create_macro_button.setProperty('class', 'small_button') self.ui.scripts_groupBox.layout().addWidget(self.scripts_list_widget) def setup_menu_actions(self): # flow designs light_themes_menu = QMenu('light') for d in self.session.design.flow_themes: design_action = QAction(d.name, self) if d.type_ == 'dark': self.ui.menuFlow_Design_Style.addAction(design_action) else: light_themes_menu.addAction(design_action) design_action.triggered.connect(self.on_design_action_triggered) self.flow_view_theme_actions.append(design_action) self.ui.menuFlow_Design_Style.addMenu(light_themes_menu) self.ui.actionImport_Nodes.triggered.connect(self.on_import_nodes_triggered) self.ui.actionSave_Project.triggered.connect(self.on_save_project_triggered) self.ui.actionEnableInfoMessages.triggered.connect(self.on_enable_info_msgs_triggered) self.ui.actionDisableInfoMessages.triggered.connect(self.on_disable_info_msgs_triggered) self.ui.actionSave_Pic_Viewport.triggered.connect(self.on_save_scene_pic_viewport_triggered) self.ui.actionSave_Pic_Whole_Scene_scaled.triggered.connect(self.on_save_scene_pic_whole_triggered) # performance mode self.ac_perf_mode_fast = QAction('Fast', self) self.ac_perf_mode_fast.setCheckable(True) self.ac_perf_mode_pretty = QAction('Pretty', self) self.ac_perf_mode_pretty.setCheckable(True) perf_mode_ag = QActionGroup(self) perf_mode_ag.addAction(self.ac_perf_mode_fast) perf_mode_ag.addAction(self.ac_perf_mode_pretty) self.ac_perf_mode_fast.setChecked(self.session.design.performance_mode == 'fast') self.ac_perf_mode_pretty.setChecked(self.session.design.performance_mode == 'pretty') perf_mode_ag.triggered.connect(self.on_performance_mode_changed) perf_menu = QMenu('Performance Mode', self) perf_menu.addAction(self.ac_perf_mode_fast) perf_menu.addAction(self.ac_perf_mode_pretty) self.ui.menuView.addMenu(perf_menu) # animations self.ac_anims_active = QAction('Enabled', self) self.ac_anims_active.setCheckable(True) self.ac_anims_inactive = QAction('Disabled', self) self.ac_anims_inactive.setCheckable(True) anims_ag = QActionGroup(self) anims_ag.addAction(self.ac_anims_active) anims_ag.addAction(self.ac_anims_inactive) self.ac_anims_active.setChecked(self.session.design.animations_enabled) self.ac_anims_inactive.setChecked(not self.session.design.animations_enabled) anims_ag.triggered.connect(self.on_animation_enabling_changed) animations_menu = QMenu('Animations', self) animations_menu.addAction(self.ac_anims_active) animations_menu.addAction(self.ac_anims_inactive) self.ui.menuView.addMenu(animations_menu) def load_stylesheet(self, ss): ss_content = '' try: f = open('../resources/stylesheets/'+ss+'.txt') ss_content = f.read() f.close() finally: self.session.set_stylesheet(ss_content) self.setStyleSheet(ss_content) # SLOTS def on_import_nodes_triggered(self): file_path = QFileDialog.getOpenFileName(self, 'select nodes file', '../packages', '(*.py)',)[0] if file_path != '': self.import_nodes(path=dirname(file_path)) def on_performance_mode_changed(self, action): if action == self.ac_perf_mode_fast: self.session.design.set_performance_mode('fast') else: self.session.design.set_performance_mode('pretty') def on_animation_enabling_changed(self, action): if action == self.ac_anims_active: self.session.design.animations_enabled = True else: self.session.design.animations_enabled = False def on_design_action_triggered(self): index = self.flow_view_theme_actions.index(self.sender()) self.session.design.set_flow_theme(self.session.design.flow_themes[index]) def on_enable_info_msgs_triggered(self): rc.InfoMsgs.enable() def on_disable_info_msgs_triggered(self): rc.InfoMsgs.disable() def on_save_scene_pic_viewport_triggered(self): """Saves a picture of the currently visible viewport.""" if len(self.session.scripts) == 0: return file_path = QFileDialog.getSaveFileName(self, 'select file', '', 'PNG(*.png)')[0] script = self.ui.scripts_tab_widget.currentWidget().script view = self.session.flow_views[script] img = view.get_viewport_img() img.save(file_path) def on_save_scene_pic_whole_triggered(self): """Saves a picture of the whole currently visible scene.""" if len(self.session.scripts) == 0: return file_path = QFileDialog.getSaveFileName(self, 'select file', '', 'PNG(*.png)')[0] script = self.ui.scripts_tab_widget.currentWidget().script view = self.session.flow_views[script] img = view.get_whole_scene_img() img.save(file_path) def on_save_project_triggered(self): file_name = QFileDialog.getSaveFileName(self, 'select location and give file name', '../saves', '(*.json)')[0] if file_name != '': self.save_project(file_name) # SESSION def script_created(self, script, flow_view): script_widget = ScriptUI(self, script, flow_view) self.script_UIs.append(script_widget) self.ui.scripts_tab_widget.addTab(script_widget, script.title) def script_renamed(self, script): script_UI, index = self.get_script_ui(script) if index != -1: self.ui.scripts_tab_widget.setTabText( index, script.title ) def script_deleted(self, script): script_UI, index = self.get_script_ui(script) self.ui.scripts_tab_widget.removeTab(index) self.script_UIs.remove(script_UI) def get_script_ui(self, script): script_UI = None index = -1 for index in range(len(self.script_UIs)): sui = self.script_UIs[index] if sui.script == script: script_UI = sui break return script_UI, index def get_current_script(self): return self.session.scripts[self.ui.scripts_tab_widget.currentIndex()] def import_packages(self, packages_list: [NodesPackage]): for p in packages_list: self.import_nodes(p) def import_nodes(self, package: NodesPackage = None, path: str = None): if package is not None: p = package else: p = NodesPackage(path) try: nodes = import_nodes_package(p) except ModuleNotFoundError as e: QMessageBox.warning(self, title='Missing Python module', text=str(e)) sys.exit() self.session.register_nodes(nodes) for n in nodes: self.node_packages[n] = p # self.nodes_tree_widget.update_list() def save_project(self, file_name): import json file = None try: if os.path.exists(file_name): os.remove(file_name) file = open(file_name, 'w') except FileNotFoundError: rc.InfoMsgs.write('couldn\'t open file') return general_project_info_dict = {'type': 'Ryven project file'} scripts_data = self.session.serialize() required_packages = set() for node in self.session.all_node_objects(): if node.__class__ not in self.node_packages.keys() or \ self.node_packages[node.__class__] is None or \ self.node_packages[node.__class__].name == 'built_in': continue required_packages.add( self.node_packages[node.__class__] ) whole_project_dict = {'general info': general_project_info_dict, 'required packages': [p.config_data() for p in required_packages], **scripts_data} data = json.dumps(whole_project_dict, indent=4) rc.InfoMsgs.write(data) file.write(data) file.close()
def menu_actions(self): """ List of QtWidgets.QActions to be attached to this tool as a context menu. """ self.options = [] # WARNING: QAction labels are used to identify them. # Changing them can cause problems unless # all references are updated in this package. component_action_group = QActionGroup(self.tool_bar) action = QAction("Off", self.tool_bar, checkable=True) action.setChecked(True) action.setActionGroup(component_action_group) action.triggered.connect(self.viewer.remove_contour) self.options.append(action) action = QAction("Current Component", self.tool_bar, checkable=True) action.setActionGroup(component_action_group) action.triggered.connect(self.viewer.default_contour) self.options.append(action) action = QAction("Other Component", self.tool_bar, checkable=True) action.setActionGroup(component_action_group) action.triggered.connect(self.viewer.custom_contour) self.options.append(action) action = QAction(" ", self.tool_bar) action.setSeparator(True) self.options.append(action) action = QAction("Contour Settings", self.tool_bar) action.triggered.connect(self.viewer.edit_contour_settings) self.options.append(action) return self.options
def InitMenu(self): mainMenu = self.menubar fileMenu = mainMenu.addMenu('File') SaveFigAction = QAction('Save Figures', self) SaveFigAction.setShortcut('Ctrl+s') SaveFigAction.setStatusTip('Save all open figures') SaveFigAction.triggered.connect(self.SaveFigures) fileMenu.addAction(SaveFigAction) CloseFigsAction = QAction('Close Figures', self) CloseFigsAction.setStatusTip('Close all open figures') CloseFigsAction.triggered.connect(self.CloseFigures) fileMenu.addAction(CloseFigsAction) LoadConfAction = QAction('Load Configuration', self) LoadConfAction.setStatusTip('Load Config') LoadConfAction.triggered.connect(self.LoadConf) fileMenu.addAction(LoadConfAction) SaveConfAction = QAction('Save Configuration', self) SaveConfAction.setStatusTip('Save Config') SaveConfAction.triggered.connect(self.SaveConf) fileMenu.addAction(SaveConfAction)
class ObjectExplorer(QTreeView): nodevalue_changed = pyqtSignal(AbstractJsonItem) nodeproperty_changed = pyqtSignal(AbstractJsonItem) def __init__(self, rootnode: JsonNode, parent): super().__init__(parent) self.mainwindow = parent self.setModel(JsonDataModel(rootnode, self.mainwindow)) self.model().dataChanged.connect(self.data_changed) self.setItemDelegate(MyItemDelegate()) self.setDragDropMode(QTreeView.DragDrop) self.setDragEnabled(True) self.setAcceptDrops(True) self.setDropIndicatorShown(True) self.doubleClicked.connect(self.double_clicked) # context menu self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_contextmenu) # actions # properties action self.propertiesAction = QAction(self.tr("properties"), self) self.propertiesAction.setIcon(QIcon(pixmap("document_properties.png"))) self.propertiesAction.triggered.connect(self.show_properties) # edit action self.editAction = QAction(self.tr("edit value"), self) self.editAction.setShortcut("F2") self.editAction.setIcon(QIcon(pixmap("edit.png"))) self.editAction.triggered.connect(self.edit_value) # edit key action self.editkeyAction = QAction(self.tr("edit key"), self) self.editkeyAction.setIcon(QIcon(pixmap("kgpg_key1_kgpg.png"))) self.editkeyAction.triggered.connect(self.edit_key) # insert item action self.insertitemAction = QAction(self.tr("insert item"), self) self.insertitemAction.setIcon(QIcon(pixmap("list_add.png"))) self.insertitemAction.triggered.connect(self.insert_item) # insert node action self.insertnodeAction = QAction(self.tr("insert node"), self) self.insertnodeAction.setIcon(QIcon(pixmap("list_add.png"))) self.insertnodeAction.triggered.connect(self.insert_node) # remove item action self.removeitemAction = QAction(self.tr("remove"), self) self.removeitemAction.setIcon(QIcon(pixmap("list_remove"))) self.removeitemAction.triggered.connect(self.remove_item) def data_changed(self, topleft, bottomright, *args): node = topleft.internalPointer() if node is not None and isinstance(node, JsonItem): self.nodevalue_changed.emit(node) def double_clicked(self, *args, **kwargs): index = self.currentIndex() if not index.isValid(): return column = self.model().columns[index.column()] if column.name == "value": self.edit_value() else: self.show_properties() def edit_key(self): index = self.currentIndex() if index.isValid(): node = index.internalPointer() key, b = QInputDialog.getText( self, "Edit Json item", "Insert new key for item:", text=node.key ) if not b: return node.key = key try: # PyQt5 self.model().dataChanged.emit(index, index, [Qt.DisplayRole]) except TypeError: # PyQt4, PySide self.model().dataChanged.emit(index, index) def edit_value(self): index = self.currentIndex() if not index.isValid(): return i = self.model().index(index.row(), 2, index.parent()) self.edit(i) def insert_item(self): index = self.currentIndex() if index.isValid(): node = index.internalPointer() else: node = self.model().root key, b = QInputDialog.getText( self, "Insert Json item", "Insert key for new item:") if not b: return item = JsonItem(key) node.add(item) row = node.index(item) self.model().beginInsertRows(index, row, row) self.model().endInsertRows() def insert_node(self): index = self.currentIndex() parentnode = index.internalPointer() or self.model().root key, b = QInputDialog.getText( self, "Insert Json node", "Insert key for new node:") if not b: return node = JsonNode(key) parentnode.add(node) row = parentnode.index(node) self.model().beginInsertRows(index, row, row) self.model().endInsertRows() def mousePressEvent(self, event): index = self.indexAt(event.pos()) if not index.isValid(): self.setCurrentIndex(QModelIndex()) super().mousePressEvent(event) def refresh(self): self.model().refresh() def remove_item(self): index = self.currentIndex() self.model().beginRemoveRows(index.parent(), index.row(), index.row()) if index.isValid(): node = index.internalPointer() if node.parent is not None: node.parent.remove(node.key) self.model().refresh() self.model().endRemoveRows() def show_contextmenu(self, pos: QPoint): menu = QMenu(self) index = self.currentIndex() node = index.internalPointer() # insert item and node menu.addAction(self.insertitemAction) menu.addAction(self.insertnodeAction) # edit key if isinstance(node, (JsonNode, JsonItem)): menu.addSeparator() menu.addAction(self.editkeyAction) if isinstance(node, JsonItem): menu.addAction(self.editAction) self.editAction.setEnabled(not node.readonly) # remove if isinstance(node, (JsonNode, JsonItem)): menu.addSeparator() menu.addAction(self.removeitemAction) # properties if isinstance(node, JsonItem): menu.addSeparator() menu.addAction(self.propertiesAction) menu.setDefaultAction(self.propertiesAction) menu.popup(self.viewport().mapToGlobal(pos), self.editAction) def show_properties(self): index = self.currentIndex() node = index.internalPointer() if not (index.isValid() and isinstance(node, JsonItem)): return dlg = ItemPropertyDialog(node, self.parent()) if dlg.exec_() == QDialog.Accepted: self.nodeproperty_changed.emit(node)
class UiLinelistsWindow(object): # this code was taken as-is from the Designer. # Cleaning it up sounds like a lower priority # task for now. def setupUi(self, MainWindow, title): MainWindow.setWindowTitle(title) MainWindow.setObjectName("MainWindow") MainWindow.resize(500, 500) MainWindow.setMinimumSize(QSize(300, 350)) self.centralWidget = QWidget(MainWindow) self.centralWidget.setObjectName("centralWidget") self.gridLayout = QGridLayout(self.centralWidget) self.gridLayout.setContentsMargins(11, 11, 11, 11) self.gridLayout.setSpacing(6) self.gridLayout.setObjectName("gridLayout") self.horizontalLayout_5 = QHBoxLayout() self.horizontalLayout_5.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_5.setSpacing(6) self.horizontalLayout_5.setObjectName("horizontalLayout_5") self.lines_selected_label = QLabel(self.centralWidget) self.lines_selected_label.setObjectName("lines_selected_label") self.horizontalLayout_5.addWidget(self.lines_selected_label) self.label = QLabel(self.centralWidget) self.label.setObjectName("label") self.horizontalLayout_5.addWidget(self.label) self.draw_button = QPushButton(self.centralWidget) self.draw_button.setObjectName("draw_button") self.horizontalLayout_5.addWidget(self.draw_button) self.erase_button = QPushButton(self.centralWidget) self.erase_button.setObjectName("erase_button") self.horizontalLayout_5.addWidget(self.erase_button) self.dismiss_button = QPushButton(self.centralWidget) self.dismiss_button.setObjectName("dismiss_button") self.horizontalLayout_5.addWidget(self.dismiss_button) self.gridLayout.addLayout(self.horizontalLayout_5, 4, 0, 1, 1) self.verticalLayout_11 = QVBoxLayout() self.verticalLayout_11.setContentsMargins(11, 11, 11, 11) self.verticalLayout_11.setSpacing(6) self.verticalLayout_11.setObjectName("verticalLayout_11") self.tabWidget = QTabWidget(self.centralWidget) self.tabWidget.setObjectName("tabWidget") self.verticalLayout_11.addWidget(self.tabWidget) self.gridLayout.addLayout(self.verticalLayout_11, 0, 0, 1, 1) self.horizontalLayout_7 = QHBoxLayout() self.horizontalLayout_7.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_7.setSpacing(6) self.horizontalLayout_7.setObjectName("horizontalLayout_7") self.add_set_button = QPushButton(self.centralWidget) self.add_set_button.setObjectName("add_set_button") self.horizontalLayout_7.addWidget(self.add_set_button) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_7.addItem(spacerItem) self.gridLayout.addLayout(self.horizontalLayout_7, 2, 0, 2, 1) MainWindow.setCentralWidget(self.centralWidget) self.menuBar = QMenuBar(MainWindow) self.menuBar.setGeometry(QRect(0, 0, 767, 22)) self.menuBar.setObjectName("menuBar") self.menuFile = QMenu(self.menuBar) self.menuFile.setObjectName("menuFile") MainWindow.setMenuBar(self.menuBar) self.mainToolBar = QToolBar(MainWindow) self.mainToolBar.setMovable(False) self.mainToolBar.setFloatable(False) self.mainToolBar.setObjectName("mainToolBar") MainWindow.addToolBar(Qt.TopToolBarArea, self.mainToolBar) self.statusBar = QStatusBar(MainWindow) self.statusBar.setObjectName("statusBar") MainWindow.setStatusBar(self.statusBar) self.actionOpen = QAction(MainWindow) icon = QIcon() icon.addPixmap(QPixmap(":/img/Open Folder-48.png"), QIcon.Normal, QIcon.Off) self.actionOpen.setIcon(icon) self.actionOpen.setObjectName("actionOpen") self.actionExit = QAction(MainWindow) self.actionExit.setObjectName("actionExit") self.actionRemove = QAction(MainWindow) self.actionRemove.setObjectName("actionRemove") self.actionChange_Color = QAction(MainWindow) self.actionChange_Color.setObjectName("actionChange_Color") self.menuFile.addAction(self.actionOpen) self.menuFile.addSeparator() self.menuFile.addAction(self.actionExit) self.menuBar.addAction(self.menuFile.menuAction()) self.mainToolBar.addAction(self.actionOpen) self.mainToolBar.addSeparator() self.retranslateUi(MainWindow) QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QCoreApplication.translate self.lines_selected_label.setText(_translate("MainWindow", "0")) self.label.setText(_translate("MainWindow", "lines selected")) self.draw_button.setText(_translate("MainWindow", "Draw")) self.erase_button.setText(_translate("MainWindow", "Erase")) self.dismiss_button.setText(_translate("MainWindow", "Dismiss")) self.add_set_button.setText(_translate("MainWindow", "Add set")) self.menuFile.setTitle(_translate("MainWindow", "File")) self.actionOpen.setText(_translate("MainWindow", "Open")) self.actionExit.setText(_translate("MainWindow", "Exit")) self.actionRemove.setText(_translate("MainWindow", "Remove")) self.actionRemove.setToolTip( _translate("MainWindow", "Removes the selected layer")) self.actionChange_Color.setText( _translate("MainWindow", "Change Color")) self.actionChange_Color.setToolTip( _translate("MainWindow", "Change the line color selected layer"))
def __init__(self, *args): QAction.__init__(self, *args) self.triggered.connect(self.correct)
def setupUi(self, MainWindow, title): MainWindow.setWindowTitle(title) MainWindow.setObjectName("MainWindow") MainWindow.resize(500, 500) MainWindow.setMinimumSize(QSize(300, 350)) self.centralWidget = QWidget(MainWindow) self.centralWidget.setObjectName("centralWidget") self.gridLayout = QGridLayout(self.centralWidget) self.gridLayout.setContentsMargins(11, 11, 11, 11) self.gridLayout.setSpacing(6) self.gridLayout.setObjectName("gridLayout") self.horizontalLayout_5 = QHBoxLayout() self.horizontalLayout_5.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_5.setSpacing(6) self.horizontalLayout_5.setObjectName("horizontalLayout_5") self.lines_selected_label = QLabel(self.centralWidget) self.lines_selected_label.setObjectName("lines_selected_label") self.horizontalLayout_5.addWidget(self.lines_selected_label) self.label = QLabel(self.centralWidget) self.label.setObjectName("label") self.horizontalLayout_5.addWidget(self.label) self.draw_button = QPushButton(self.centralWidget) self.draw_button.setObjectName("draw_button") self.horizontalLayout_5.addWidget(self.draw_button) self.erase_button = QPushButton(self.centralWidget) self.erase_button.setObjectName("erase_button") self.horizontalLayout_5.addWidget(self.erase_button) self.dismiss_button = QPushButton(self.centralWidget) self.dismiss_button.setObjectName("dismiss_button") self.horizontalLayout_5.addWidget(self.dismiss_button) self.gridLayout.addLayout(self.horizontalLayout_5, 4, 0, 1, 1) self.verticalLayout_11 = QVBoxLayout() self.verticalLayout_11.setContentsMargins(11, 11, 11, 11) self.verticalLayout_11.setSpacing(6) self.verticalLayout_11.setObjectName("verticalLayout_11") self.tabWidget = QTabWidget(self.centralWidget) self.tabWidget.setObjectName("tabWidget") self.verticalLayout_11.addWidget(self.tabWidget) self.gridLayout.addLayout(self.verticalLayout_11, 0, 0, 1, 1) self.horizontalLayout_7 = QHBoxLayout() self.horizontalLayout_7.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_7.setSpacing(6) self.horizontalLayout_7.setObjectName("horizontalLayout_7") self.add_set_button = QPushButton(self.centralWidget) self.add_set_button.setObjectName("add_set_button") self.horizontalLayout_7.addWidget(self.add_set_button) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_7.addItem(spacerItem) self.gridLayout.addLayout(self.horizontalLayout_7, 2, 0, 2, 1) MainWindow.setCentralWidget(self.centralWidget) self.menuBar = QMenuBar(MainWindow) self.menuBar.setGeometry(QRect(0, 0, 767, 22)) self.menuBar.setObjectName("menuBar") self.menuFile = QMenu(self.menuBar) self.menuFile.setObjectName("menuFile") MainWindow.setMenuBar(self.menuBar) self.mainToolBar = QToolBar(MainWindow) self.mainToolBar.setMovable(False) self.mainToolBar.setFloatable(False) self.mainToolBar.setObjectName("mainToolBar") MainWindow.addToolBar(Qt.TopToolBarArea, self.mainToolBar) self.statusBar = QStatusBar(MainWindow) self.statusBar.setObjectName("statusBar") MainWindow.setStatusBar(self.statusBar) self.actionOpen = QAction(MainWindow) icon = QIcon() icon.addPixmap(QPixmap(":/img/Open Folder-48.png"), QIcon.Normal, QIcon.Off) self.actionOpen.setIcon(icon) self.actionOpen.setObjectName("actionOpen") self.actionExit = QAction(MainWindow) self.actionExit.setObjectName("actionExit") self.actionRemove = QAction(MainWindow) self.actionRemove.setObjectName("actionRemove") self.actionChange_Color = QAction(MainWindow) self.actionChange_Color.setObjectName("actionChange_Color") self.menuFile.addAction(self.actionOpen) self.menuFile.addSeparator() self.menuFile.addAction(self.actionExit) self.menuBar.addAction(self.menuFile.menuAction()) self.mainToolBar.addAction(self.actionOpen) self.mainToolBar.addSeparator() self.retranslateUi(MainWindow) QMetaObject.connectSlotsByName(MainWindow)
def mkButtons(self, nodes): # Remove+delete previous children layout = self.layout() for i in reversed(range(layout.count())): layout.itemAt(i).widget().setParent(None) if not nodes: return parent = nodes[0].parent if parent is not None: action = QAction("↑", self) action.setFont(self.font) action.triggered.connect( partial(self.showNode, parent.parent, direction="up")) action.setProperty("isMode", True) self.addAction(action) # Make separator pipe label = QAction("|", self) label.setFont(self.font) label.setDisabled(True) self.addAction(label) # Loop over each "GUIPlugin" plugin for node in reversed(list(nodes)): action = QAction(node.name, self) action.triggered.connect( partial(self.showNode, node, direction="down")) action.setFont(self.font) action.setProperty("isMode", True) action.setCheckable(True) action.setActionGroup(self.GUIPluginActionGroup) self.addAction(action) # Make separator pipe label = QAction("|", self) label.setFont(self.font) label.setDisabled(True) self.addAction(label) # Remove last separator if self.layout().count(): self.layout().takeAt( self.layout().count() - 1).widget().deleteLater() # Delete the last pipe symbol if parent is not None: # Make separator pipe label = QAction(">", self) label.setFont(self.font) label.setDisabled(True) self.addAction(label) action = QAction(parent.name, self) action.setFont(self.font) action.setProperty("isMode", True) action.setDisabled(True) action.setActionGroup(self.GUIPluginActionGroup) self.addAction(action) self.fadeIn()
def help(self): action = QAction(self.app.ui.help_icon, "Help") action.setToolTip("Help") action.setToolTip("Show help window, Shortcuts : F1") action.setShortcuts(["F1"]) return action