def addToolbars(self): mypath = respath + '/icons/' self.listViewAction = QtWidgets.QAction(QtGui.QIcon(mypath + 'listView.png'), '&List View', self, triggered=self.listView) self.symbolViewAction = QtWidgets.QAction( QtGui.QIcon(mypath + 'symbolView.png'), '&Symbol View', self, triggered=self.symbolView) self.addLibraryAction = QtWidgets.QAction( QtGui.QIcon(mypath + 'addLibrary.png'), '&Add Library', self, triggered=self.addLibrary) self.importMyhdlLAction = QtWidgets.QAction(QtGui.QIcon(mypath + 'import.png'), '&Import MyHDL', self, triggered=self.importMyhdl) self.toolbar = self.addToolBar('File') self.toolbar.addAction(self.listViewAction) self.toolbar.addAction(self.symbolViewAction) self.toolbar.addAction(self.addLibraryAction) self.toolbar.addAction(self.importMyhdlLAction)
def __init__(self, parent=get_maya_window()): super(MattesController, self).__init__(parent=parent) load_action = QtWidgets.QAction('&Load', self) load_action.triggered.connect(self.load) save_action = QtWidgets.QAction('&Save', self) save_action.triggered.connect(self.save) self.file_menu.addAction(load_action) self.file_menu.addAction(save_action) self.matte_list.itemSelectionChanged.connect(self.matte_list_select) self.obj_list.itemSelectionChanged.connect(self.obj_list_select) self.button_new.clicked.connect(self.new_clicked) self.button_refresh.clicked.connect(self.refresh_matte_list) self.button_help.clicked.connect(self.show_help) self.button_add.clicked.connect(self.add_clicked) self.button_red.clicked.connect(self.color_clicked(1, 0, 0)) self.button_green.clicked.connect(self.color_clicked(0, 1, 0)) self.button_blue.clicked.connect(self.color_clicked(0, 0, 1)) self.button_white.clicked.connect(self.color_clicked(1, 1, 1)) self.button_black.clicked.connect(self.color_clicked(0, 0, 0)) self.maya_hooks = MayaHooks(parent=self) self.maya_hooks.before_scene_changed.connect(self.clear_lists) self.maya_hooks.scene_changed.connect(self.refresh_matte_list) self.maya_hooks.scene_selection_changed.connect(self.scene_sel_changed) self.refresh_matte_list()
def _show_actions(self): if self.project_name is None: return menu = QtWidgets.QMenu(self) actions_mapping = {} if self.project_name == DEFAULT_PROJECT_KEY: remove_label = LABEL_REMOVE_DEFAULT add_label = LABEL_ADD_DEFAULT else: remove_label = LABEL_REMOVE_PROJECT add_label = LABEL_ADD_PROJECT has_value = self._get_local_settings_item(self.project_name) if has_value: action = QtWidgets.QAction(remove_label) callback = self._remove_from_local else: action = QtWidgets.QAction(add_label) callback = self._add_to_local actions_mapping[action] = callback menu.addAction(action) if self.is_modified(): discard_changes_action = QtWidgets.QAction(LABEL_DISCARD_CHANGES) actions_mapping[discard_changes_action] = self.discard_changes menu.addAction(discard_changes_action) result = menu.exec_(QtGui.QCursor.pos()) if result: to_run = actions_mapping[result] if to_run: to_run()
def create_help_menu_items(menu, tool_help_func=None): label = 'Tool Help...' if callable(tool_help_func) is False: label = 'Help...' tool_help_func = _launch_default_help_page tooltip = 'Show help for this tool.' action = QtWidgets.QAction(label, menu) action.setStatusTip(tooltip) action.triggered.connect(tool_help_func) menu.addAction(action) label = 'System Information...' tooltip = 'Display detailed information about software and hardware.' action = QtWidgets.QAction(label, menu) action.setStatusTip(tooltip) action.triggered.connect(_launch_sysinfo_window) menu.addAction(action) label = 'About mmSolver...' tooltip = 'About the Maya MatchMove Solver project.' action = QtWidgets.QAction(label, menu) action.setStatusTip(tooltip) action.triggered.connect(_launch_about_window) menu.addAction(action) return
def groceryTreeMenuRequested(self,point): treeItem = self.uiGroceryTreeWidget.itemAt(point) if treeItem is None: return None if treeItem.text(1) == '': return None self.currentItem = treeItem menu = QtWidgets.QMenu(parent = self) actEditItem = QtWidgets.QAction('Edit Item',self) actRemoveItem = QtWidgets.QAction('Remove Item',self) actAddNote = QtWidgets.QAction('View/Edit Note',self) actClearNotes = QtWidgets.QAction('Clear Notes',self) menu.addAction(actEditItem) menu.addAction(actRemoveItem) menu.addSeparator() menu.addAction(actAddNote) menu.addAction(actClearNotes) actRemoveItem.triggered.connect(self.removeItem) actEditItem.triggered.connect(self.editItem) actAddNote.triggered.connect(self.addNoteToCurrentItem) actClearNotes.triggered.connect(self.clearCurrentItemNotes) menu.exec_(self.uiGroceryTreeWidget.mapToGlobal(point))
def on_view_horizontalHeader_sectionClicked(self, logicalIndex): self.logicalIndex = logicalIndex self.menuValues = QtWidgets.QMenu(self) self.signalMapper = QtCore.QSignalMapper(self) self.comboBox.blockSignals(True) self.comboBox.setCurrentIndex(self.logicalIndex) self.comboBox.blockSignals(True) valuesUnique = [ self.model.item(row, self.logicalIndex).text() for row in range(self.model.rowCount()) ] actionAll = QtWidgets.QAction("All", self) actionAll.triggered.connect(self.on_actionAll_triggered) self.menuValues.addAction(actionAll) self.menuValues.addSeparator() for actionNumber, actionName in enumerate( sorted(list(set(valuesUnique)))): action = QtWidgets.QAction(actionName, self) self.signalMapper.setMapping(action, actionNumber) action.triggered.connect(self.signalMapper.map) self.menuValues.addAction(action) self.signalMapper.mapped.connect(self.on_signalMapper_mapped) self.headerPos = self.view.mapToGlobal(self.horizontalHeader.pos()) posY = self.headerPos.y() + self.horizontalHeader.height() posX = self.headerPos.x() + self.horizontalHeader.sectionPosition( self.logicalIndex) self.menuValues.exec_(QtCore.QPoint(posX, posY))
def create_tool_bar(self): init_tool_bar = QtWidgets.QToolBar() # Create expose button expose_action = QtWidgets.QAction(MIcon.MIcon("visible"), 'Show', self) expose_action.setShortcut('Shift+H') expose_action.triggered.connect( self.expose_ndynamic_nodes_in_playground_selected_in_outliner) init_tool_bar.addAction(expose_action) # Create hide button hide_action = QtWidgets.QAction(MIcon.MIcon("shy"), 'Hide', self) hide_action.setShortcut('Ctrl+H') hide_action.triggered.connect( self.hide_ndynamic_nodes_in_playground_selected_in_outliner) init_tool_bar.addAction(hide_action) # Create settings button settings_action = QtWidgets.QAction(MIcon.MIcon("settings"), 'Settings', self) settings_action.triggered.connect(self.settings) init_tool_bar.addAction(settings_action) # Create info button info_action = QtWidgets.QAction(MIcon.MIcon("info"), 'Info', self) info_action.setShortcut('F1') info_action.triggered.connect(MMessageBox.AboutNClothUiMessageBox) init_tool_bar.addAction(info_action) # Create quit Button exit_action = QtWidgets.QAction(MIcon.MIcon("quit"), 'Quit', self) exit_action.triggered.connect(self.close) init_tool_bar.addAction(exit_action) return init_tool_bar
def add_module(self, item, parent_menu): """Inicialize object of module and add it to context. :param item: item from presets containing information about module :type item: dict :param parent_menu: menu where module's submenus/actions will be add :type parent_menu: QtWidgets.QMenu :returns: success of module implementation :rtype: bool REQUIRED KEYS (item): :import_path (*str*): - full import path as python's import - e.g. *"path.to.module"* :fromlist (*list*): - subparts of import_path (as from is used) - e.g. *["path", "to"]* OPTIONAL KEYS (item): :title (*str*): - represents label shown in services menu - import_path is used if title is not set - title is not used at all if module is not a service .. note:: Module is added as **service** if object does not have *tray_menu* method. """ import_path = item.get('import_path', None) title = item.get('title', import_path) fromlist = item.get('fromlist', []) try: module = __import__("{}".format(import_path), fromlist=fromlist) obj = module.tray_init(self.tray_widget, self.main_window) name = obj.__class__.__name__ if hasattr(obj, 'tray_menu'): obj.tray_menu(parent_menu) else: if self.services_submenu is None: self.services_submenu = QtWidgets.QMenu( 'Services', self.tray_widget.menu) action = QtWidgets.QAction(title, self.services_submenu) action.setIcon(self.icon_run) self.services_submenu.addAction(action) if hasattr(obj, 'set_qaction'): obj.set_qaction(action, self.icon_failed) self.modules[name] = obj self.log.info("{} - Module imported".format(title)) except ImportError as ie: if self.services_submenu is None: self.services_submenu = QtWidgets.QMenu( 'Services', self.tray_widget.menu) action = QtWidgets.QAction(title, self.services_submenu) action.setIcon(self.icon_failed) self.services_submenu.addAction(action) self.log.warning("{} - Module import Error: {}".format( title, str(ie)), exc_info=True) return False return True
def __init__(self, parent=None): super(SocketTool, self).__init__(parent=parent) ui_file = os.path.join(__file__, "..", "skeletal_socket_tool.ui") load_ui(ui_file, self) self.model = MTableModel() header_list = [u"骨骼", u"插槽"] self.header_list = [ { "label": data, "key": data, "editable": True, "selectable": True, "width": 400, } for data in header_list ] self.model.set_header_list(self.header_list) self.model_sort = MSortFilterModel() self.model_sort.setSourceModel(self.model) self.Table_View.setShowGrid(True) self.Table_View.setModel(self.model_sort) header = self.Table_View.horizontalHeader() header.setStretchLastSection(True) self.popMenu = QtWidgets.QMenu(self) action = QtWidgets.QAction(u"删除选择", self) action.triggered.connect(self.remove_line) self.popMenu.addAction(action) action = QtWidgets.QAction(u"添加一行", self) action.triggered.connect(self.add_line) self.popMenu.addAction(action) self.Table_View.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.Table_View.customContextMenuRequested.connect(self.on_context_menu) self.Close_Action.triggered.connect(self.close) self.Export_CSV_Action.triggered.connect(self.export_csv) self.Import_CSV_Action.triggered.connect(self.import_csv) self.Help_Action.triggered.connect( lambda: webbrowser.open_new_tab( "http://wiki.l0v0.com/unreal/PyToolkit/#/anim/2_skeletal_socket_tool" ) ) self.Socket_BTN.clicked.connect(self.add_socket) self.Clear_BTN.clicked.connect(self.clear_socket) # NOTE 读取 csv self.settings = QtCore.QSettings( "%s.ini" % self.__class__.__name__, QtCore.QSettings.IniFormat ) csv_file = self.settings.value("csv_file") # csv_file = os.path.join(__file__,"..","test.csv") if csv_file and os.path.exists(csv_file): self.handle_csv(csv_file)
def tabDialog(self): # This is the default tab # tabA = libraryTab(DIRECTORY) # first create the libraries defined in the settings file libs = self.settings(mode="load") junkPaths = [] for item in libs: name = item[0] path = item[1] if not os.path.exists(path): logger.warning( "Cannot reach library path: \n%s \n Removing from the database..." % (path)) junkPaths.append(item) continue preTab = libraryTab(path) self.addTab(preTab, name) preTab.setLayout(preTab.layout) ## Remove the junk paths from the config file for x in junkPaths: self.settings(mode="remove", item=x) if len(libs) == 0: self.createNewTab() self.addNew = QtWidgets.QWidget() # self.addNew.installEventFilter(self.addNew) self.addTab(self.addNew, "+") self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) # self.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) self.customContextMenuRequested.connect(self.on_context_menu) self.tabsRightMenu = QtWidgets.QMenu() renameTabAction = QtWidgets.QAction('Rename', self) self.tabsRightMenu.addAction(renameTabAction) # renameTabAction.triggered.connect(self.renameLibrary) renameTabAction.triggered.connect( lambda val="rename": self.settings(mode=val)) repathTabAction = QtWidgets.QAction('Re-path', self) self.tabsRightMenu.addAction(repathTabAction) # renameTabAction.triggered.connect(self.renameLibrary) repathTabAction.triggered.connect( lambda val="repath": self.settings(mode=val)) removeTabAction = QtWidgets.QAction('Remove Selected Library', self) self.tabsRightMenu.addAction(removeTabAction) removeTabAction.triggered.connect(self.deleteCurrentTab) self.currentChanged.connect(self.createNewTab) # changed!
def __init__(self, parent): super(nukeContextMenu, self).__init__('Nuke') self.par = parent self.setTearOffEnabled(1) self.setWindowTitle('MSE %s Nuke' % self.par.ver) self.addAction(QtWidgets.QAction('Read PyScript Knob', parent, triggered=self.readPyScriptKnob)) self.addAction(QtWidgets.QAction('Save To PyScript Knob', parent, triggered=self.saveToKnob)) self.addSeparator() self.addAction(QtWidgets.QAction('From Selected', parent, triggered=self.nodeToCode)) self.addAction(QtWidgets.QAction('From Clipboard', parent, triggered=self.nodesFromClipboard))
def fileItemRightClickEvent(self): self.menu = QtWidgets.QMenu(self) remove_action = QtWidgets.QAction(u'删除选择', self) remove_action.triggered.connect(self.fileRemoveItem) clear_action = QtWidgets.QAction(u'清空全部', self) clear_action.triggered.connect(self.itemClear) self.menu.addAction(remove_action) self.menu.addAction(clear_action) self.menu.popup(QtGui.QCursor.pos())
def right_menu(self): self.menu = QtWidgets.QMenu(self) # NOTE 右键选择资源 select_asset = QtWidgets.QAction(u'选择资源', self) select_asset.triggered.connect(self.sync_asset) select_assets = QtWidgets.QAction(u'选择已选中的资源', self) select_assets.triggered.connect(self.sync_assets) self.menu.addAction(select_asset) self.menu.addAction(select_assets) self.menu.popup(QtGui.QCursor.pos())
def __init__(self, asset, parent=None): super(PlacerItem, self).__init__(parent) # self.placer_win = parent layout = QtWidgets.QVBoxLayout() self.setLayout(layout) self.Image = QtWidgets.QLabel() self.Image.setAlignment(QtCore.Qt.AlignCenter) self.Label = QtWidgets.QLabel() self.Label.setAlignment(QtCore.Qt.AlignCenter) self.Label.setWordWrap(True) self.Label.setScaledContents(True) self.Label.setStyleSheet("font-size:10px") self.Label.setMinimumHeight(30) self.Label.setWordWrap(True) # font = self.Label.font() layout.addWidget(self.Image) layout.addWidget(self.Label) self.asset = asset asset_name = str(asset.get_name()) if len(asset_name) >= 8: asset_name = "%s\n%s" % (asset_name[:8], asset_name[8:]) self.Label.setText(asset_name) self.item_path = asset.get_full_name().split(" ")[-1] self.setToolTip(self.item_path) # NOTE 设置 menu 对象 self.menu = QtWidgets.QMenu(self) locate_action = QtWidgets.QAction(u"定位资源", self) locate_action.triggered.connect(self.locate_item) open_action = QtWidgets.QAction(u"打开路径", self) open_action.triggered.connect(self.open_item) copy_action = QtWidgets.QAction(u"复制名称", self) copy_action.triggered.connect(self.open_item_name) remove_action = QtWidgets.QAction(u"删除资源", self) remove_action.triggered.connect(self.remove_items) self.menu.addAction(locate_action) self.menu.addAction(open_action) self.menu.addAction(copy_action) # self.menu.addAction(remove_action) # NOTE 设置右键菜单 self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.popup_menu)
def fillThemeMenu(self): self.theme_menu.clear() self.theme_menu.addAction( QtWidgets.QAction('Edit...', self, triggered=self.openThemeEditor)) self.theme_menu.addSeparator() self.theme_menu.addAction( QtWidgets.QAction('default', self, triggered=lambda: self.applyTheme('default'))) data = self.s.readSettings() if data.get('colors'): for t in data.get('colors').keys(): self.theme_menu.addAction( QtWidgets.QAction( t, self, triggered=lambda x=t: self.applyTheme(x)))
def _getUI(element, parent): if element.tag not in {"Menu", "Action", "Separator"}: return None if element.tag == "Menu": m = QtWidgets.QMenu(parent) m.setTitle(element.attrib.get("label", "").decode("utf8")) return m if element.tag == "Action": a = QtWidgets.QAction( element.attrib.get("label", "").decode("utf8"), parent) return a if element.tag == "Separator": s = QtWidgets.QAction(parent) s.setSeparator(True) return s
def addContextMenu(self, widget, name, command, icon=None, tintNormal=True): """ Add context menu item to widget. 'widget' should be a Push Button or Tool Button. 'name' is the text to be displayed in the menu. 'command' is the function to run when the item is triggered. 'icon' is a pixmap to use for the item's icon (optional). """ widget.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) # Remove illegal characters from name actionName = "action%s" % re.sub(r"[^\w]", "_", name) action = QtWidgets.QAction(name, None) if icon: action.setIcon(self.iconSet(icon, tintNormal=tintNormal)) action.setObjectName(actionName) action.triggered.connect(command) widget.addAction(action) # Make a class-scope reference to this object # (won't work without it for some reason) exec_str = "self.%s = action" % actionName exec(exec_str)
def _rcmenu(self, x): menu = QtWidgets.QMenu(self) new_dir = QtWidgets.QAction(self) new_dir.setText('New Directory') new_dir.triggered.connect(self._gen_new_dir) menu.addAction(new_dir) menu.exec_(self.mapToGlobal(x))
def build_ui(self): if self.settings.value("geometry"): self.restoreGeometry(self.settings.value("geometry")) else: self.resize(600, 400) lay = QtWidgets.QVBoxLayout() self.setLayout(lay) self.toolBar = QtWidgets.QToolBar('Main') self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextOnly) lay.addWidget(self.toolBar) openAction = QtWidgets.QAction('Open...', self) openAction.setShortcut('Ctrl+o') openAction.triggered.connect(self.manualOpen) self.toolBar.addAction(openAction) logger.info('building nodes') configPath = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'nodz_config.json') self.nodz = nodz_main.Nodz(None, configPath=configPath) lay.addWidget(self.nodz) self.nodz.initialize()
def contextMenuEvent(self, event): LOG.debug('Object TreeView Context Menu Event: %r', event) menu = QtWidgets.QMenu(self) label = 'Select Marker / Bundle' swap_sel_act = QtWidgets.QAction(label, self) swap_sel_act.triggered.connect(self.selection_swap) label = 'Select Marker + Bundle' both_sel_act = QtWidgets.QAction(label, self) both_sel_act.triggered.connect(self.selection_both_markers_bundles) menu.addAction(swap_sel_act) menu.addAction(both_sel_act) menu.exec_(event.globalPos()) return
def add_command(menu, name, func=None, parent=None, shortcut=None): action = QtWidgets.QAction(name, parent) if shortcut: action.setShortcut(shortcut) if func: action.triggered.connect(func) menu.addAction(action)
def on_plugin_action_menu_requested(self, pos): """The user right-clicked on a plug-in __________ | | | Action 1 | | Action 2 | | Action 3 | | | |__________| """ index = self.data["views"]["right"].indexAt(pos) actions = index.data(model.Actions) if not actions: return menu = QtWidgets.QMenu(self) plugin = self.data["models"]["plugins"].items[index.row()] for action in actions: qaction = QtWidgets.QAction(action.label or action.__name__, self) qaction.triggered.connect( lambda p=plugin, a=action: self.act(p, a)) menu.addAction(qaction) menu.popup(self.data["views"]["right"].viewport().mapToGlobal(pos))
def _add_version_item(self): config_file_path = os.path.join(os.environ["PYPE_SETUP_PATH"], "pypeapp", "config.ini") default_config = {} if os.path.exists(config_file_path): config = configparser.ConfigParser() config.read(config_file_path) try: default_config = config["CLIENT"] except Exception: pass subversion = default_config.get("subversion") client_name = default_config.get("client_name") version_string = pype.version.__version__ if subversion: version_string += " ({})".format(subversion) if client_name: version_string += ", {}".format(client_name) version_action = QtWidgets.QAction(version_string, self.tray_widget) self.tray_widget.menu.addAction(version_action) self.add_separator(self.tray_widget.menu)
def on_plugin_action_menu_requested(self, pos): """The user right-clicked on a plug-in __________ | | | Action 1 | | Action 2 | | Action 3 | | | |__________| """ index = self.overview_plugin_view.indexAt(pos) actions = index.data(Roles.PluginValidActionsRole) if not actions: return menu = QtWidgets.QMenu(self) plugin_id = index.data(Roles.ObjectIdRole) plugin_item = self.plugin_model.plugin_items[plugin_id] print("plugin is: %s" % plugin_item.plugin) for action in actions: qaction = QtWidgets.QAction(action.label or action.__name__, self) qaction.triggered.connect(partial(self.act, plugin_item, action)) menu.addAction(qaction) menu.popup(self.overview_plugin_view.viewport().mapToGlobal(pos))
def setMaxItemCount(self, count): style = self.style() opt = QtWidgets.QStyleOptionMenuItem() opt.initFrom(self) a = QtWidgets.QAction("fake action", self) self.initStyleOption(opt, a) size = QtCore.QSize() fm = self.fontMetrics() qfm = opt.fontMetrics size.setWidth( fm.boundingRect(QtCore.QRect(), QtCore.Qt.TextSingleLine, a.text()).width() ) size.setHeight(max(fm.height(), qfm.height())) self.defaultItemHeight = style.sizeFromContents( style.CT_MenuItem, opt, size, self ).height() if not count: self.setMaximumHeight(self._maximumHeight) else: fw = style.pixelMetric(style.PM_MenuPanelWidth, None, self) vmargin = style.pixelMetric(style.PM_MenuHMargin, opt, self) scrollHeight = self.scrollHeight(style) self.setMaximumHeight( self.defaultItemHeight * count + (fw + vmargin + scrollHeight) * 2 ) self.dirty = True
def openMenu(self): menu = QtWidgets.QMenu(self) menu.addAction( QtWidgets.QAction('Rename Current Tab', self, triggered=self.renameTab)) menu.exec_(QtGui.QCursor.pos())
def __init__(self, stage_model, node_path, widget, items=None, parent=None): super(ContextMenu, self).__init__(parent=parent) self.setStyleSheet( 'background-color: #232323; border: 1px solid #3E3E3E') self.stage_model = stage_model self.node_path = node_path self.widget = widget # add context menu to widget self.widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.widget.customContextMenuRequested.connect(self.show_menu) self.widget.menu = self # add menu items items = items or [] for item in items: if item == 'separator': self.addSeparator() else: self.addAction(item) # add node selection item if items: self.addSeparator() node_action = QtWidgets.QAction('Select NXT Node', self) node_action.triggered.connect(self.select_node) self.addAction(node_action)
def show_actions_menu(self, event=None): if event and event.button() != QtCore.Qt.RightButton: return if not self.allow_actions: if event: return self.mouseReleaseEvent(event) return menu = QtWidgets.QMenu(self) actions_mapping = {} self._discard_changes_action(menu, actions_mapping) self._add_to_studio_default(menu, actions_mapping) self._remove_from_studio_default_action(menu, actions_mapping) self._add_to_project_override_action(menu, actions_mapping) self._remove_from_project_override_action(menu, actions_mapping) if not actions_mapping: action = QtWidgets.QAction("< No action >") actions_mapping[action] = None menu.addAction(action) result = menu.exec_(QtGui.QCursor.pos()) if result: to_run = actions_mapping[result] if to_run: to_run()
def add_menu_item(self, text, callback, icon=None): menu_item = QtWidgets.QAction(text, parent=self) menu_item.triggered.connect(callback) if icon: menu_item.setIcon(QtGui.QIcon(icon, pix(24), pix(24))) self.menu.addAction(menu_item) self.menu_button.show()
def _add_to_project_override_action(self, menu, actions_mapping): if not self.entity.can_add_to_project_override: return action = QtWidgets.QAction("Add to project project override") actions_mapping[action] = self.entity.add_to_project_override menu.addAction(action)