def __init__(self, parent=None, standalone=False): super(Camera, self).__init__(parent) # This prevents doing unneeded initialization # when QtDesginer loads the plugin. if parent is None and not standalone: return if not multimedia_available: return self.ui = uic.loadUi(os.path.join(WIDGET_PATH, "camera.ui"), self) self.camera = None self.imageCapture = None self.mediaRecorder = None self.isCapturingImage = False self.applicationExiting = False self.imageSettings = QImageEncoderSettings() self.audioSettings = QAudioEncoderSettings() self.videoSettings = QVideoEncoderSettings() self.videoContainerFormat = '' camera_device = QByteArray() videoDevicesGroup = QActionGroup(self) videoDevicesGroup.setExclusive(True) if not QCamera.availableDevices(): self.ui.devicesCombo.addItem("No Device") else: for deviceName in QCamera.availableDevices(): description = QCamera.deviceDescription(deviceName) self.ui.devicesCombo.addItem(description) videoDeviceAction = QAction(description, videoDevicesGroup) videoDeviceAction.setCheckable(True) videoDeviceAction.setData(deviceName) if camera_device.isEmpty(): cameraDevice = deviceName videoDeviceAction.setChecked(True) self.ui.devicesCombo.addAction(videoDeviceAction) videoDevicesGroup.triggered.connect(self.updateCameraDevice) self.ui.captureWidget.currentChanged.connect(self.updateCaptureMode) self.ui.devicesCombo.currentIndexChanged.connect(self.get_device_action) self.ui.lockButton.hide() if not IN_DESIGNER: # Start camera 2s after the UI has loaded QTimer.singleShot(2000, lambda: self.setCamera(camera_device))
def __init__(self, *args, menuBar, **kwargs): super().__init__(*args, **kwargs) self._run_to_tabs = collections.defaultdict(list) self._title_to_tab = {} self._tabs_from_streaming = [] self._overplot = OverPlotState.individual_tab self._overplot_target = None self._live_enabled = False self._live_run_router = RunRouter([self.route_live_stream]) self._containers = [TabbedViewingArea(self, menuBar=menuBar) for _ in range(2)] layout = QVBoxLayout() for container in self._containers: layout.addWidget(container) self.setLayout(layout) overplot_group = QActionGroup(self) self.off = QAction('&Off', self) self.off.setStatusTip('Drop streaming data.') self.individual_tab = QAction('&New Tab', self) self.individual_tab.setStatusTip('Open a new viewer tab for each Run.') self.latest_live = QAction('&Latest Live Tab', self) self.latest_live.setStatusTip('Attempt to overplot on the most recent live Run.') self.fixed = QAction('&Fixed Tab...', self) self.fixed.setStatusTip('Attempt to overplot on a specific tab.') self.fixed.setEnabled(False) overplot_group.addAction(self.off) overplot_group.addAction(self.individual_tab) overplot_group.addAction(self.latest_live) overplot_group.addAction(self.fixed) for action in overplot_group.actions(): action.setCheckable(True) overplot_group.setExclusive(True) self.off.setChecked(True) overplot_menu = menuBar().addMenu('&Streaming') overplot_menu.addActions(overplot_group.actions()) self.off.triggered.connect(self.disable_live) self.individual_tab.triggered.connect(partial(self.set_overplot_state, OverPlotState.individual_tab)) self.latest_live.triggered.connect(partial(self.set_overplot_state, OverPlotState.latest_live)) def set_overplot_target(): item, ok = QInputDialog.getItem( self, "Select Tab", "Tab", tuple(self._title_to_tab), 0, False) if not ok: # Abort and fallback to Off. Would be better to fall back to # previous state (which could be latest_live) but it's not # clear how to know what that state was. self.off.setChecked(True) return self.set_overplot_state(OverPlotState.fixed) self._overplot_target = item self.fixed.triggered.connect(set_overplot_target)
def getMenuAction(self, menu, title='notitle', action_name='noaction', args=[], kwargs={}): # ToDo: Clean this up, it is very hacky env = {'app': QApplication.instance(), 'win': self, 'action': actions, } if action_name is not None: if action_name.startswith('settings.'): setting_id = action_name[len('settings.'):] setting = getSetting(setting_id) if setting: if setting.enum_options is not None: submenu = QMenu(parent=self, title=title) group = QActionGroup(self) group.setExclusive(True) group.triggered.connect(lambda a: setting.setValue(a.data())) def update(group, val): for act in group.actions(): if act.data() == val: act.setChecked(True) break for num, opt in enumerate(setting.enum_options): act = QAction(parent=self, text=opt) act.setCheckable(True) if setting.value == num: act.setChecked(True) act.setData(num) setting.notify(lambda v: update(group, v)) act.setActionGroup(group) submenu.addAction(act) menu.addMenu(submenu) elif setting.value_type == bool: # works for bool settings menu_action = QAction(parent=self, text=title) menu_action.setCheckable(True) menu_action.triggered.connect(setting.setValue) setting.notify(menu_action.setChecked) menu.addAction(menu_action) return try: menu_action = QAction(parent=self, text=title) mod, action = action_name.split('.', 1) method = getattr(env.get(mod, self), action) if menu_action.isCheckable(): menu_action.triggered.connect(method) else: menu_action.triggered.connect(lambda checked: method(*args, **kwargs)) menu.addAction(menu_action) return except: pass try: menu_action = QAction(parent=self, text=title) actions.bindWidget(menu_action, action_name) menu.addAction(menu_action) return except actions.InvalidAction: LOG.exception('Error binding menu action %s', action_name) menu_action = QAction(parent=self, text=title) msg = "The <b>{}</b> action specified for the " \ "<b>{}</b> menu item could not be triggered. " \ "Check the YAML config file for errors." \ .format(action_name or '', title.replace('&', '')) menu_action.triggered.connect(lambda: QMessageBox.critical(self, "Menu Action Error!", msg)) menu.addAction(menu_action)
def __init__(self, parent=None, css_path=CSS_PATH): SpyderPluginWidget.__init__(self, parent) self.internal_shell = None self.console = None self.css_path = css_path self.no_doc_string = _("No documentation available") self._last_console_cb = None self._last_editor_cb = None self.plain_text = PlainText(self) self.rich_text = RichText(self) color_scheme = self.get_color_scheme() self.set_plain_text_font(self.get_font(), color_scheme) self.plain_text.editor.toggle_wrap_mode(self.get_option('wrap')) # Add entries to read-only editor context-menu self.wrap_action = create_action(self, _("Wrap lines"), toggled=self.toggle_wrap_mode) self.wrap_action.setChecked(self.get_option('wrap')) self.plain_text.editor.readonly_menu.addSeparator() add_actions(self.plain_text.editor.readonly_menu, (self.wrap_action,)) self.set_rich_text_font(self.get_font(rich_text=True)) self.shell = None # locked = disable link with Console self.locked = False self._last_texts = [None, None] self._last_editor_doc = None # Object name layout_edit = QHBoxLayout() layout_edit.setContentsMargins(0, 0, 0, 0) txt = _("Source") if sys.platform == 'darwin': source_label = QLabel(" " + txt) else: source_label = QLabel(txt) layout_edit.addWidget(source_label) self.source_combo = QComboBox(self) self.source_combo.addItems([_("Console"), _("Editor")]) self.source_combo.currentIndexChanged.connect(self.source_changed) if (not programs.is_module_installed('rope') and not programs.is_module_installed('jedi', '>=0.11.0')): self.source_combo.hide() source_label.hide() layout_edit.addWidget(self.source_combo) layout_edit.addSpacing(10) layout_edit.addWidget(QLabel(_("Object"))) self.combo = ObjectComboBox(self) layout_edit.addWidget(self.combo) self.object_edit = QLineEdit(self) self.object_edit.setReadOnly(True) layout_edit.addWidget(self.object_edit) self.combo.setMaxCount(self.get_option('max_history_entries')) self.combo.addItems( self.load_history() ) self.combo.setItemText(0, '') self.combo.valid.connect(self.force_refresh) # Plain text docstring option self.docstring = True self.rich_help = self.get_option('rich_mode', True) self.plain_text_action = create_action(self, _("Plain Text"), toggled=self.toggle_plain_text) # Source code option self.show_source_action = create_action(self, _("Show Source"), toggled=self.toggle_show_source) # Rich text option self.rich_text_action = create_action(self, _("Rich Text"), toggled=self.toggle_rich_text) # Add the help actions to an exclusive QActionGroup help_actions = QActionGroup(self) help_actions.setExclusive(True) help_actions.addAction(self.plain_text_action) help_actions.addAction(self.rich_text_action) # Automatic import option self.auto_import_action = create_action(self, _("Automatic import"), toggled=self.toggle_auto_import) auto_import_state = self.get_option('automatic_import') self.auto_import_action.setChecked(auto_import_state) # Lock checkbox self.locked_button = create_toolbutton(self, triggered=self.toggle_locked) layout_edit.addWidget(self.locked_button) self._update_lock_icon() # Option menu layout_edit.addWidget(self.options_button) if self.rich_help: self.switch_to_rich_text() else: self.switch_to_plain_text() self.plain_text_action.setChecked(not self.rich_help) self.rich_text_action.setChecked(self.rich_help) self.source_changed() # Main layout layout = create_plugin_layout(layout_edit) # we have two main widgets, but only one of them is shown at a time layout.addWidget(self.plain_text) layout.addWidget(self.rich_text) self.setLayout(layout) # Add worker thread for handling rich text rendering self._sphinx_thread = SphinxThread( html_text_no_doc=warning(self.no_doc_string, css_path=self.css_path), css_path=self.css_path) self._sphinx_thread.html_ready.connect( self._on_sphinx_thread_html_ready) self._sphinx_thread.error_msg.connect(self._on_sphinx_thread_error_msg) # Handle internal and external links view = self.rich_text.webview if not WEBENGINE: view.page().setLinkDelegationPolicy(QWebEnginePage.DelegateAllLinks) view.linkClicked.connect(self.handle_link_clicks) self._starting_up = True
def setup(self): self.wrap_action = self.create_action( name=HelpWidgetActions.ToggleWrap, text=_("Wrap lines"), toggled=True, initial=self.get_conf('wrap'), option='wrap' ) self.copy_action = self.create_action( name=HelpWidgetActions.CopyAction, text=_("Copy"), triggered=lambda value: self.plain_text.copy(), register_shortcut=False, ) self.select_all_action = self.create_action( name=HelpWidgetActions.SelectAll, text=_("Select All"), triggered=lambda value: self.plain_text.select_all(), register_shortcut=False, ) self.auto_import_action = self.create_action( name=HelpWidgetActions.ToggleAutomaticImport, text=_("Automatic import"), toggled=True, initial=self.get_conf('automatic_import'), option='automatic_import' ) self.show_source_action = self.create_action( name=HelpWidgetActions.ToggleShowSource, text=_("Show Source"), toggled=True, option='show_source' ) self.rich_text_action = self.create_action( name=HelpWidgetActions.ToggleRichMode, text=_("Rich Text"), toggled=True, initial=self.get_conf('rich_mode'), option='rich_mode' ) self.plain_text_action = self.create_action( name=HelpWidgetActions.TogglePlainMode, text=_("Plain Text"), toggled=True, initial=self.get_conf('plain_mode'), option='plain_mode' ) self.locked_action = self.create_action( name=HelpWidgetActions.ToggleLocked, text=_("Lock/Unlock"), toggled=True, icon=self.create_icon('lock_open'), initial=self.get_conf('locked'), option='locked' ) self.home_action = self.create_action( name=HelpWidgetActions.Home, text=_("Home"), triggered=self.show_intro_message, icon=self.create_icon('home'), ) # Add the help actions to an exclusive QActionGroup help_actions = QActionGroup(self) help_actions.setExclusive(True) help_actions.addAction(self.plain_text_action) help_actions.addAction(self.rich_text_action) # Menu menu = self.get_options_menu() for item in [self.rich_text_action, self.plain_text_action, self.show_source_action]: self.add_item_to_menu( item, menu=menu, section=HelpWidgetOptionsMenuSections.Display, ) self.add_item_to_menu( self.auto_import_action, menu=menu, section=HelpWidgetOptionsMenuSections.Other, ) # Plain text menu self._plain_text_context_menu = self.create_menu( "plain_text_context_menu") self.add_item_to_menu( self.copy_action, self._plain_text_context_menu, section="copy_section", ) self.add_item_to_menu( self.select_all_action, self._plain_text_context_menu, section="select_section", ) self.add_item_to_menu( self.wrap_action, self._plain_text_context_menu, section="wrap_section", ) # Toolbar toolbar = self.get_main_toolbar() for item in [self.source_label, self.source_combo, self.object_label, self.object_combo, self.object_edit, self.home_action, self.locked_action]: self.add_item_to_toolbar( item, toolbar=toolbar, section=HelpWidgetMainToolbarSections.Main, ) self.source_changed() self.switch_to_rich_text() self.show_intro_message() # Signals self.plain_text.sig_custom_context_menu_requested.connect( self._show_plain_text_context_menu)
def setup(self, options): self.wrap_action = self.create_action( name=HelpWidgetActions.ToggleWrap, text=_("Wrap lines"), toggled=lambda value: self.set_option('wrap', value), initial=self.get_option('wrap'), ) self.auto_import_action = self.create_action( name=HelpWidgetActions.ToggleAutomaticImport, text=_("Automatic import"), toggled=lambda value: self.set_option('automatic_import', value), initial=self.get_option('automatic_import'), ) self.show_source_action = self.create_action( name=HelpWidgetActions.ToggleShowSource, text=_("Show Source"), toggled=lambda value: self.set_option('show_source', value), ) self.rich_text_action = self.create_action( name=HelpWidgetActions.ToggleRichMode, text=_("Rich Text"), toggled=lambda value: self.set_option('rich_mode', value), initial=self.get_option('rich_mode'), ) self.plain_text_action = self.create_action( name=HelpWidgetActions.TogglePlainMode, text=_("Plain Text"), toggled=lambda value: self.set_option('plain_mode', value), initial=self.get_option('plain_mode'), ) self.locked_action = self.create_action( name=HelpWidgetActions.ToggleLocked, text=_("Lock/Unlock"), toggled=lambda value: self.set_option('locked', value), icon=self.create_icon('lock_open'), initial=self.get_option('locked'), ) # TODO: Temporal while code editor migrates to SpyderMixin self.plain_text.set_wrap_action(self.wrap_action) # Add the help actions to an exclusive QActionGroup help_actions = QActionGroup(self) help_actions.setExclusive(True) help_actions.addAction(self.plain_text_action) help_actions.addAction(self.rich_text_action) # Menu menu = self.get_options_menu() for item in [self.rich_text_action, self.plain_text_action, self.show_source_action]: self.add_item_to_menu( item, menu=menu, section=HelpWidgetOptionsMenuSections.Display, ) self.add_item_to_menu( self.auto_import_action, menu=menu, section=HelpWidgetOptionsMenuSections.Other, ) # Toolbar toolbar = self.get_main_toolbar() for item in [self.source_label, self.source_combo, self.object_label, self.object_combo, self.object_edit, self.locked_action]: self.add_item_to_toolbar( item, toolbar=toolbar, section=HelpWidgetMainToolBarSections.Main, ) self.source_changed() self.switch_to_rich_text() self.show_intro_message()
def __init__(self, parent): if PYQT5: SpyderPluginWidget.__init__(self, parent, main = parent) else: SpyderPluginWidget.__init__(self, parent) self.internal_shell = None # Initialize plugin self.initialize_plugin() self.no_doc_string = _("No further documentation available") self._last_console_cb = None self._last_editor_cb = None self.plain_text = PlainText(self) self.rich_text = RichText(self) color_scheme = self.get_color_scheme() self.set_plain_text_font(self.get_plugin_font(), color_scheme) self.plain_text.editor.toggle_wrap_mode(self.get_option('wrap')) # Add entries to read-only editor context-menu self.wrap_action = create_action(self, _("Wrap lines"), toggled=self.toggle_wrap_mode) self.wrap_action.setChecked(self.get_option('wrap')) self.plain_text.editor.readonly_menu.addSeparator() add_actions(self.plain_text.editor.readonly_menu, (self.wrap_action,)) self.set_rich_text_font(self.get_plugin_font('rich_text')) self.shell = None self.external_console = None # locked = disable link with Console self.locked = False self._last_texts = [None, None] self._last_editor_doc = None # Object name layout_edit = QHBoxLayout() layout_edit.setContentsMargins(0, 0, 0, 0) txt = _("Source") if sys.platform == 'darwin': source_label = QLabel(" " + txt) else: source_label = QLabel(txt) layout_edit.addWidget(source_label) self.source_combo = QComboBox(self) self.source_combo.addItems([_("Console"), _("Editor")]) self.source_combo.currentIndexChanged.connect(self.source_changed) if (not programs.is_module_installed('rope') and not programs.is_module_installed('jedi', '>=0.8.1')): self.source_combo.hide() source_label.hide() layout_edit.addWidget(self.source_combo) layout_edit.addSpacing(10) layout_edit.addWidget(QLabel(_("Object"))) self.combo = ObjectComboBox(self) layout_edit.addWidget(self.combo) self.object_edit = QLineEdit(self) self.object_edit.setReadOnly(True) layout_edit.addWidget(self.object_edit) self.combo.setMaxCount(self.get_option('max_history_entries')) self.combo.addItems( self.load_history() ) self.combo.setItemText(0, '') self.combo.valid.connect(lambda valid: self.force_refresh()) # Plain text docstring option self.docstring = True self.rich_help = self.get_option('rich_mode', True) self.plain_text_action = create_action(self, _("Plain Text"), toggled=self.toggle_plain_text) # Source code option self.show_source_action = create_action(self, _("Show Source"), toggled=self.toggle_show_source) # Rich text option self.rich_text_action = create_action(self, _("Rich Text"), toggled=self.toggle_rich_text) # Add the help actions to an exclusive QActionGroup help_actions = QActionGroup(self) help_actions.setExclusive(True) help_actions.addAction(self.plain_text_action) help_actions.addAction(self.rich_text_action) # Automatic import option self.auto_import_action = create_action(self, _("Automatic import"), toggled=self.toggle_auto_import) auto_import_state = self.get_option('automatic_import') self.auto_import_action.setChecked(auto_import_state) # Lock checkbox self.locked_button = create_toolbutton(self, triggered=self.toggle_locked) layout_edit.addWidget(self.locked_button) self._update_lock_icon() # Option menu options_button = create_toolbutton(self, text=_('Options'), icon=ima.icon('tooloptions')) options_button.setPopupMode(QToolButton.InstantPopup) menu = QMenu(self) add_actions(menu, [self.rich_text_action, self.plain_text_action, self.show_source_action, None, self.auto_import_action]) options_button.setMenu(menu) layout_edit.addWidget(options_button) if self.rich_help: self.switch_to_rich_text() else: self.switch_to_plain_text() self.plain_text_action.setChecked(not self.rich_help) self.rich_text_action.setChecked(self.rich_help) self.source_changed() # Main layout layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addLayout(layout_edit) layout.addWidget(self.plain_text) layout.addWidget(self.rich_text) self.setLayout(layout) # Add worker thread for handling rich text rendering self._sphinx_thread = SphinxThread( html_text_no_doc=warning(self.no_doc_string)) self._sphinx_thread.html_ready.connect( self._on_sphinx_thread_html_ready) self._sphinx_thread.error_msg.connect(self._on_sphinx_thread_error_msg) # Handle internal and external links view = self.rich_text.webview if not WEBENGINE: view.page().setLinkDelegationPolicy(QWebEnginePage.DelegateAllLinks) view.linkClicked.connect(self.handle_link_clicks) self._starting_up = True
class ToggleColumnMixIn(object): """ Adds actions to a QTableView that can show/hide columns by right clicking on the header """ def add_header_context_menu(self, checked=None, checkable=None, enabled=None): """ Adds the context menu from using header information checked can be a header_name -> boolean dictionary. If given, headers with the key name will get the checked value from the dictionary. The corresponding column will be hidden if checked is False. checkable can be a header_name -> boolean dictionary. If given, headers with the key name will get the checkable value from the dictionary. enabled can be a header_name -> boolean dictionary. If given, headers with the key name will get the enabled value from the dictionary. """ checked = checked if checked is not None else {} checkable = checkable if checkable is not None else {} enabled = enabled if enabled is not None else {} horizontal_header = self._horizontal_header() horizontal_header.setContextMenuPolicy(Qt.ActionsContextMenu) self.toggle_column_actions_group = QActionGroup(self) self.toggle_column_actions_group.setExclusive(False) self.__toggle_functions = [] # for keeping references for col in range(horizontal_header.count()): column_label = self.model().headerData(col, Qt.Horizontal, Qt.DisplayRole) logger.debug("Adding: col {}: {}".format(col, column_label)) action = QAction(str(column_label), self.toggle_column_actions_group, checkable=checkable.get(column_label, True), enabled=enabled.get(column_label, True), toolTip=_("Shows or hides " "the {} column").format(column_label)) func = self.__make_show_column_function(col) self.__toggle_functions.append(func) # keep reference horizontal_header.addAction(action) is_checked = checked.get( column_label, not horizontal_header.isSectionHidden(col)) horizontal_header.setSectionHidden(col, not is_checked) action.setChecked(is_checked) action.toggled.connect(func) def get_header_context_menu_actions(self): """Returns the actions of the context menu of the header.""" return self._horizontal_header().actions() def _horizontal_header(self): """ Returns the horizontal header (of type QHeaderView). Override this if the horizontalHeader() function does not exist. """ return self.horizontalHeader() def __make_show_column_function(self, column_idx): """Creates a function that shows or hides a column.""" show_column = lambda checked: self.setColumnHidden(column_idx, not checked) return show_column def read_view_settings(self, key, settings=None, reset=False): """ Reads the persistent program settings :param reset: If True, the program resets to its default settings :returns: True if the header state was restored, otherwise returns False """ logger.debug("Reading view settings for: {}".format(key)) header_restored = False # TODO: Implement settings management # if not reset: # if settings is None: # settings = get_qsettings() # horizontal_header = self._horizontal_header() # header_data = settings.value(key) # if header_data: # header_restored = horizontal_header.restoreState(header_data) # # # update actions # for col, action in enumerate(horizontal_header.actions()): # is_checked = not horizontal_header.isSectionHidden(col) # action.setChecked(is_checked) return header_restored def write_view_settings(self, key, settings=None): """Writes the view settings to the persistent store.""" logger.debug("Writing view settings for: {}".format(key))