def _create_context_menu(self): self._context_menu = QMenu() move_up_icon = resources.icon('sort_up') move_down_icon = resources.icon('sort_down') rename_icon = resources.icon('rename') remove_icon = resources.icon('delete') copy_icon = resources.icon('copy') move_up_action = QAction(move_up_icon, 'Move Up', self._context_menu) self._context_menu.addAction(move_up_action) move_down_action = QAction(move_down_icon, 'Move Down', self._context_menu) self._context_menu.addAction(move_down_action) self._context_menu.addSeparator() copy_action = QAction(copy_icon, 'Copy', self._context_menu) self._context_menu.addAction(copy_action) rename_action = QAction(rename_icon, 'Rename', self._context_menu) self._context_menu.addAction(rename_action) remove_action = QAction(remove_icon, 'Remove', self._context_menu) self._context_menu.addAction(remove_action) move_up_action.triggered.connect(self.move_up) move_down_action.triggered.connect(self.move_down) rename_action.triggered.connect(self.rename) remove_action.triggered.connect(self.remove)
def __init__(self, url): super().__init__() self.setAttribute(Qt.WA_DeleteOnClose, True) self.progress = 0 f = QFile() f.setFileName(":/jquery.min.js") f.open(QIODevice.ReadOnly) self.jQuery = f.readAll().data().decode() self.jQuery += "\nvar qt = { 'jQuery': jQuery.noConflict(true) };" f.close() self.view = QWebEngineView(self) self.view.load(url) self.view.loadFinished.connect(self.adjustLocation) self.view.titleChanged.connect(self.adjustTitle) self.view.loadProgress.connect(self.setProgress) self.view.loadFinished.connect(self.finishLoading) self.locationEdit = QLineEdit(self) self.locationEdit.setSizePolicy( QSizePolicy.Expanding, self.locationEdit.sizePolicy().verticalPolicy()) self.locationEdit.returnPressed.connect(self.changeLocation) toolBar = self.addToolBar(self.tr("Navigation")) toolBar.addAction(self.view.pageAction(QWebEnginePage.Back)) toolBar.addAction(self.view.pageAction(QWebEnginePage.Forward)) toolBar.addAction(self.view.pageAction(QWebEnginePage.Reload)) toolBar.addAction(self.view.pageAction(QWebEnginePage.Stop)) toolBar.addWidget(self.locationEdit) viewMenu = self.menuBar().addMenu(self.tr("&View")) viewSourceAction = QAction(self.tr("Page Source"), self) viewSourceAction.triggered.connect(self.viewSource) viewMenu.addAction(viewSourceAction) effectMenu = self.menuBar().addMenu(self.tr("&Effect")) effectMenu.addAction(self.tr("Highlight all links"), self.highlightAllLinks) self.rotateAction = QAction(self) self.rotateAction.setIcon(self.style().standardIcon( QStyle.SP_FileDialogDetailedView)) self.rotateAction.setCheckable(True) self.rotateAction.setText(self.tr("Turn images upside down")) self.rotateAction.toggled.connect(self.rotateImages) effectMenu.addAction(self.rotateAction) toolsMenu = self.menuBar().addMenu(self.tr("&Tools")) toolsMenu.addAction(self.tr("Remove GIF images"), self.removeGifImages) toolsMenu.addAction(self.tr("Remove all inline frames"), self.removeInlineFrames) toolsMenu.addAction(self.tr("Remove all object elements"), self.removeObjectElements) toolsMenu.addAction(self.tr("Remove all embedded elements"), self.removeEmbeddedElements) self.setCentralWidget(self.view)
def __init__(self, parent: QWidget = None): super().__init__(parent) self.map = LightMaps() self.setCentralWidget(self.map) self.map.setFocus() osloAction = QAction(self.tr("&Oslo"), self) berlinAction = QAction(self.tr("&Berlin"), self) jakartaAction = QAction(self.tr("&Jakarta"), self) nightModeAction = QAction(self.tr("Night Mode"), self) nightModeAction.setCheckable(True) nightModeAction.setChecked(False) osmAction = QAction(self.tr("About OpenStreetMap"), self) osloAction.triggered.connect(self.chooseOslo) berlinAction.triggered.connect(self.chooseBerlin) jakartaAction.triggered.connect(self.chooseJakarta) nightModeAction.triggered.connect(self.map.toggleNightMode) osmAction.triggered.connect(self.aboutOsm) menu = self.menuBar().addMenu(self.tr("&Options")) menu.addAction(osloAction) menu.addAction(berlinAction) menu.addAction(jakartaAction) menu.addSeparator() menu.addAction(nightModeAction) menu.addAction(osmAction) self.setWindowTitle(self.tr("Light Maps"))
def __init__(self, page, parent=None): super(HelpForm, self).__init__(parent) self.setAttribute(Qt.WA_DeleteOnClose) self.setAttribute(Qt.WA_GroupLeader) backAction = QAction(QIcon(":/back.png"), "&Back", self) backAction.setShortcut(QKeySequence.Back) homeAction = QAction(QIcon(":/home.png"), "&Home", self) homeAction.setShortcut("Home") self.pageLabel = QLabel() toolBar = QToolBar() toolBar.addAction(backAction) toolBar.addAction(homeAction) toolBar.addWidget(self.pageLabel) self.textBrowser = QTextBrowser() layout = QVBoxLayout() layout.addWidget(toolBar) layout.addWidget(self.textBrowser, 1) self.setLayout(layout) backAction.triggered.connect(self.tbackward) homeAction.triggered.connect(self.thome) self.textBrowser.sourceChanged.connect(self.updatePageTitle) self.textBrowser.setSearchPaths([":/help"]) self.textBrowser.setSource(QUrl(page)) self.resize(400, 600) self.setWindowTitle("{0} Help".format(QApplication.applicationName()))
def _toolbar_example(self): def _collapse(): tool_bar.collapse() def _set_icon_color(): tool_bar.set_icon_color(QColor(255, 255, 0)) toolbar_widget = QWidget(parent=self) toolbar_layout = layouts.VerticalLayout() toolbar_widget.setLayout(toolbar_layout) tool_bar = toolbar.ToolBar(parent=self) tool_bar.set_children_height(50) toolbar_layout.addWidget(tool_bar) line_edit = lineedit.BaseLineEdit(parent=self) line_edit.setObjectName('hello') collapse_action = tool_bar.addAction('Collapse') tool_bar.addWidget(line_edit) tool_bar.addAction(resources.icon('add'), 'Plus') color_action = QAction('Yellow', None) tool_bar.insertAction('Plus', color_action) collapse_action.triggered.connect(_collapse) color_action.triggered.connect(_set_icon_color) self.main_layout.addWidget(buttons.BaseButton('Hello')) self.main_layout.addStretch() return toolbar_widget
def showContextMenu(self, pos): self.row = self.propertiesTableView.indexAt(pos).row() self.menu = QMenu(self) deleteRowAction = QAction('Delete', self) deleteRowAction.triggered.connect(self.deleteRow) self.menu.addAction(deleteRowAction) # add other required actions self.menu.popup(QCursor.pos())
def _create_group_context_menu(self, group, menu): self._create_context_menu(menu=menu, parent=group) group.copy_action.setVisible(False) string_icon = resources.icon('rename') remove_icon = resources.icon('trash') rename_action = QAction(string_icon, 'Rename', menu) menu.addAction(rename_action) remove_action = QAction(remove_icon, 'Remove', menu) menu.addAction(remove_action) rename_action.triggered.connect(group.rename) remove_action.triggered.connect(group.remove) return menu
def __init__(self, mainwindow): self.main = mainwindow self.main.sourceDescription.stateChanged.connect(self.updateDisplay) self.groupIcon = QIcon() self.groupIcon.addPixmap( mainwindow.style().standardPixmap(QStyle.SP_DirClosedIcon), QIcon.Normal, QIcon.Off, ) self.groupIcon.addPixmap( mainwindow.style().standardPixmap(QStyle.SP_DirOpenIcon), QIcon.Normal, QIcon.On, ) self.keyIcon = QIcon() self.keyIcon.addPixmap(mainwindow.style().standardPixmap( QStyle.SP_FileIcon)) self.main.treeView.itemSelectionChanged.connect(self.updateDisplay) self.main.tracePattern.textChanged.connect(self.updateDisplay) self.main.availableSignals.stateChanged.connect(self.updateDisplay) self.main.treeView.setContextMenuPolicy( Qt.CustomContextMenu) # Enable popup menus # Context menu self.main.treeView.customContextMenuRequested.connect( self.handlePopupMenu) # Context menu actions self.actionAdd = QAction("Add", self.main, statusTip="Add a new source") self.actionDelete = QAction("Delete", self.main, statusTip="Remove source from tree") self.actionDelete.triggered.connect(self.deleteSource) self.actionConfig = QAction("Configure", self.main, statusTip="Configure source") self.actionConfig.triggered.connect(self.configureSource)
def _on_open_menu(self): """ Internal function that is called when the user opens the context menu of the tab menu bar :param pos: QPos """ menu = QMenu(self) menu.addAction( QAction('Rename Current Tab', self, triggered=self._on_rename_tab)) menu.exec_(QCursor.pos())
def context_menu(self, menu, items=None): """ Returns the context menu for the item :return: QMenu """ self._select_content_action = QAction(resources.icon('cursor'), 'Select content', menu) self._select_content_action.triggered.connect(self.select_content) menu.addAction(self._select_content_action) menu.addSeparator()
def reload(self): """ Reloads current menu data """ self.clear() if self._enable_select_content: select_content_action = QAction(resources.icon('cursor'), 'Select content', self) select_content_action.triggered.connect(self.item().select_content) self.addAction(select_content_action) self.addSeparator() selection_sets = self.selection_sets() if not selection_sets: action = QAction('No selection sets found!', self) action.setEnabled(False) self.addAction(action) return for selection_set in selection_sets: dirname = os.path.basename(os.path.dirname(selection_set.path())) basename = os.path.basename(selection_set.path()).replace( selection_set.EXTENSION, '') nice_name = '{}: {}'.format(dirname, basename) selection_set_action = QAction(nice_name, self) selection_set_action_callback = partial( selection_set.load, namespaces=self.namespaces()) selection_set_action.triggered.connect( selection_set_action_callback) self.addAction(selection_set_action)
def contextMenuEvent(self, event): data = self.page().contextMenuData() assert data.isValid() if not data.isContentEditable(): super().contextMenuEvent(event) return profile = self.page().profile() languages = profile.spellCheckLanguages() menu = self.page().createStandardContextMenu() menu.setParent(self) menu.addSeparator() spellcheckAction = QAction(self.tr("Check Spelling"), None) spellcheckAction.setCheckable(True) spellcheckAction.setChecked(profile.isSpellCheckEnabled()) spellcheckAction.toggled.connect(profile.setSpellCheckEnabled) menu.addAction(spellcheckAction) if profile.isSpellCheckEnabled(): subMenu = menu.addMenu(self.tr("Select Language")) for key, lang in self.m_spellCheckLanguages.items(): action = subMenu.addAction(key) action.setCheckable(True) action.setChecked(lang in languages) action.triggered.connect(partial(self.on_triggered, lang)) menu.aboutToHide.connect(menu.deleteLater) menu.popup(event.globalPos())
def create_overwrite_menu(self, menu): """ Creates a menu or action to trigger the overwrite functionality :param menu: QMenu """ if self.is_read_only(): return menu.addSeparator() overwrite_action = QAction(resources.icon('replace'), 'Overwrite', menu) overwrite_action.triggered.connect(self._on_overwrite) menu.addAction(overwrite_action)
def init_ui(self): self.text_edit = QTextEdit(self) self.setCentralWidget(self.text_edit) font = QFont("Menlo", 12) # TODO: Create a layout and change the line spacing #spacing = QFontMetrics(font).lineSpacing() self.text_edit.setFont(font) self.highlighter = Highlighter(self.text_edit.document(), DEFAULT_RULES, DEFAULT_STYLE) #print("Highlighter doc: {}".format(self.text_edit.document())) menu_bar = self.menuBar() m_file = menu_bar.addMenu("File") i_open = QAction("Open", self) i_open.setShortcut('Ctrl+O') i_open.triggered.connect(self.on_open) m_file.addAction(i_open) self.setGeometry(300, 300, 350, 300) self.setWindowTitle("tea")
def addAction(self, path, text, tip, callback): """ Overrides base QToolButton addAction function Adds aan action to the toolbar :param path: str :param text: str :param tip: str :param callback: fn :return: QAction """ action_icon = icon.Icon.state_icon( path, color='rgb(250,250,250,160)', color_active='rgb(250,250,250,250)', color_disabled='rgb(0,0,0,20)' ) action = QAction(action_icon, text, self._toolbar) action.setToolTip(tip) self._toolbar.insertAction(self._first_spacer, action) action.triggered.connect(callback) return action
def _create_context_menu(self, menu, parent=None): create_menu = super(RigOptionList, self)._create_context_menu(menu=menu, parent=parent) if self._menu_added: return create_menu control_icon = resources.icon('rigcontrol') bone_icon = resources.icon('bone') link_icon = resources.icon('link') create_menu.addSeparator() add_rig_control_action = QAction(control_icon, 'Add Rig Control', create_menu) create_menu.addAction(add_rig_control_action) add_bone_action = QAction(bone_icon, 'Add Rig Joint', create_menu) create_menu.addAction(add_bone_action) add_bone_list_action = QAction(bone_icon, 'Add Rig Joint List', create_menu) create_menu.addAction(add_bone_list_action) add_control_bone_link_action = QAction(link_icon, 'Add Control/Joint Link', create_menu) create_menu.addAction(add_control_bone_link_action) add_rig_control_action.triggered.connect( partial(parent._add_option, 'rigcontrol')) add_bone_action.triggered.connect(partial(parent._add_option, 'bone')) add_bone_list_action.triggered.connect( partial(parent._add_option, 'boneList')) add_control_bone_link_action.triggered.connect( partial(parent._add_option, 'boneControlLink')) self._menu_added = True return create_menu
def init(import_libs=True): """ Initializes tpRigToolkit module :param import_libs: bool, Whether to import deps libraries by default or not """ logger = create_logger() if import_libs: dcc_loader.init() dcc_loader_module = core_dcc.get_dcc_loader_module('tpRigToolkit.dccs') if dcc_loader_module: dcc_loader_module.init() register_resources() # Register configuration files dev = strings.to_boolean(os.getenv('TPRIGTOOLKIT_DEV', 'False')) configs.register_package_configs(PACKAGE, os.path.dirname(tpRigToolkit.config.__file__)) core_config = configs.get_config('tpRigToolkit-core', environment='development' if dev else 'production') if not core_config: logger.warning( 'tpRigToolkit-core configuration file not found! ' 'Make sure that you have tpRigToolkit-config package installed!') return None libs_to_load = core_config.get('libs', list()) tools_to_load = core_config.get('tools', list()) with contexts.Timer('Libraries loaded', logger=logger): libs.LibsManager().register_package_libs(PACKAGE, libs_to_register=libs_to_load) with contexts.Timer('Tools loaded', logger=logger): tools.ToolsManager().register_package_tools(PACKAGE, tools_to_register=tools_to_load) tools_paths = tools.ToolsManager().paths(PACKAGE) with contexts.Timer('Toolsets loaded', logger=logger): qt_toolsets.ToolsetsManager().register_package_toolsets( PACKAGE, os.path.dirname(os.path.abspath(tpRigToolkit.toolsets.__file__)), tools_paths) with contexts.Timer('Menu created', logger=logger): main_menu = menus.create_main_menu( package_name=PACKAGE, force_creation=True, icon=resources.icon('tpRigToolkit')) if main_menu: hub_action = QAction(resources.icon('tpRigToolkit'), 'Hub', main_menu) main_menu.addAction(hub_action) hub_action.triggered.connect(run_hub) menus.create_menus(package_name=PACKAGE, dev=dev, force_main_menu_creation=False)
def refresh_presets(self): """cleans and repopulates the "presets" dropdown on the tool's ribbon""" self.presets_menu.clear() for program in self.presets: program_submenu = self.presets_menu.addMenu(program) for preset in self.presets[program]: preset_action = QAction(preset, self) preset_action.triggered.connect( lambda *args, program=program, name=preset: self. apply_preset(program, name)) program_submenu.addAction(preset_action) self.settings.gaussian_presets = dumps(self.presets['Gaussian']) self.settings.orca_presets = dumps(self.presets['ORCA']) self.settings.psi4_presets = dumps(self.presets['Psi4'])
def create_settings_menu(self): """ Creates and returns the settings menu for this widget :return: QMenu """ menu = QMenu('Item View', self) menu.setIcon(resources.icon('eye')) menu.addSeparator() # copy_text_menu = self.tree_widget().create_copy_text_menu() # menu.addMenu(copy_text_menu) # menu.addSeparator() size_action = action.SliderAction('Size', menu) size_action.slider().setMinimum(10) size_action.slider().setMaximum(200) size_action.slider().setValue(self.zoom_amount()) size_action.slider().valueChanged.connect(self.set_zoom_amount) menu.addAction(size_action) border_action = action.SliderAction('Border', menu) border_action.slider().setMinimum(0) border_action.slider().setMaximum(20) border_action.slider().setValue(self.padding()) border_action.slider().valueChanged.connect(self.set_padding) menu.addAction(border_action) spacing_action = action.SliderAction('Spacing', menu) spacing_action.slider().setMinimum(self.DEFAULT_MIN_SPACING) spacing_action.slider().setMaximum(self.DEFAULT_MAX_SPACING) spacing_action.slider().setValue(self.spacing()) spacing_action.slider().valueChanged.connect(self.set_spacing) menu.addAction(spacing_action) menu.addAction(action.SeparatorAction('Label Options', menu)) for option in item.LabelDisplayOption.values(): option_action = QAction(option.title(), menu) option_action.setCheckable(True) option_action.setChecked(option == self.label_display_option()) option_callback = partial(self.set_label_display_option, option) option_action.triggered.connect(option_callback) menu.addAction(option_action) return menu
def context_edit_menu(self, menu, items=None): """ This function is called when the user opens context menu The given menu is shown as a submenu of the main context menu This function can be override to create custom context menus in LibraryItems :param menu: QMenu :param items: list(LibraryItem) """ rename_action = QAction(resources.icon('rename'), 'Rename', menu) rename_action.triggered.connect(self._on_show_rename_dialog) menu.addAction(rename_action) move_to_action = QAction(resources.icon('move'), 'Move to', menu) move_to_action.triggered.connect(self._on_move_dialog) menu.addAction(move_to_action) copy_path_action = QAction(resources.icon('copy'), 'Copy Path', menu) copy_path_action.triggered.connect(self._on_copy_path) menu.addAction(copy_path_action) if self.library_window(): select_folder_action = QAction(resources.icon('select'), 'Select Folder', menu) select_folder_action.triggered.connect(self._on_select_folder) menu.addAction(select_folder_action) show_in_folder_action = QAction(resources.icon('folder'), 'Show in Folder', menu) show_in_folder_action.triggered.connect(self._on_show_in_folder) menu.addAction(show_in_folder_action) if self.is_deletable(): delete_action = QAction(resources.icon('delete'), 'Delete', menu) delete_action.triggered.connect(self._on_show_delete_dialog) delete_with_dependencies_action = QAction(resources.icon('delete'), 'Delete with Dependencies', menu) delete_with_dependencies_action.triggered.connect(self._on_show_delete_with_dependencies_dialog) menu.addSeparator() menu.addAction(delete_action) menu.addAction(delete_with_dependencies_action) self.create_overwrite_menu(menu)
def context_menu(self, menu, items=None): """ Returns the context menu for the item :return: QMenu """ super(MayaDataItemView, self).context_menu(menu, items=items) clean_student_license_function = self.item.functionality().get( 'clean_student_license') if clean_student_license_function: clean_student_license_action = QAction(resources.icon('student'), 'Clean Student License', menu) menu.addAction(clean_student_license_action) clean_student_license_action.triggered.connect( lambda: clean_student_license_function()) menu.addSeparator() create_selection_sets_menu = self._create_selection_sets_menu( menu, enable_select_content=False) menu.insertMenu(self._select_content_action, create_selection_sets_menu)
def __init__(self): super(LoggerTool, self).__init__() self.logView = QTextBrowser() self.logView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) self.logView.setOpenLinks(False) self.logView.setReadOnly(True) self.logView.setStyleSheet( "background-color: %s; Font: 10pt 'Consolas'" % "rgba%s" % str(editableStyleSheet().LoggerBgColor.getRgb())) self.clearAction = QAction("Clear", None) self.clearAction.triggered.connect(self.clearView) self.logView.addAction(self.clearAction) self.logView.anchorClicked.connect(self.anchorClickedMethod) self.logView.setTextColor(QtGui.QColor('white')) self.setWidget(self.logView) ##################################################### # Sys Output Redirection ##################################################### self.handler = None if REDIRECT: self.handler = QtHandler(self) else: self.handler = logging.StreamHandler(sys.stdout) self.handler.setFormatter(LoggerTool.formater) logger.addHandler(self.handler) logger.setLevel(logging.DEBUG) sys.excepthook = LoggerTool.exceptHook if self.handler and REDIRECT: self.handler.messageHolder.messageWritten.connect( lambda value: self.logPython(value, 0)) self.handler.messageHolder.warningWritten.connect( lambda value: self.logPython(value, 1)) self.handler.messageHolder.errorWritten.connect( lambda value: self.logPython(value, 2)) self.handler.messageHolder.flushSig.connect(self.flushPython)
def _generate_context_menu(self, pos): """ Internal function that generates context menu of the console :param pos: QPos :return: QMneu """ menu = self.createStandardContextMenu() clear_action = QAction('Clear', menu) clear_action.triggered.connect(self.clear) menu.addSeparator() menu.addAction(clear_action) # menu.addSeparator() # undo_action = QAction('Undo', menu) # undo_action.setShortcut('Ctrl+Z') # menu.addAction(undo_action) # redo_action = QAction('Redo', menu) # redo_action.setShortcut('Ctrl+Y') # menu.addAction(redo_action) # undo_action.setEnabled(self.isUndoRedoEnabled()) # redo_action.setEnabled(self.isUndoRedoEnabled()) # undo_action.triggered.connect(self._on_undo) # redo_action.triggered.connect(self._on_redo) menu.popup(self.mapToGlobal(pos))
def create_items_menu(self, items=None): """ Creates the item menu for the given items :param items: list(LibraryItem) :return: QMenu """ item = items or self.selected_item() menu = QMenu(self) if item: try: item.context_menu(menu) except Exception as e: LOGGER.exception(e) else: item_action = QAction(menu) item_action.setText('No Item selected') item_action.setDisabled(True) menu.addAction(item_action) return menu
def __init__(self, U, plot, length=1, title=None): super().__init__() layout = QVBoxLayout() if title: title = QLabel('<b>' + title + '</b>') title.setAlignment(Qt.AlignHCenter) layout.addWidget(title) layout.addWidget(plot) plot.set(U, 0) if length > 1: hlayout = QHBoxLayout() self.slider = QSlider(Qt.Horizontal) self.slider.setMinimum(0) self.slider.setMaximum(length - 1) self.slider.setTickPosition(QSlider.TicksBelow) hlayout.addWidget(self.slider) lcd = QLCDNumber(m.ceil(m.log10(length))) lcd.setDecMode() lcd.setSegmentStyle(QLCDNumber.Flat) hlayout.addWidget(lcd) layout.addLayout(hlayout) hlayout = QHBoxLayout() toolbar = QToolBar() self.a_play = QAction(self.style().standardIcon(QStyle.SP_MediaPlay), 'Play', self) self.a_play.setCheckable(True) self.a_rewind = QAction(self.style().standardIcon(QStyle.SP_MediaSeekBackward), 'Rewind', self) self.a_toend = QAction(self.style().standardIcon(QStyle.SP_MediaSeekForward), 'End', self) self.a_step_backward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipBackward), 'Step Back', self) self.a_step_forward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipForward), 'Step', self) self.a_loop = QAction(self.style().standardIcon(QStyle.SP_BrowserReload), 'Loop', self) self.a_loop.setCheckable(True) toolbar.addAction(self.a_play) toolbar.addAction(self.a_rewind) toolbar.addAction(self.a_toend) toolbar.addAction(self.a_step_backward) toolbar.addAction(self.a_step_forward) toolbar.addAction(self.a_loop) if hasattr(self, 'save'): self.a_save = QAction(self.style().standardIcon(QStyle.SP_DialogSaveButton), 'Save', self) toolbar.addAction(self.a_save) self.a_save.triggered.connect(self.save) hlayout.addWidget(toolbar) self.speed = QSlider(Qt.Horizontal) self.speed.setMinimum(0) self.speed.setMaximum(100) hlayout.addWidget(QLabel('Speed:')) hlayout.addWidget(self.speed) layout.addLayout(hlayout) self.timer = QTimer() self.timer.timeout.connect(self.update_solution) self.slider.valueChanged.connect(self.slider_changed) self.slider.valueChanged.connect(lcd.display) self.speed.valueChanged.connect(self.speed_changed) self.a_play.toggled.connect(self.toggle_play) self.a_rewind.triggered.connect(self.rewind) self.a_toend.triggered.connect(self.to_end) self.a_step_forward.triggered.connect(self.step_forward) self.a_step_backward.triggered.connect(self.step_backward) self.speed.setValue(50) elif hasattr(self, 'save'): hlayout = QHBoxLayout() toolbar = QToolBar() self.a_save = QAction(self.style().standardIcon(QStyle.SP_DialogSaveButton), 'Save', self) toolbar.addAction(self.a_save) hlayout.addWidget(toolbar) layout.addLayout(hlayout) self.a_save.triggered.connect(self.save) self.setLayout(layout) self.plot = plot self.U = U self.length = length
class PlotMainWindow(QWidget): """Base class for plot main windows.""" def __init__(self, U, plot, length=1, title=None): super().__init__() layout = QVBoxLayout() if title: title = QLabel('<b>' + title + '</b>') title.setAlignment(Qt.AlignHCenter) layout.addWidget(title) layout.addWidget(plot) plot.set(U, 0) if length > 1: hlayout = QHBoxLayout() self.slider = QSlider(Qt.Horizontal) self.slider.setMinimum(0) self.slider.setMaximum(length - 1) self.slider.setTickPosition(QSlider.TicksBelow) hlayout.addWidget(self.slider) lcd = QLCDNumber(m.ceil(m.log10(length))) lcd.setDecMode() lcd.setSegmentStyle(QLCDNumber.Flat) hlayout.addWidget(lcd) layout.addLayout(hlayout) hlayout = QHBoxLayout() toolbar = QToolBar() self.a_play = QAction(self.style().standardIcon(QStyle.SP_MediaPlay), 'Play', self) self.a_play.setCheckable(True) self.a_rewind = QAction(self.style().standardIcon(QStyle.SP_MediaSeekBackward), 'Rewind', self) self.a_toend = QAction(self.style().standardIcon(QStyle.SP_MediaSeekForward), 'End', self) self.a_step_backward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipBackward), 'Step Back', self) self.a_step_forward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipForward), 'Step', self) self.a_loop = QAction(self.style().standardIcon(QStyle.SP_BrowserReload), 'Loop', self) self.a_loop.setCheckable(True) toolbar.addAction(self.a_play) toolbar.addAction(self.a_rewind) toolbar.addAction(self.a_toend) toolbar.addAction(self.a_step_backward) toolbar.addAction(self.a_step_forward) toolbar.addAction(self.a_loop) if hasattr(self, 'save'): self.a_save = QAction(self.style().standardIcon(QStyle.SP_DialogSaveButton), 'Save', self) toolbar.addAction(self.a_save) self.a_save.triggered.connect(self.save) hlayout.addWidget(toolbar) self.speed = QSlider(Qt.Horizontal) self.speed.setMinimum(0) self.speed.setMaximum(100) hlayout.addWidget(QLabel('Speed:')) hlayout.addWidget(self.speed) layout.addLayout(hlayout) self.timer = QTimer() self.timer.timeout.connect(self.update_solution) self.slider.valueChanged.connect(self.slider_changed) self.slider.valueChanged.connect(lcd.display) self.speed.valueChanged.connect(self.speed_changed) self.a_play.toggled.connect(self.toggle_play) self.a_rewind.triggered.connect(self.rewind) self.a_toend.triggered.connect(self.to_end) self.a_step_forward.triggered.connect(self.step_forward) self.a_step_backward.triggered.connect(self.step_backward) self.speed.setValue(50) elif hasattr(self, 'save'): hlayout = QHBoxLayout() toolbar = QToolBar() self.a_save = QAction(self.style().standardIcon(QStyle.SP_DialogSaveButton), 'Save', self) toolbar.addAction(self.a_save) hlayout.addWidget(toolbar) layout.addLayout(hlayout) self.a_save.triggered.connect(self.save) self.setLayout(layout) self.plot = plot self.U = U self.length = length def slider_changed(self, ind): self.plot.set(self.U, ind) def speed_changed(self, val): self.timer.setInterval(val * 20) def update_solution(self): ind = self.slider.value() + 1 if ind >= self.length: if self.a_loop.isChecked(): ind = 0 else: self.a_play.setChecked(False) return self.slider.setValue(ind) def toggle_play(self, checked): if checked: if self.slider.value() + 1 == self.length: self.slider.setValue(0) self.timer.start() else: self.timer.stop() def rewind(self): self.slider.setValue(0) def to_end(self): self.a_play.setChecked(False) self.slider.setValue(self.length - 1) def step_forward(self): self.a_play.setChecked(False) ind = self.slider.value() + 1 if ind == self.length and self.a_loop.isChecked(): ind = 0 if ind < self.length: self.slider.setValue(ind) def step_backward(self): self.a_play.setChecked(False) ind = self.slider.value() - 1 if ind == -1 and self.a_loop.isChecked(): ind = self.length - 1 if ind >= 0: self.slider.setValue(ind)
def _build_ui(self): layout = QFormLayout() self.cone_option = QComboBox() self.cone_option.addItems(["Tolman (Unsymmetrical)", "Exact"]) ndx = self.cone_option.findText(self.settings.cone_option, Qt.MatchExactly) self.cone_option.setCurrentIndex(ndx) layout.addRow("method:", self.cone_option) self.radii_option = QComboBox() self.radii_option.addItems(["Bondi", "UMN"]) ndx = self.radii_option.findText(self.settings.radii, Qt.MatchExactly) self.radii_option.setCurrentIndex(ndx) layout.addRow("radii:", self.radii_option) self.display_cone = QCheckBox() self.display_cone.setChecked(self.settings.display_cone) layout.addRow("show cone:", self.display_cone) self.display_radii = QCheckBox() self.display_radii.setChecked(self.settings.display_radii) layout.addRow("show radii:", self.display_radii) set_ligand_button = QPushButton("set ligand to current selection") set_ligand_button.clicked.connect(self.set_ligand) layout.addRow(set_ligand_button) self.set_ligand_button = set_ligand_button calc_cone_button = QPushButton( "calculate cone angle for ligand on selected center") calc_cone_button.clicked.connect(self.calc_cone) layout.addRow(calc_cone_button) self.calc_cone_button = calc_cone_button remove_cone_button = QPushButton("remove cone visualizations") remove_cone_button.clicked.connect(self.del_cone) layout.addRow(remove_cone_button) self.remove_cone_button = remove_cone_button self.table = QTableWidget() self.table.setColumnCount(3) self.table.setHorizontalHeaderLabels([ 'model', 'center', 'cone angle (°)', ]) self.table.setSelectionBehavior(QTableWidget.SelectRows) self.table.setEditTriggers(QTableWidget.NoEditTriggers) self.table.resizeColumnToContents(0) self.table.resizeColumnToContents(1) self.table.resizeColumnToContents(2) self.table.horizontalHeader().setSectionResizeMode( 2, QHeaderView.Stretch) layout.addRow(self.table) menu = QMenuBar() export = menu.addMenu("&Export") clear = QAction("Clear data table", self.tool_window.ui_area) clear.triggered.connect(self.clear_table) export.addAction(clear) copy = QAction("&Copy CSV to clipboard", self.tool_window.ui_area) copy.triggered.connect(self.copy_csv) shortcut = QKeySequence(Qt.CTRL + Qt.Key_C) copy.setShortcut(shortcut) export.addAction(copy) save = QAction("&Save CSV...", self.tool_window.ui_area) save.triggered.connect(self.save_csv) #this shortcut interferes with main window's save shortcut #I've tried different shortcut contexts to no avail #thanks Qt... #shortcut = QKeySequence(Qt.CTRL + Qt.Key_S) #save.setShortcut(shortcut) #save.setShortcutContext(Qt.WidgetShortcut) export.addAction(save) delimiter = export.addMenu("Delimiter") comma = QAction("comma", self.tool_window.ui_area, checkable=True) comma.setChecked(self.settings.delimiter == "comma") comma.triggered.connect(lambda *args, delim="comma": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(comma) tab = QAction("tab", self.tool_window.ui_area, checkable=True) tab.setChecked(self.settings.delimiter == "tab") tab.triggered.connect(lambda *args, delim="tab": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(tab) space = QAction("space", self.tool_window.ui_area, checkable=True) space.setChecked(self.settings.delimiter == "space") space.triggered.connect(lambda *args, delim="space": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(space) semicolon = QAction("semicolon", self.tool_window.ui_area, checkable=True) semicolon.setChecked(self.settings.delimiter == "semicolon") semicolon.triggered.connect(lambda *args, delim="semicolon": self. settings.__setattr__("delimiter", delim)) delimiter.addAction(semicolon) add_header = QAction("&Include CSV header", self.tool_window.ui_area, checkable=True) add_header.setChecked(self.settings.include_header) add_header.triggered.connect(self.header_check) export.addAction(add_header) comma.triggered.connect( lambda *args, action=tab: action.setChecked(False)) comma.triggered.connect( lambda *args, action=space: action.setChecked(False)) comma.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) tab.triggered.connect( lambda *args, action=comma: action.setChecked(False)) tab.triggered.connect( lambda *args, action=space: action.setChecked(False)) tab.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) space.triggered.connect( lambda *args, action=comma: action.setChecked(False)) space.triggered.connect( lambda *args, action=tab: action.setChecked(False)) space.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=comma: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=tab: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=space: action.setChecked(False)) menu.setNativeMenuBar(False) self._menu = menu layout.setMenuBar(menu) menu.setVisible(True) self.tool_window.ui_area.setLayout(layout) self.tool_window.manage(None)
def _build_ui(self): #each group has an empty widget at the bottom so they resize the way I want while also having the #labels where I want them layout = QGridLayout() self.tab_widget = QTabWidget() layout.addWidget(self.tab_widget) #layout for absolute thermo stuff absolute_widget = QWidget() absolute_layout = QGridLayout(absolute_widget) #box for sp sp_area_widget = QGroupBox("Single-point") sp_layout = QFormLayout(sp_area_widget) self.sp_selector = FilereaderComboBox(self.session, otherItems=['energy']) self.sp_selector.currentIndexChanged.connect(self.set_sp) sp_layout.addRow(self.sp_selector) self.sp_table = QTableWidget() self.sp_table.setColumnCount(3) self.sp_table.setShowGrid(False) self.sp_table.horizontalHeader().hide() self.sp_table.verticalHeader().hide() self.sp_table.setFrameShape(QTableWidget.NoFrame) self.sp_table.setSelectionMode(QTableWidget.NoSelection) self.sp_table.insertRow(0) sp_layout.addRow(self.sp_table) #box for thermo therm_area_widget = QGroupBox("Thermal corrections") thermo_layout = QFormLayout(therm_area_widget) self.thermo_selector = FilereaderComboBox(self.session, otherItems=['frequency']) self.thermo_selector.currentIndexChanged.connect(self.set_thermo_mdl) thermo_layout.addRow(self.thermo_selector) self.temperature_line = QDoubleSpinBox() self.temperature_line.setMaximum(2**31 - 1) self.temperature_line.setValue(298.15) self.temperature_line.setSingleStep(10) self.temperature_line.setSuffix(" K") self.temperature_line.setMinimum(0) self.temperature_line.valueChanged.connect(self.set_thermo) thermo_layout.addRow("T =", self.temperature_line) self.v0_edit = QDoubleSpinBox() self.v0_edit.setMaximum(4000) self.v0_edit.setValue(self.settings.w0) self.v0_edit.setSingleStep(25) self.v0_edit.setSuffix(" cm\u207b\u00b9") self.v0_edit.valueChanged.connect(self.set_thermo) self.v0_edit.setMinimum(0) self.v0_edit.setToolTip( "frequency parameter for quasi treatments of entropy") thermo_layout.addRow("𝜔<sub>0</sub> =", self.v0_edit) self.thermo_table = QTableWidget() self.thermo_table.setColumnCount(3) self.thermo_table.setShowGrid(False) self.thermo_table.horizontalHeader().hide() self.thermo_table.verticalHeader().hide() self.thermo_table.setFrameShape(QTableWidget.NoFrame) self.thermo_table.setSelectionMode(QTableWidget.NoSelection) thermo_layout.addRow(self.thermo_table) # for for total sum_area_widget = QGroupBox("Thermochemistry") sum_layout = QFormLayout(sum_area_widget) self.sum_table = QTableWidget() self.sum_table.setColumnCount(3) self.sum_table.setShowGrid(False) self.sum_table.horizontalHeader().hide() self.sum_table.verticalHeader().hide() self.sum_table.setFrameShape(QTableWidget.NoFrame) self.sum_table.setSelectionMode(QTableWidget.NoSelection) sum_layout.addRow(self.sum_table) splitter = QSplitter(Qt.Horizontal) splitter.setChildrenCollapsible(False) splitter.addWidget(sp_area_widget) splitter.addWidget(therm_area_widget) splitter.addWidget(sum_area_widget) absolute_layout.addWidget(splitter) self.status = QStatusBar() self.status.setSizeGripEnabled(False) self.status.setStyleSheet("color: red") absolute_layout.addWidget(self.status, 1, 0, 1, 1, Qt.AlignTop) self.tab_widget.addTab(absolute_widget, "absolute") relative_widget = QWidget() relative_layout = QGridLayout(relative_widget) size = [self.settings.ref_col_1, self.settings.ref_col_2] self.ref_group = ThermoGroup("reference group", self.session, self.nrg_fr, self.thermo_co, size) self.ref_group.changes.connect(self.calc_relative_thermo) relative_layout.addWidget(self.ref_group, 0, 0, 1, 3, Qt.AlignTop) size = [self.settings.other_col_1, self.settings.other_col_2] self.other_group = ThermoGroup("other group", self.session, self.nrg_fr, self.thermo_co, size) self.other_group.changes.connect(self.calc_relative_thermo) relative_layout.addWidget(self.other_group, 0, 3, 1, 3, Qt.AlignTop) self.relative_temperature = QDoubleSpinBox() self.relative_temperature.setMaximum(2**31 - 1) self.relative_temperature.setValue(self.settings.rel_temp) self.relative_temperature.setSingleStep(10) self.relative_temperature.setSuffix(" K") self.relative_temperature.setMinimum(0) self.relative_temperature.valueChanged.connect( self.calc_relative_thermo) relative_layout.addWidget(QLabel("T ="), 1, 0, 1, 1, Qt.AlignRight | Qt.AlignVCenter) relative_layout.addWidget(self.relative_temperature, 1, 1, 1, 5, Qt.AlignLeft | Qt.AlignVCenter) self.relative_v0 = QDoubleSpinBox() self.relative_v0.setMaximum(2**31 - 1) self.relative_v0.setValue(self.settings.w0) self.relative_v0.setSingleStep(25) self.relative_v0.setSuffix(" cm\u207b\u00b9") self.relative_v0.setMinimum(0) self.relative_v0.setToolTip( "frequency parameter for quasi treatments of entropy") self.relative_v0.valueChanged.connect(self.calc_relative_thermo) relative_layout.addWidget(QLabel("𝜔<sub>0</sub> ="), 2, 0, 1, 1, Qt.AlignRight | Qt.AlignVCenter) relative_layout.addWidget(self.relative_v0, 2, 1, 1, 5, Qt.AlignLeft | Qt.AlignVCenter) relative_layout.addWidget( QLabel("Boltzmann-weighted relative energies in kcal/mol:"), 3, 0, 1, 6, Qt.AlignVCenter | Qt.AlignLeft) self.relative_table = QTextBrowser() self.relative_table.setMaximumHeight( 4 * self.relative_table.fontMetrics().boundingRect("Q").height()) relative_layout.addWidget(self.relative_table, 4, 0, 1, 6, Qt.AlignTop) relative_layout.setRowStretch(0, 1) relative_layout.setRowStretch(1, 0) relative_layout.setRowStretch(2, 0) relative_layout.setRowStretch(3, 0) relative_layout.setRowStretch(4, 0) self.tab_widget.addTab(relative_widget, "relative") #menu stuff menu = QMenuBar() export = menu.addMenu("&Export") copy = QAction("&Copy CSV to clipboard", self.tool_window.ui_area) copy.triggered.connect(self.copy_csv) shortcut = QKeySequence(Qt.CTRL + Qt.Key_C) copy.setShortcut(shortcut) export.addAction(copy) self.copy = copy save = QAction("&Save CSV...", self.tool_window.ui_area) save.triggered.connect(self.save_csv) #this shortcut interferes with main window's save shortcut #I've tried different shortcut contexts to no avail #thanks Qt... #shortcut = QKeySequence(Qt.CTRL + Qt.Key_S) #save.setShortcut(shortcut) #save.setShortcutContext(Qt.WidgetShortcut) export.addAction(save) delimiter = export.addMenu("Delimiter") comma = QAction("comma", self.tool_window.ui_area, checkable=True) comma.setChecked(self.settings.delimiter == "comma") comma.triggered.connect(lambda *args, delim="comma": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(comma) tab = QAction("tab", self.tool_window.ui_area, checkable=True) tab.setChecked(self.settings.delimiter == "tab") tab.triggered.connect(lambda *args, delim="tab": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(tab) space = QAction("space", self.tool_window.ui_area, checkable=True) space.setChecked(self.settings.delimiter == "space") space.triggered.connect(lambda *args, delim="space": self.settings. __setattr__("delimiter", delim)) delimiter.addAction(space) semicolon = QAction("semicolon", self.tool_window.ui_area, checkable=True) semicolon.setChecked(self.settings.delimiter == "semicolon") semicolon.triggered.connect(lambda *args, delim="semicolon": self. settings.__setattr__("delimiter", delim)) delimiter.addAction(semicolon) add_header = QAction("&Include CSV header", self.tool_window.ui_area, checkable=True) add_header.setChecked(self.settings.include_header) add_header.triggered.connect(self.header_check) export.addAction(add_header) comma.triggered.connect( lambda *args, action=tab: action.setChecked(False)) comma.triggered.connect( lambda *args, action=space: action.setChecked(False)) comma.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) tab.triggered.connect( lambda *args, action=comma: action.setChecked(False)) tab.triggered.connect( lambda *args, action=space: action.setChecked(False)) tab.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) space.triggered.connect( lambda *args, action=comma: action.setChecked(False)) space.triggered.connect( lambda *args, action=tab: action.setChecked(False)) space.triggered.connect( lambda *args, action=semicolon: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=comma: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=tab: action.setChecked(False)) semicolon.triggered.connect( lambda *args, action=space: action.setChecked(False)) menu.setNativeMenuBar(False) self._menu = menu layout.setMenuBar(menu) menu.setVisible(True) self.tool_window.ui_area.setLayout(layout) self.tool_window.manage(None)
def __init__(self, window, system=None): self.system = system self.window = window # Build Actions blendToTargetACT = QAction("Blend To Target", self.window) generateShapeIncrementalsACT = QAction("Generate Shape Incrementals", self.window) #generateTimeIncrementalsACT = QAction("Generate Time Incrementals", self.window) relaxToSelectionACT = QAction("Relax To Selection", self.window) snapShapeToNeutralACT = QAction("Snap Shape To Neutral", self.window) softSelectToClusterACT = QAction("Soft Select To Cluster", self.window) extractDeltasACT = QAction("Extract Deltas", self.window) applyDeltasACT = QAction("Apply Deltas", self.window) extractExternalACT = QAction("Extract External", self.window) tweakMixACT = QAction("Tweak Mix", self.window) extractProgressivesACT = QAction("Extract Progressive", self.window) reloadDefinitionACT = QAction("Reload Definition", self.window) updateRestShapeACT = QAction("Update Rest Shape", self.window) extractCleanComboACT = QAction("Extract Clean Combo", self.window) importObjFolderACT = QAction("Import Obj Folder", self.window) # Build the menu menu = self.window.menuBar.addMenu('Tools') menu.addAction(blendToTargetACT) menu.addAction(generateShapeIncrementalsACT) #menu.addAction(generateTimeIncrementalsACT) menu.addAction(relaxToSelectionACT) menu.addAction(snapShapeToNeutralACT) menu.addAction(softSelectToClusterACT) menu.addSeparator() menu.addAction(extractDeltasACT) menu.addAction(applyDeltasACT) menu.addAction(extractExternalACT) menu.addAction(tweakMixACT) menu.addAction(extractProgressivesACT) menu.addAction(reloadDefinitionACT) menu.addAction(updateRestShapeACT) menu.addAction(extractCleanComboACT) menu.addAction(importObjFolderACT) # Set up the connections blendToTargetACT.triggered.connect(self.blendToTarget) generateShapeIncrementalsACT.triggered.connect( self.generateShapeIncrementals) #generateTimeIncrementalsACT.triggered.connect(self.generateTimeIncrementals) relaxToSelectionACT.triggered.connect(self.relaxToSelection) snapShapeToNeutralACT.triggered.connect(self.snapShapeToNeutral) softSelectToClusterACT.triggered.connect(self.softSelectToCluster) extractDeltasACT.triggered.connect(self.extractDeltas) applyDeltasACT.triggered.connect(self.applyDeltas) extractExternalACT.triggered.connect(self.extractExternal) tweakMixACT.triggered.connect(self.tweakMix) extractProgressivesACT.triggered.connect(self.extractProgressives) reloadDefinitionACT.triggered.connect(self.reloadDefinition) updateRestShapeACT.triggered.connect(self.updateRestShape) extractCleanComboACT.triggered.connect(self.extractCleanCombo) importObjFolderACT.triggered.connect(self.loadObjFolder)
def _create_button(self, name=None, icon=None, fn=None, status=None, tooltip=None, description=None, instructions=None, whats_this='', settings=None, settings_fn=None, info_message='', error_message='', widgets=None): """ Internal function to easily create buttons for the box widget :param name: :param icon: :param fn: :param status: :param tooltip: :return: """ name = name or '' new_btn = CommandButton(parent=self).small() if icon: if python.is_string(icon): icon = resources.icon(icon) new_btn.setIcon(icon) else: new_btn.setText(name) new_btn.setObjectName(name.replace(' ', '').lower() or description) new_btn.setStatusTip(status or name) new_btn.setToolTip(tooltip or name) new_btn.setProperty('name', name) new_btn.setProperty('description', description or tooltip or status or '') new_btn.setProperty('instructions', instructions or '') new_btn.setProperty('tooltip_help', { 'title': name, 'description': description }) new_btn.setStyleSheet('qproperty-iconSize: 20px 20px;') new_btn.setIconSize(QSize(20, 20)) new_btn.setWhatsThis(whats_this or tooltip or name) new_btn.setContextMenuPolicy(Qt.CustomContextMenu) new_btn.installEventFilter(self) if widgets: valid_widgets = list() for widget in widgets: if hasattr(self, widget): valid_widgets.append(getattr(self, widget)) if valid_widgets: self._widgets[new_btn.objectName()] = valid_widgets new_btn.has_menu = True if fn: info_message = info_message or 'Command "{}" executed successfully!'.format( name) error_message = error_message or 'Error while executing command "{}"! Check log for more info.'.format( name) new_btn.clicked.connect( partial(self._on_execute_command, name, fn, info_message, error_message)) new_btn.customContextMenuRequested.connect(self._on_show_context_menu) if settings: settings_icon = 'menu_dots' if settings and len( settings) > 1 else 'settings' buttons_widget = QWidget() buttons_widget.setStyleSheet( 'QPushButton::menu-indicator{ image: none; };') buttons_layout = layouts.HorizontalLayout(spacing=0, margins=(0, 0, 0, 0)) buttons_widget.setLayout(buttons_layout) if len(settings) > 1: options_name = '{} Options'.format(name) options_description = 'Show {} Menu'.format(options_name) options_btn = self._create_button( icon=settings_icon, fn=settings_fn, name=options_name, description=options_description) options_menu = QMenu(self) options_menu.installEventFilter(self) options_btn.setMenu(options_menu) for setting in settings: option_name = setting.get('name', None) if not option_name: continue option_fn = setting.get('fn', None) if not option_fn: continue option_description = setting.get('description', '') option_instructions = setting.get('instructions', '') option_icon = resources.icon( setting.get('icon', 'tpRigToolkit')) option_action = QAction(option_icon, option_name, self) option_action.setProperty('description', option_description or '') option_action.setProperty('instructions', option_instructions or '') option_info_message = info_message or 'Command "{}" executed successfully!'.format( name) option_error_message = error_message or 'Error while executing command "{}"! ' \ 'Check log for more info.'.format(name) option_action.triggered.connect( partial(self._on_execute_command, option_name, option_fn, option_info_message, option_error_message)) options_menu.addAction(option_action) else: setting = settings[0] option_description = setting.get('description', '') option_name = setting.get('name', None) option_fn = setting.get('fn', None) options_btn = self._create_button( icon=settings_icon, fn=option_fn, name=option_name, description=option_description) new_btn.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) new_btn.setStyleSheet( new_btn.styleSheet() + ';border-top-right-radius: 0px; border-bottom-right-radius: 0px; ' 'border-right: 0px;') new_btn.setMaximumWidth(28) options_btn.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) options_btn.setMaximumWidth(18) options_btn.setStyleSheet( options_btn.styleSheet() + ';border-top-left-radius: 0px; border-bottom-left-radius: 0px; ' 'qproperty-iconSize: 12px 12px;') buttons_layout.addWidget(new_btn) buttons_layout.addWidget(options_btn) self._buttons.append(new_btn) return buttons_widget self._buttons.append(new_btn) return new_btn
class ScriptEditorView(window.BaseWindow, object): lastTabClosed = Signal() scriptSaved = Signal(str) def __init__(self, model, controller, parent=None): self._model = model or script_model.ScriptEditorModel() self._controller = controller or script_controller.ScriptEditorController( model=self._model) super(ScriptEditorView, self).__init__(parent=parent) self._controller.update_namespace( {'self_output': self._output_console}) # self._load_settings() self.refresh() # self._process_args() # ================================================================================================================= # OVERRIDES # ================================================================================================================= @property def model(self): return self._model # ================================================================================================================= # OVERRIDES # ================================================================================================================= def ui(self): super(ScriptEditorView, self).ui() self._stack = stack.SlidingOpacityStackedWidget(parent=self) main_splitter = QSplitter(Qt.Vertical, parent=self) self._output_console = console.OutputConsole(parent=self) # NOTE: Scripts Tab MUST pass ScriptEditor as parent because internally some ScriptEditor functions # NOTE: are connected to some signals. If we don't do this Maya will crash when opening new Script Editors :) self._scripts_tab = script.ScriptsTab(controller=self._controller, parent=self) main_splitter.addWidget(self._output_console) main_splitter.addWidget(self._scripts_tab) self._menu_bar = self._setup_menubar() self._tool_bar = self._setup_toolbar() self._tool_bar_divider = dividers.Divider() # Empty widget empty_widget = QWidget(self) empty_layout = layouts.HorizontalLayout(spacing=5, margins=(5, 5, 5, 5)) empty_widget.setLayout(empty_layout) main_empty_layout = layouts.VerticalLayout(spacing=5, margins=(5, 5, 5, 5)) self._empty_label = label.BaseLabel('No Scripts Opened', parent=self).h4().strong() self._empty_label.setAlignment(Qt.AlignCenter) main_empty_layout.addStretch() main_empty_layout.addWidget(self._empty_label) main_empty_layout.addStretch() empty_layout.addStretch() empty_layout.addLayout(main_empty_layout) empty_layout.addStretch() self._stack.addWidget(empty_widget) self._stack.addWidget(main_splitter) self.main_layout.addWidget(self._menu_bar) self.main_layout.addWidget(self._tool_bar) self.main_layout.addWidget(self._tool_bar_divider) self.main_layout.addWidget(self._stack) def setup_signals(self): self._scripts_tab.lastTabClosed.connect(self.lastTabClosed.emit) self._output_console.outputTextChanged.connect( self._controller.set_output_text) self._scripts_tab.currentChanged.connect(self._on_current_tab_changed) self._scripts_tab.selectionChanged.connect(self._on_selection_changed) self._scripts_tab.scriptTextChanged.connect( self._on_script_text_changed) self._model.consoleVisibleChanged.connect( self._on_console_visible_changed) self._model.toolbarVisibleChanged.connect( self._on_toolbar_visible_changed) self._model.menubarVisibleChanged.connect( self._on_menubar_visible_changed) self._model.sessionPathChanged.connect(self._on_session_changed) self._model.currentScriptChanged.connect( self._on_current_script_changed) self._model.currentTextChanged.connect(self._on_current_text_changed) self._model.outputTextChanged.connect(self._on_output_text_changed) self._model.scriptOpened.connect(self._on_script_opened) self._model.scriptSaved.connect(self._on_script_saved) self._model.scriptClosed.connect(self._on_script_closed) def eventFilter(self, obj, event): if event.type() in (QEvent.Move, QEvent.Resize): self._adjust_completers() return super(ScriptEditorView, self).eventFilter(obj, event) def closeEvent(self, event): # self.save_current_session() # self._save_settings() super(ScriptEditorView, self).closeEvent(event) # ================================================================================================================= # BASE # ================================================================================================================= def refresh(self): self._update_session() self._execute_selected_action.setEnabled( bool(self._model.selected_text)) self._output_console.setVisible(self._model.console_visible) self._tool_bar.setVisible(self._model.toolbar_visible) self._tool_bar_divider.setVisible(self._model.toolbar_visible) self._menu_bar.setVisible(self._model.menubar_visible) self._refresh_stack() # ================================================================================================================= # INTERNAL # ================================================================================================================= def _setup_menubar(self): """ Internal function that setups menu bar for the widget :return: """ menubar = self.menuBar() save_icon = resources.icon('save') load_icon = resources.icon('open_folder') play_icon = resources.icon('play') clear_icon = resources.icon('delete') resume_icon = resources.icon('resume') undo_icon = resources.icon('undo') redo_icon = resources.icon('redo') copy_icon = resources.icon('copy') cut_icon = resources.icon('cut') paste_icon = resources.icon('paste') tab_icon = resources.icon('tab') quote_icon = resources.icon('quote') rename_icon = resources.icon('rename') keyboard_icon = resources.icon('keyboard') help_icon = resources.icon('help') file_menu = QMenu('File', menubar) menubar.addMenu(file_menu) save_session_action = QAction(save_icon, 'Save Session', file_menu) load_script_action = QAction(load_icon, 'Load Script', file_menu) save_script_action = QAction(save_icon, 'Save Script', file_menu) file_menu.addAction(save_session_action) file_menu.addAction(load_script_action) file_menu.addAction(save_script_action) load_script_action.setShortcut('Ctrl+O') # load_script_action.setShortcutContext(Qt.WidgetShortcut) save_script_action.setShortcut('Ctrl+S') # save_script_action.setShortcutContext(Qt.WidgetShortcut) edit_menu = QMenu('Edit', self) menubar.addMenu(edit_menu) undo_action = QAction(undo_icon, 'Undo', edit_menu) redo_action = QAction(redo_icon, 'Redo', edit_menu) copy_action = QAction(copy_icon, 'Copy', edit_menu) cut_action = QAction(cut_icon, 'Cut', edit_menu) paste_action = QAction(paste_icon, 'Paste', edit_menu) tab_to_spaces_action = QAction(tab_icon, 'Tab to Spaces', edit_menu) comment_action = QAction(quote_icon, 'Comment', edit_menu) find_and_replace = QAction(rename_icon, 'Find and Replace', edit_menu) edit_menu.addAction(undo_action) edit_menu.addAction(redo_action) edit_menu.addSeparator() edit_menu.addAction(copy_action) edit_menu.addAction(cut_action) edit_menu.addAction(paste_action) edit_menu.addSeparator() edit_menu.addAction(tab_to_spaces_action) edit_menu.addAction(comment_action) edit_menu.addAction(find_and_replace) run_menu = QMenu('Run', self) menubar.addMenu(run_menu) self._execute_all_action = QAction(play_icon, 'Execute All', run_menu) self._execute_all_action.setShortcut('Ctrl+Shift+Return') self._execute_all_action.setShortcutContext(Qt.ApplicationShortcut) self._execute_selected_action = QAction(resume_icon, 'Execute Selected', run_menu) self._execute_selected_action.setShortcut('Ctrl+Return') self._execute_selected_action.setShortcutContext( Qt.WidgetWithChildrenShortcut) self._clear_output_action = QAction(clear_icon, 'Clear Output', run_menu) run_menu.addAction(self._execute_all_action) run_menu.addAction(self._execute_selected_action) run_menu.addAction(self._clear_output_action) help_menu = QMenu('Help', self) menubar.addMenu(help_menu) show_shortcuts_action = QAction(keyboard_icon, 'Show Shortcuts', help_menu) print_help_action = QAction(help_icon, 'Print Help', help_menu) help_menu.addAction(show_shortcuts_action) help_menu.addSeparator() help_menu.addAction(print_help_action) undo_action.setShortcut('Ctrl+Z') undo_action.setShortcutContext(Qt.WidgetShortcut) redo_action.setShortcut('Ctrl+Y') redo_action.setShortcutContext(Qt.WidgetShortcut) copy_action.setShortcut('Ctrl+C') copy_action.setShortcutContext(Qt.WidgetShortcut) cut_action.setShortcut('Ctrl+X') cut_action.setShortcutContext(Qt.WidgetShortcut) paste_action.setShortcut('Ctrl+V') paste_action.setShortcutContext(Qt.WidgetShortcut) comment_action.setShortcut(QKeySequence(Qt.ALT + Qt.Key_Q)) comment_action.setShortcutContext(Qt.WidgetShortcut) self._execute_all_action.triggered.connect( self._controller.execute_script) self._execute_selected_action.triggered.connect( partial(self._controller.execute_script, True)) self._clear_output_action.triggered.connect( partial(self._controller.set_output_text, '')) # open_settings_folder_action.triggered.connect(self._open_settings) # show_shortcuts_action.triggered.connect(self._open_shortcuts) # print_help_action.triggered.connect(self.editor_help) save_session_action.triggered.connect( self._controller.save_current_session) save_script_action.triggered.connect(self._controller.save_script) load_script_action.triggered.connect(self._controller.load_script) undo_action.triggered.connect(self._scripts_tab.undo) redo_action.triggered.connect(self._scripts_tab.redo) copy_action.triggered.connect(self._scripts_tab.copy) cut_action.triggered.connect(self._scripts_tab.cut) paste_action.triggered.connect(self._scripts_tab.paste) tab_to_spaces_action.triggered.connect( self._controller.convert_tab_to_spaces) # find_and_replace.triggered.connect(self._open_find_replace) comment_action.triggered.connect(self._scripts_tab.comment) return menubar def _setup_toolbar(self): """ Internal function that setups script editor toolbar """ toolbar = QToolBar('Script Editor ToolBar', parent=self) toolbar.setIconSize(QSize(16, 16)) execute_btn = buttons.BaseToolButton(parent=self) execute_btn.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) execute_selected_btn = buttons.BaseToolButton(parent=self) execute_selected_btn.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) clear_output_btn = buttons.BaseToolButton(parent=self) clear_output_btn.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) toolbar.addWidget(execute_btn) toolbar.addWidget(execute_selected_btn) toolbar.addWidget(clear_output_btn) execute_btn.setDefaultAction(self._execute_all_action) execute_selected_btn.setDefaultAction(self._execute_selected_action) clear_output_btn.setDefaultAction(self._clear_output_action) return toolbar def _update_session(self): """ Internal function that updates ui taking into account the current active session """ current_session = self._controller.get_session() if not current_session: self._scripts_tab.add_new_tab() else: sessions = current_session.read() self._scripts_tab.clear() active = 0 if sessions: for i, s in enumerate(sessions): script_file = s.get('file', None) script_name = s.get('name', '') script_text = s.get('text', '') if script_file and os.path.isfile(script_file): script_editor = self._scripts_tab.add_new_tab( script_name, script_file) else: script_editor = self._scripts_tab.add_new_tab( script_name, script_text) if s.get('active', False): active = i script_editor.set_font_size(s.get('size', None)) else: self._scripts_tab.add_new_tab() self._scripts_tab.setCurrentIndex(active) def _adjust_completers(self): """ Internal callback function that updates the size of the completers depending on its visiblity """ for i in range(self._scripts_tab.count()): script_widget = self._scripts_tab.widget(i) if not script_widget: continue if script_widget.editor.completer.isVisible(): script_widget.editor.move_completer() def _refresh_stack(self): """ Internal function that updates stack status """ total_scripts = len(list(self._model.scripts.items())) if total_scripts <= 0: self._stack.setCurrentIndex(0) else: self._stack.setCurrentIndex(1) # self._scripts_tab.widget(0).editor.setFocus() def _process_args(self): """ Internal function that adds processes given args If file path is given in sys.argv, we tyr to open it ... :return: """ if sys.argv: f = sys.argv[-1] if os.path.exists(f): if not os.path.basename(f) == os.path.basename(__file__): if os.path.splitext(f)[-1] in ['.txt', '.py']: self._output_console.show_message( os.path.splitext(f)[-1]) self._output_console.show_message('Open File: ' + f) self._scripts_tab.add_new_tab(os.path.basename(f), f) if self._scripts_tab.count() == 2: self._scripts_tab.removeTab(0) # ================================================================================================================= # CALLBACKS # ================================================================================================================= def _on_console_visible_changed(self, flag): """ Internal callback function that is called when console visibility is changed in the model :param flag: bool """ self._output_console.setVisible(flag) def _on_toolbar_visible_changed(self, flag): """ Internal callback function that is called when toolbar visibility is changed in the model :param flag: bool """ self._tool_bar.setVisible(flag) self._tool_bar_divider.setVisible(flag) def _on_menubar_visible_changed(self, flag): """ Internal callback function that is called when menubar visibility is changed in the model :param flag: bool """ self._menu_bar.setVisible(flag) def _on_current_tab_changed(self, index): """ Internal callback function that is called when current user selects a new script tab :param index: int """ script_widget = self._scripts_tab.widget(index) if not script_widget: return script_path = script_widget.file_path all_text = self._scripts_tab.get_current_text() with qt_contexts.block_signals(self._model): self._controller.set_current_script(script_path) self._controller.set_current_text( all_text.strip() if all_text else '') def _on_selection_changed(self, text): """ Internal callback function that is called when user selects new script text :param text: str """ with qt_contexts.block_signals(self._model): self._controller.set_selected_text(text) self._execute_selected_action.setEnabled( bool(self._model.selected_text)) def _on_script_text_changed(self, text): """ Internal callback function that is called when script text changes :param text: str """ with qt_contexts.block_signals(self._model): self._controller.set_current_text(text) def _on_session_changed(self): """ Internal callback function that is called when current session is changed in the model """ self._update_session() def _on_current_script_changed(self, script_path): """ Internal callback function that is called each time current selected script is updated in the model :param script_path: str :return: """ script_path = path_utils.clean_path(script_path) for i in range(self._scripts_tab.count()): script_widget = self._scripts_tab.widget(i) if not script_widget: continue if path_utils.clean_path(script_widget.file_path) == script_path: self._scripts_tab.setCurrentIndex(i) return def _on_current_text_changed(self, script_text): """ Internal callback function that is called when current script text is updated by the model :param script_text: str """ script_widget = self._scripts_tab.currentWidget() if not script_widget: return with qt_contexts.block_signals(self._model): script_widget.editor.setPlainText(script_text) def _on_output_text_changed(self, output_text): """ Internal callback function that is called when output text is updated in the model :param output_text: str """ with qt_contexts.block_signals(self._model): self._output_console.setText(output_text) self._output_console.move_cursor_to_line_end() def _on_script_opened(self, script_path): """ Internal callback function that is called when a new script is opened by the model :param script_path: str """ if not script_path or not os.path.isfile(script_path): return self._scripts_tab.add_new_tab(os.path.basename(script_path), script_path, skip_if_exists=True) self._refresh_stack() def _on_script_saved(self, script_path): """ Internal callback function that is called when a script is saved :param script_path: str """ script_widget = self._scripts_tab.currentWidget() if not script_widget: return with qt_contexts.block_signals(self._model): script_path = path_utils.clean_path(script_path) current_file_path = path_utils.clean_path(script_widget.file_path) if script_path != current_file_path: script_widget.file_path = script_path self._scripts_tab.set_current_tab_name( os.path.basename(script_widget.file_path)) self._controller.set_current_script(script_widget.file_path) self._controller.set_current_text( self._scripts_tab.get_current_text()) self._controller.set_selected_text( self._scripts_tab.get_current_selected_text()) def _on_script_closed(self, script_path): """ Internal callback function that is called when a script is closed by model :param script_path: str """ if not script_path: return script_path = path_utils.clean_path(script_path) for i in range(self._scripts_tab.count()): script_widget = self._scripts_tab.widget(i) if not script_widget: continue if path_utils.clean_path(script_widget.file_path) == script_path: self._scripts_tab.removeTab(i, force=True) break self._refresh_stack()
def _setup_menubar(self): """ Internal function that setups menu bar for the widget :return: """ menubar = self.menuBar() save_icon = resources.icon('save') load_icon = resources.icon('open_folder') play_icon = resources.icon('play') clear_icon = resources.icon('delete') resume_icon = resources.icon('resume') undo_icon = resources.icon('undo') redo_icon = resources.icon('redo') copy_icon = resources.icon('copy') cut_icon = resources.icon('cut') paste_icon = resources.icon('paste') tab_icon = resources.icon('tab') quote_icon = resources.icon('quote') rename_icon = resources.icon('rename') keyboard_icon = resources.icon('keyboard') help_icon = resources.icon('help') file_menu = QMenu('File', menubar) menubar.addMenu(file_menu) save_session_action = QAction(save_icon, 'Save Session', file_menu) load_script_action = QAction(load_icon, 'Load Script', file_menu) save_script_action = QAction(save_icon, 'Save Script', file_menu) file_menu.addAction(save_session_action) file_menu.addAction(load_script_action) file_menu.addAction(save_script_action) load_script_action.setShortcut('Ctrl+O') # load_script_action.setShortcutContext(Qt.WidgetShortcut) save_script_action.setShortcut('Ctrl+S') # save_script_action.setShortcutContext(Qt.WidgetShortcut) edit_menu = QMenu('Edit', self) menubar.addMenu(edit_menu) undo_action = QAction(undo_icon, 'Undo', edit_menu) redo_action = QAction(redo_icon, 'Redo', edit_menu) copy_action = QAction(copy_icon, 'Copy', edit_menu) cut_action = QAction(cut_icon, 'Cut', edit_menu) paste_action = QAction(paste_icon, 'Paste', edit_menu) tab_to_spaces_action = QAction(tab_icon, 'Tab to Spaces', edit_menu) comment_action = QAction(quote_icon, 'Comment', edit_menu) find_and_replace = QAction(rename_icon, 'Find and Replace', edit_menu) edit_menu.addAction(undo_action) edit_menu.addAction(redo_action) edit_menu.addSeparator() edit_menu.addAction(copy_action) edit_menu.addAction(cut_action) edit_menu.addAction(paste_action) edit_menu.addSeparator() edit_menu.addAction(tab_to_spaces_action) edit_menu.addAction(comment_action) edit_menu.addAction(find_and_replace) run_menu = QMenu('Run', self) menubar.addMenu(run_menu) self._execute_all_action = QAction(play_icon, 'Execute All', run_menu) self._execute_all_action.setShortcut('Ctrl+Shift+Return') self._execute_all_action.setShortcutContext(Qt.ApplicationShortcut) self._execute_selected_action = QAction(resume_icon, 'Execute Selected', run_menu) self._execute_selected_action.setShortcut('Ctrl+Return') self._execute_selected_action.setShortcutContext( Qt.WidgetWithChildrenShortcut) self._clear_output_action = QAction(clear_icon, 'Clear Output', run_menu) run_menu.addAction(self._execute_all_action) run_menu.addAction(self._execute_selected_action) run_menu.addAction(self._clear_output_action) help_menu = QMenu('Help', self) menubar.addMenu(help_menu) show_shortcuts_action = QAction(keyboard_icon, 'Show Shortcuts', help_menu) print_help_action = QAction(help_icon, 'Print Help', help_menu) help_menu.addAction(show_shortcuts_action) help_menu.addSeparator() help_menu.addAction(print_help_action) undo_action.setShortcut('Ctrl+Z') undo_action.setShortcutContext(Qt.WidgetShortcut) redo_action.setShortcut('Ctrl+Y') redo_action.setShortcutContext(Qt.WidgetShortcut) copy_action.setShortcut('Ctrl+C') copy_action.setShortcutContext(Qt.WidgetShortcut) cut_action.setShortcut('Ctrl+X') cut_action.setShortcutContext(Qt.WidgetShortcut) paste_action.setShortcut('Ctrl+V') paste_action.setShortcutContext(Qt.WidgetShortcut) comment_action.setShortcut(QKeySequence(Qt.ALT + Qt.Key_Q)) comment_action.setShortcutContext(Qt.WidgetShortcut) self._execute_all_action.triggered.connect( self._controller.execute_script) self._execute_selected_action.triggered.connect( partial(self._controller.execute_script, True)) self._clear_output_action.triggered.connect( partial(self._controller.set_output_text, '')) # open_settings_folder_action.triggered.connect(self._open_settings) # show_shortcuts_action.triggered.connect(self._open_shortcuts) # print_help_action.triggered.connect(self.editor_help) save_session_action.triggered.connect( self._controller.save_current_session) save_script_action.triggered.connect(self._controller.save_script) load_script_action.triggered.connect(self._controller.load_script) undo_action.triggered.connect(self._scripts_tab.undo) redo_action.triggered.connect(self._scripts_tab.redo) copy_action.triggered.connect(self._scripts_tab.copy) cut_action.triggered.connect(self._scripts_tab.cut) paste_action.triggered.connect(self._scripts_tab.paste) tab_to_spaces_action.triggered.connect( self._controller.convert_tab_to_spaces) # find_and_replace.triggered.connect(self._open_find_replace) comment_action.triggered.connect(self._scripts_tab.comment) return menubar