def _init(self): menu = self._interface.getMaViewerIndicatorParentMenu() maIndicatorMenu = menu.addMenu('均线视图指标') # OHLC openAction = QAction('开盘价', maIndicatorMenu) openAction.triggered.connect(self._act) openAction.setCheckable(True) maIndicatorMenu.addAction(openAction) highAction = QAction('最高价', maIndicatorMenu) highAction.triggered.connect(self._act) highAction.setCheckable(True) maIndicatorMenu.addAction(highAction) lowAction = QAction('最低价', maIndicatorMenu) lowAction.triggered.connect(self._act) lowAction.setCheckable(True) maIndicatorMenu.addAction(lowAction) closeAction = QAction('收盘价', maIndicatorMenu) closeAction.triggered.connect(self._act) closeAction.setCheckable(True) maIndicatorMenu.addAction(closeAction) self._actions = [(openAction, 'open'), (highAction, 'high'), (lowAction, 'low'), (closeAction, 'close')] closeAction.setChecked(True) self._checkedAction = closeAction self._checkedIndicator = 'close'
def addColumnCategory(self, name, columns, visible=True): qa = QAction(name, self) qa.setCheckable(True) qa.setChecked(visible) if not visible: self._showColumnCategory(columns, False) qa.toggled[bool].connect( self._currier.curry(self._showColumnCategory, columns)) self._column_views.append((name, qa, columns))
def _createEncodingAction(self, codecName, activeCodecName, menu): ''' @param: codecName QString @param: activeCodecName QString @param: menu QMenu ''' action = QAction(codecName, menu) action.setData(codecName) action.setCheckable(True) action.triggered.connect(self._changeEncoding) if activeCodecName.lower() == codecName.lower(): action.setChecked(True) return action
def contextMenuEvent(self, event): ''' @param: event QContextMenuEvent ''' if not self._menu: self._menu = QMenu(self) for idx in range(self.count()): act = QAction(self.model().headerData(idx, Qt.Horizontal), self._menu) act.setCheckable(True) act.setData(idx) act.triggered.connect(self._toggleSectionVisibility) self._menu.addAction(act) for idx, act in enumerate(self._menu.actions()): act.setEnabled(idx > 0) act.setChecked(not self.isSectionHidden(idx)) self._menu.popup(event.globalPos())
class MainWindow(QMainWindow): def __init__(self, app): super(MainWindow, self).__init__() self.app = app print('window created') self.setWindowIcon(QIcon('img/icon.png')) self.setWindowTitle('Kasino') self.setPalette(QPalette(Qt.darkGreen)) self.setup_music() self.statusbar = QStatusBar(self) self.statusbar.setStyleSheet('background: white') self.setStatusBar(self.statusbar) self.statusbar.showMessage('Welcome to the Cassino game!') self.menubar = QMenuBar(self) self.optionsMenu = self.menubar.addMenu('Options') self.music_toggle = QAction() self.music_toggle.setText('Music') self.music_toggle.setShortcut('Ctrl+m') self.music_toggle.setCheckable(True) self.music_toggle.setChecked(True) self.optionsMenu.addAction(self.music_toggle) self.music_toggle.triggered.connect(self.toggle_music) self.speedGroup = QActionGroup(self) self.speedGroup.triggered.connect(self.set_speed) self.slow_speed = QAction('Slow', self.speedGroup) self.slow_speed.setCheckable(True) self.normal_speed = QAction('Normal', self.speedGroup) self.normal_speed.setCheckable(True) self.fast_speed = QAction('Fast', self.speedGroup) self.fast_speed.setCheckable(True) self.vfast_speed = QAction('Very Fast', self.speedGroup) self.vfast_speed.setCheckable(True) self.normal_speed.setChecked(True) self.speed_menu = self.optionsMenu.addMenu('Speed') self.speed_menu.addActions(self.speedGroup.actions()) self.menubar.setMouseTracking(False) self.setMenuBar(self.menubar) self.play_widget = PlayWidget(self) self.main_menu = MainMenu(self) self.start_menu = StartMenu(self) self.widgets = QStackedWidget(self) self.widgets.addWidget(self.play_widget) self.widgets.addWidget(self.main_menu) self.widgets.addWidget(self.start_menu) self.widgets.setCurrentWidget(self.main_menu) self.setCentralWidget(self.widgets) self.setGeometry(25, 50, 1028, 720) self.main_menu.startbutton.clicked.connect(self.init_game) self.main_menu.loadbutton.clicked.connect(self.load_game) self.main_menu.quitbutton.clicked.connect(self.quit) self.play_widget.quit_button.clicked.connect(self.quit_to_menu) self.play_widget.save_button.clicked.connect(self.save_game) self.start_menu.startbutton.clicked.connect(self.start_game) def setup_music(self): self.music = QMediaPlayer() self.playlist = QMediaPlaylist() self.playlist.setPlaybackMode(QMediaPlaylist.Loop) file_name = "sound/bg.mp3" self.media = QMediaContent(QUrl.fromLocalFile(file_name)) self.playlist.addMedia(self.media) self.music.setPlaylist(self.playlist) self.music.setVolume(20) self.music.play() def toggle_music(self): if self.music.isMuted(): self.music.setMuted(False) self.statusbar.showMessage('Music on', 5000) else: self.music.setMuted(True) self.statusbar.showMessage('Music off', 5000) def set_speed(self, action): if action == self.slow_speed: self.play_widget.speed = 1 elif action == self.normal_speed: self.play_widget.speed = 3 elif action == self.fast_speed: self.play_widget.speed = 4 else: self.play_widget.speed = 6 def start_game(self): self.play_widget.init_game( self.start_menu.extract_info_and_init_game()) self.widgets.setCurrentWidget(self.play_widget) self.statusbar.showMessage('Game launched', 2000) def load_game(self): path = QFileDialog.getOpenFileName(self, 'Open save file', QDir.currentPath() + '/sav')[0] if path != '': game, msg, count = load(path) self.play_widget.resume_from_save(game, msg, count) self.widgets.setCurrentWidget(self.play_widget) self.statusbar.showMessage('Loaded save file', 5000) def save_game(self): path = QFileDialog.getSaveFileName(self, 'Create save file', QDir.currentPath() + '/sav')[0] if path != '': save(path, self.play_widget.game, self.play_widget.export_log(), self.play_widget.move_count) self.statusbar.showMessage('Game saved', 5000) def init_game(self): self.widgets.setCurrentWidget(self.start_menu) self.statusbar.showMessage('Starting new game') def quit_to_menu(self): #Reset playwidget self.widgets.removeWidget(self.play_widget) speed = self.play_widget.speed self.play_widget.setParent(None) self.play_widget = PlayWidget(self) self.play_widget.speed = speed self.widgets.addWidget(self.play_widget) self.play_widget.quit_button.clicked.connect(self.quit_to_menu) self.play_widget.save_button.clicked.connect(self.save_game) self.widgets.setCurrentWidget(self.main_menu) def closeEvent(self, *args, **kwargs): #for handling closing from 'x' button self.quit() def quit(self): print('Exited game. Thanks for playing!\n') self.app.exit()
class TextToSpeechPlugin(ViewerPlugin): ''' ''' name = 'TTS Ebook Viewer' description = 'adds TTS capability to ebook-viewer' supported_platforms = ['windows'] author = 'Christine Ye' version = (0, 0, 2) minimum_calibre_version = (0, 7, 53) def customize_ui(self, ui): self.ebookViewer = ui self.tts_speaker = TTSSpeaker(ui) self.ebookViewer.tts_speaker = self.tts_speaker ui.tool_bar.addSeparator() self.speak_button = QAction('play / pause', ui) ui.tool_bar.addAction(self.speak_button) self.speak_button.triggered.connect(self.tts_speaker.playOrPause) self.tts_speaker.toolbarButton = self.speak_button self.select_mode_button = QAction('select mode', ui) ui.tool_bar.addAction(self.select_mode_button) self.select_mode_button.triggered.connect( self.tts_speaker.toggleSelectMode) self.select_mode_button.setCheckable(True) self.select_mode_button.setChecked(False) self.tts_speaker.toggleSelectModeButton = self.select_mode_button self.stop_button = QAction('stop', ui) ui.tool_bar.addAction(self.stop_button) self.stop_button.triggered.connect(self.tts_speaker.stop) # HACK? # append a callback to the javaScriptWindowObjectCleared # signal receiver. If you don't do this, the `py_annotator` # object will be empty (has no python functions callable) # from js ui.view.document.mainFrame().javaScriptWindowObjectCleared.connect( self.add_window_objects) # print ("finished customizing ") def add_window_objects(self): self.ebookViewer.view.document.mainFrame().addToJavaScriptWindowObject( 'tts_speaker', Responder(self.ebookViewer.view.document)) # this function is by far the slowest, and is what causes pauses in the render def run_javascript(self, evaljs): ''' this gets called after load_javascript. ''' # inject css evaljs(''' $("<style>.tts_reading { background-color: yellow !important;} p.tts_selectMode:hover { background-color: #e7eaa4; } </style>").appendTo(document.head) ''') self.evaljs = evaljs self.tts_speaker.evaljs = evaljs def jsbool(pyBool): return unicode(pyBool).lower() from calibre_plugins.tts_ebook_viewer.config import prefs if prefs['pause_hotkey_enabled'] or prefs[ 'stop_hotkey_enabled'] or prefs['select_hotkey_enabled']: hotkeyjs = ''' $(document).keydown(function(event) { if (%s && event.ctrlKey == %s && event.altKey == %s && event.shiftKey == %s && event.which == %i) { tts_speaker.playOrPause() } else if (%s && event.ctrlKey == %s && event.altKey == %s && event.shiftKey == %s && event.which == %i) { tts_speaker.stop() } else if (%s && event.ctrlKey == %s && event.altKey == %s && event.shiftKey == %s && event.which == %i) { tts_speaker.toggleSelectMode() } }) ''' hotkeyArgs = [] for hotkey in ['pause', 'stop', 'select']: hotkeyArgs.append(jsbool(prefs[hotkey + '_hotkey_enabled'])) hotkeyArgs.append(jsbool(prefs[hotkey + '_hotkey_ctrl'])) hotkeyArgs.append(jsbool(prefs[hotkey + '_hotkey_alt'])) hotkeyArgs.append(jsbool(prefs[hotkey + '_hotkey_shift'])) hotkeyArgs.append(prefs[hotkey + '_hotkey_keycode']) self.evaljs(hotkeyjs % tuple(hotkeyArgs)) if self.tts_speaker.isPlaying: print("TTS: Start reading automatically") evaljs(''' $currentReading = getFirstParagraphInView().addClass("tts_reading") tts_speaker.readText($currentReading.text()); ''') def load_javascript(self, evaljs): ''' from calibre docs: This method is called every time a new HTML document is loaded in the viewer. Use it to load javascript libraries into the viewer. ''' evaljs(''' function getFirstParagraphInView() { $p = $("body").find(":visible") if (window.paged_display != null && window.paged_display.in_paged_mode) { var columnLeft = window.paged_display.current_column_location() $p.each(function(index, element) { var br = element.getBoundingClientRect() var pos = calibre_utils.viewport_to_document(br.left, br.top, element.ownerDocument) if (pos[0] >= columnLeft && pos[0] < columnLeft + window.paged_display.page_width) { $currentReading = $(element); $currentReading.addClass("tts_reading") return false; } }) } else { var $window = $(window); var docViewTop = $window.scrollTop(); var docViewBottom = docViewTop + $window.height(); $p.each(function(index, element) { $elem = $(element) var elemTop = $elem.offset().top; var elemBottom = elemTop + $elem.height(); if ((elemTop <= docViewBottom) && (elemTop >= docViewTop)) { $currentReading = $elem; $currentReading.addClass("tts_reading") return false; } }) } return $currentReading } ''') def is_customizable(self): ''' This method must return True to enable customization via Preferences->Plugins ''' return True def config_widget(self): ''' Implement this method and :meth:`save_settings` in your plugin to use a custom configuration dialog. This method, if implemented, must return a QWidget. The widget can have an optional method validate() that takes no arguments and is called immediately after the user clicks OK. Changes are applied if and only if the method returns True. If for some reason you cannot perform the configuration at this time, return a tuple of two strings (message, details), these will be displayed as a warning dialog to the user and the process will be aborted. The base class implementation of this method raises NotImplementedError so by default no user configuration is possible. ''' # It is important to put this import statement here rather than at the # top of the module as importing the config class will also cause the # GUI libraries to be loaded, which we do not want when using calibre # from the command line from calibre_plugins.tts_ebook_viewer.config import ConfigWidget # print('config config') return ConfigWidget() def save_settings(self, config_widget): ''' Save the settings specified by the user with config_widget. :param config_widget: The widget returned by :meth:`config_widget`. ''' config_widget.save_settings()
class ParameterPanel(EditionWidget, WidgetController): """Edition Panel implementation.""" def __init__(self, astergui, parent=None): """ Create panel. Arguments: astergui (AsterGui): AsterGui instance. parent (Optional[QWidget]): Parent widget. """ super(ParameterPanel, self).__init__(parent=parent, name=translate("ParameterPanel", "Edit command"), astergui=astergui) self.setPixmap(load_pixmap("as_pic_edit_command.png")) self._files_model = astergui.study().dataFilesModel() self._unit_model = None self._command = None self.title = ParameterTitle(self) self.title.installEventFilter(self) self._name = QLineEdit(self) self.views = QStackedWidget(self) v_layout = QVBoxLayout(self) v_layout.setContentsMargins(0, 0, 0, 0) v_layout.setSpacing(5) v_layout.addWidget(self.title) v_layout.addWidget(HLine(self)) n_layout = QHBoxLayout() v_layout.addLayout(n_layout) n_layout.addWidget(QLabel(translate("ParameterPanel", "Name"), self)) n_layout.addWidget(self._name) # force to be a valid identifier + length <= 8 self._name.setValidator(QRegExpValidator(QRegExp(r"[a-zA-Z]\w{1,7}"))) # create toolbar tbar = QToolBar(self) tbar.setToolButtonStyle(Qt.ToolButtonIconOnly) # - Edit comment edit_comment = QAction(translate("AsterStudy", "Edit &Comment"), self) edit_comment.setToolTip(translate("AsterStudy", "Edit comment")) edit_comment.setStatusTip( translate("AsterStudy", "Edit comment for the " "selected object")) edit_comment.setIcon(load_icon("as_pic_edit_comment.png")) connect(edit_comment.triggered, self._editComment) tbar.addAction(edit_comment) # - Switch on/off business-translations title = translate("AsterStudy", "Use Business-Oriented Translations") self.use_translations = QAction(title, self) title = translate("AsterStudy", "Use business-oriented translations") self.use_translations.setToolTip(title) self.use_translations.setStatusTip(title) self.use_translations.setIcon(load_icon("as_pic_use_translations.png")) self.use_translations.setCheckable(True) if behavior().forced_native_names: force = behavior().force_native_names self.use_translations.setDisabled(True) is_on = not force else: is_on = behavior().use_business_translations Options.use_translations = is_on self.use_translations.setChecked(is_on) connect(self.use_translations.toggled, self.updateTranslations) tbar.addAction(self.use_translations) # - Hide unused hide_unused = astergui.action(ActionType.HideUnused) connect(hide_unused.toggled, self._unusedVisibility) tbar.addAction(hide_unused) # - What's this whats_this = QWhatsThis.createAction(tbar) whats_this.setToolTip(translate("AsterStudy", "What's this?")) whats_this.setStatusTip( translate("AsterStudy", "Show element's description")) whats_this.setIcon(load_icon("as_pic_whats_this.png")) tbar.addAction(whats_this) # - Link to doc tbar.addAction(astergui.action(ActionType.LinkToDoc)) n_layout.addWidget(tbar) v_layout.addWidget(self.views) self._updateState() def unitModel(self): """ Method that get unit model. Returns: UnitModel: Unit model. """ return self._unit_model def command(self): """ Get command being edited. Returns: Command: Command being edited. """ return self._command def setCommand(self, command): """ Set command to edit. Arguments: command (Command): Command to edit. """ self.clear() self._command = command if self._command is None: self._name.setText("") else: self._name.setText(self._command.name) self._unit_model = UnitModel(command.stage) pview = self._createParameterView(ParameterPath(self._command), '') pview.view().setItemValue(command.storage) hide_unused = self.astergui().action(ActionType.HideUnused) pview.setUnusedVisibile(not hide_unused.isChecked()) self.views.setCurrentWidget(pview) self._updateState() def currentPath(self): """ Get currently edited parameter path. Returns: str: currently edited parameter path. """ path = "" wid = self.currentParameterView() if wid is not None: path = wid.path() return path def isCurrentCommand(self): """ Get true if the currently edited view contains command. Returns: bool: Current edited command flag """ curpath = self.currentPath() return ParameterPath(self.command()).isEqual(curpath) def currentParameterView(self): """ Get current parameter view. Returns: ParameterView: current view. """ return self.views.currentWidget() def clear(self): """Remove all parameter views.""" while self.views.count() > 0: wid = self.views.widget(0) if wid is not None: self.views.removeWidget(wid) wid.deleteLater() def store(self): """ Save data from all parameter views. """ cmd = self.command() if cmd is not None: with auto_dupl_on(self.astergui().study().activeCase): cmd.rename(self._name.text()) wid = self._viewByPath(ParameterPath(cmd)) if wid is not None: cmd.init(wid.view().itemValue()) def requiredButtons(self): """ Return the combination of standard button flags required for this widget. Returns: int: button flags for buttons required for this widget (combination of QDialogButtonBox.StandardButton flags). """ if self.isCurrentCommand(): return QDialogButtonBox.Ok | QDialogButtonBox.Apply | \ QDialogButtonBox.Close else: return QDialogButtonBox.Ok | QDialogButtonBox.Cancel | \ QDialogButtonBox.Abort def isButtonEnabled(self, button): """ Return True if a particular button is enabled. Arguments: button (QDialogButtonBox.StandardButton): button flag. Returns: True: that means that all buttons should be enabled. """ return True def perform(self, button): """ Perform action on button click. Redefined method from the base class. Arguments: button (QDialogButtonBox.StandardButton): clicked button flag. """ if button == QDialogButtonBox.Ok: self.performOk() elif button == QDialogButtonBox.Apply: self.performApply() elif button == QDialogButtonBox.Abort: self.performAbort() elif button == QDialogButtonBox.Close or \ button == QDialogButtonBox.Cancel: self.performClose() def performOk(self): """Called when `Ok` button is clicked in Edition panel.""" self.performChanges(True) def performApply(self): """Called when `Apply` button is clicked in Edition panel.""" self.performChanges(False) def performAbort(self): """Called when `Abort` button is clicked in Edition panel.""" pref_mgr = self.astergui().preferencesMgr() msg = translate( "ParameterPanel", "Command edition will be aborted and " "all made changes will be lost. " "Do you want to continue?") noshow = "parampanel_abort" ask = MessageBox.question(self.astergui().mainWindow(), translate("ParameterPanel", "Abort"), msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes, noshow=noshow, prefmgr=pref_mgr) if ask == QMessageBox.Yes: self.close() self.astergui().study().revert() def performClose(self): """Called when `Cancel` button is clicked in Edition panel.""" has_modif = self._hasModifications() if has_modif: pref_mgr = self.astergui().preferencesMgr() msg = translate( "ParameterPanel", "There are some unsaved modifications will be " "lost. Do you want to continue?") noshow = "parampanel_close" ask = MessageBox.question(self.astergui().mainWindow(), translate("ParameterPanel", "Close"), msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes, noshow=noshow, prefmgr=pref_mgr) has_modif = ask != QMessageBox.Yes if not has_modif: self.performDissmis(True) def performChanges(self, close=True): """ Validate and store the command into data model. """ wid = self.currentParameterView() if wid is not None: view = wid.view() if view.validate(): cur_path = self.currentPath() if self.isCurrentCommand(): self.store() self._files_model.update() if self.astergui() is not None: opname = translate("ParameterPanel", "Edit command") self.astergui().study().commit(opname) self.astergui().update() if close: self.performDissmis(False) msg = translate("ParameterPanel", "Command '{}' successfully stored") msg = msg.format(self._name.text()) self.astergui().showMessage(msg) else: child_val = view.itemValue() self._removeCurrentView() curview = self.currentParameterView() subitem = curview.view().findItemByPath(cur_path) if subitem is not None: subitem.setItemValue(child_val) self._updateState() self.updateButtonStatus() def performDissmis(self, revert=True): """ Cancel changes and revert the command changes. """ if self.isCurrentCommand(): self.close() if revert: self.astergui().study().revert() else: self._removeCurrentView() self._updateState() self.updateButtonStatus() def showEvent(self, event): """ Reimplemented for internal reason: updates the title depending on read only state, etc. """ title = translate("ParameterPanel", "View command") \ if self.isReadOnly() else \ translate("ParameterPanel", "Edit command") self.setWindowTitle(title) hide_unused = self.astergui().action(ActionType.HideUnused) hide_unused.setVisible(True) hide_unused.setChecked(self.isReadOnly()) # update meshview meshes = avail_meshes_in_cmd(self.command()) for i, mesh in enumerate(meshes): filename, meshname = get_cmd_mesh(mesh) if filename: if i > 0: self.meshview().displayMEDFileName(filename, meshname, 1.0, False) else: self.meshview().displayMEDFileName(filename, meshname, 1.0, True) super(ParameterPanel, self).showEvent(event) def hideEvent(self, event): """ Reimplemented for internal reason: hides "Hide unused" action. """ hide_unused = self.astergui().action(ActionType.HideUnused) hide_unused.setVisible(False) super(ParameterPanel, self).hideEvent(event) def updateTranslations(self): """ Update translations in GUI elements. """ Options.use_translations = self.use_translations.isChecked() self._updateState() for i in xrange(self.views.count()): view = self.views.widget(i) view.updateTranslations() def eventFilter(self, receiver, event): """ Event filter; processes clicking ln links in What's This window. """ if receiver == self.title and event.type() == QEvent.WhatsThisClicked: QDesktopServices.openUrl(QUrl(event.href())) return super(ParameterPanel, self).eventFilter(receiver, event) def _hasModifications(self): curview = self.currentParameterView().view() \ if self.currentParameterView() is not None else None return curview.hasModifications() \ if curview is not None else False def _updateState(self): """Update state and current title label.""" disabled = self.command() is None self.setDisabled(disabled) if not disabled: disabled = self.command().gettype(ConversionLevel.NoFail) is None self._name.setDisabled(disabled) txt = [] pview = self.currentParameterView() if pview is not None: txt = pview.path().names() ppath = None txt_list = [] tooltip = "" whats_this = "" while len(txt) > 0: name = txt.pop(0) if ppath is None: ppath = ParameterPath(self.command(), name=name) else: ppath = ppath.absolutePath(name) if ppath.isInSequence(): txt_list.append("[" + name + "]") elif get_cata_typeid(ppath.keyword()) in (IDS.simp, IDS.fact): # translate keyword kwtext = Options.translate_command(ppath.command().title, name) txt_list.append(kwtext) elif get_cata_typeid(ppath.keyword()) == IDS.command: # translate command translation = Options.translate_command(name) txt_list.append(translation) if translation != name: wttext = italic(translation) + " ({})".format(bold(name)) else: wttext = bold(name) tooltip = preformat(wttext) url = self.astergui().doc_url(name) if url: wttext += " " wttext += href( image(CFG.rcfile("as_pic_help.png"), width=20, height=20), url) wttext = preformat(wttext) docs = CATA.get_command_docstring(name) if docs: wttext += "<hr>" wttext += docs whats_this = wttext self.title.setTitle(txt_list) self.title.setToolTip(tooltip) self.title.setWhatsThis(whats_this) def _removeCurrentView(self): """ Remove the parameter view for given object. Arguments: obj (Parameter): Command's parameter. """ curview = self.currentParameterView() if curview is not None: master = curview.view().masterItem() if master is not None and master.slaveItem() == curview.view(): master.setSlaveItem(None) curview.view().setMasterItem(None) view = self._parentView(curview) if view is not None: self.views.setCurrentWidget(view) hide_unused = self.astergui().action(ActionType.HideUnused) view.setUnusedVisibile(not hide_unused.isChecked()) self.views.removeWidget(curview) curview.deleteLater() self._updateState() def _viewByPath(self, path): view = None for i in xrange(self.views.count()): the_view = self.views.widget(i) if the_view.path().isEqual(path): view = the_view break return view def _parentView(self, curview): view = None path = curview.path() while path is not None and view is None: path = path.parentPath() view = self._viewByPath(path) return view def _gotoParameter(self, path, link): """ Activate the parameter view for object with given id. Arguments: uid (int): Object's UID. """ curview = self.currentParameterView() act_item = curview.view().findItemByPath(path) child_val = None wid = self._createParameterView(path, link) if act_item is not None: child_val = act_item.itemValue() act_item.setSlaveItem(wid.view()) wid.view().setMasterItem(act_item) hide_unused = self.astergui().action(ActionType.HideUnused) wid.setUnusedVisibile(not hide_unused.isChecked()) self.views.setCurrentWidget(wid) wid.view().setItemValue(child_val) self._updateState() self.updateButtonStatus() def _createParameterView(self, path, link): """ Create parameter view for given object. Arguments: path (ParameterPath): Path of parameter to edit. Returns: ParameterWindow: Parameter view for parameter path. """ # pragma pylint: disable=redefined-variable-type pview = None if link == EditorLink.Table: pview = ParameterTableWindow(path, self, self.views) elif link == EditorLink.List: pview = ParameterListWindow(path, self, self.views) elif link == EditorLink.GrMa: pview = ParameterMeshGroupWindow(path, self, self.views) else: pview = ParameterFactWindow(path, self, self.views) connect(pview.gotoParameter, self._gotoParameter) self.views.addWidget(pview) return pview def _unusedVisibility(self, ison): """ Invoked when 'Hide unused' button toggled """ curview = self.currentParameterView() curview.setUnusedVisibile(not ison) def meshview(self): """ Returns the central *MeshView* object """ return self.astergui().workSpace().panels[Panel.View] def _editComment(self): """ Invoked when 'Edit comment' button is clicked """ panel = CommentPanel(self.astergui(), owner=self) panel.node = self.command() self.astergui().workSpace().panel(Panel.Edit).setEditor(panel) def pendingStorage(self): """ Dictionnary being filled as this command is edited. """ wid = self._viewByPath(ParameterPath(self.command())) if wid is not None: return wid.view().itemValue() return None
def __initUI(self): self.resize(850, 650) self.center() self.setWindowTitle('Application de tracking vidéo') self.statusBar() # status bar at the bottom of the window # QTabWidget of the application showing the 5 tabs self.tabs = QTabWidget() # tab1: display video images & video metadata self.imageTab = ImageDisplay(self) # tab2: plot (y(t), x(t)) self.onePlot = OnePlot(self) # tab3: plot curves x(t) and y(t) self.twoPlots_xy = TwoPlots(self, "position") # tab4: plot curves Vx(t) and Vy(t) self.twoPlots_VxVy = TwoPlots(self, "velocity") # tab5: plot of f(t)=f(x(t), y(t), t) self.functionOfXY = FunctionPlot(self) # tab6: IPython shell self.pythonConsole = PythonConsole(self) self.tabs.addTab(self.imageTab,"Visualisation images") self.tabs.addTab(self.onePlot,"Trajectoire") self.tabs.addTab(self.twoPlots_xy,"Positions") self.tabs.addTab(self.twoPlots_VxVy,"Vitesses") self.tabs.addTab(self.functionOfXY,"Outil de tracé") self.tabs.addTab(self.pythonConsole,"IPython") self.setCentralWidget(self.tabs) # Menu(s) self.menubar = self.menuBar() if platform.uname().system.startswith('Darw') : # Mac OS specificity: self.menubar.setNativeMenuBar(False) ###### Menu 'Files' fileMenu = self.menubar.addMenu('&Fichier') ### Open images directory: qa = QAction(QIcon(VideoTracker.icone_dir+'/open.png'), 'Ouvrir dossier images', self) qa.setShortcut('Ctrl+D') qa.setStatusTip("Ouvre un dossier contenant déjà "+\ "les images d'une vidéo") # connexion avec la méthode 'load_images_from_directory' qui est # définie dans l'objet 'imageTab' : qa.triggered.connect(self.imageTab.load_images_from_directory) fileMenu.addAction(qa) ### Load a video file : qa = QAction(QIcon(VideoTracker.icone_dir+'/open.png'), "Charger un fichier vidéo", self) qa.setShortcut('Ctrl+O') qa.setStatusTip('Ouvre un fihier vidéo et le '+\ 'découpe en images successives...') # connexion avec la méthode 'open_video' qui est définie dans # l'objet 'imageTab' : qa.triggered.connect(self.imageTab.open_video) fileMenu.addAction(qa) ### Export CSV: qa = QAction(QIcon(VideoTracker.icone_dir+'/exportCSV.png'),\ 'Export CSV', self) qa.setStatusTip("Exporte les positions extraites de la vidéo dans un"+\ "fichier CSV.") qa.triggered.connect(self.ExportCSV) fileMenu.addAction(qa) ### Import CSV: qa = QAction(QIcon(VideoTracker.icone_dir+'/importCSV.png'),\ 'Import CSV', self) qa.setStatusTip("Importe les données depuis un fichier CSV forgé par VideoTracker.") qa.triggered.connect(self.ImportCSV) fileMenu.addAction(qa) ### Quit : qa = QAction(QIcon(VideoTracker.icone_dir+'/exit.png'),\ 'Quitter', self) qa.setShortcut('Ctrl+Q') qa.setStatusTip("Quitter l'application") qa.triggered.connect(self.close) fileMenu.addAction(qa) ###### Le menu 'Options' optionMenu = self.menubar.addMenu('&Options') ### Display info box windows: qa = QAction('Afficher boîtes info', self, checkable=True) text = 'Afficher ou non les boîtes de dialogue d\'information' qa.setStatusTip(text)# message in the status bar qa.setChecked(True) qa.triggered.connect(lambda e: self.set_flag("displayInfo",e)) optionMenu.addAction(qa) ### Verbose mode : qa = QAction('Mode verbeux', self, checkable=True) text = 'Afficher ou non des informations dans le shell Python' qa.setStatusTip(text) # message in the status bar qa.setChecked(True) qa.triggered.connect(lambda e: self.set_flag("debug", e)) optionMenu.addAction(qa) ### Clear trajectory plots before a new plot: qa = QAction('Effacement trajectoire avant tracé', self, checkable=True) text = 'Effacer automatiquement le tracé des onglets <Trajectoires> et ' text += '<X(t) et Y(t)> un nouveau tracé ?' qa.setStatusTip(text) # message in the status bar qa.setChecked(True) qa.triggered.connect(lambda e: self.set_flag("autoClearTraj", e) ) optionMenu.addAction(qa) ### draw/not draw the selected color area qa = QAction('Dessiner la sélection couleur de la cible', self, checkable=True) text = 'Dessine la zone sélectionnée pour la couleur de la cible' qa.setStatusTip(text) # message in the status bar qa.setChecked(True) qa.triggered.connect(lambda e: self.set_flag("drawTargetSelection", e)) optionMenu.addAction(qa)
class MainWindow(QMainWindow): opts = read_config() profiles = read_profiles() urls = [] def __init__(self, debug=False): super().__init__() self.debug = debug self.icon_paths() self.init_UI() def icon_paths(self): self.defaultIconTheme = QIcon.themeName() iconPaths = QIcon.themeSearchPaths() iconPaths.append(icon_path()) QIcon.setThemeSearchPaths(iconPaths) QIcon.setFallbackSearchPaths([icon_path("default")]) QIcon.setFallbackThemeName("default") #QIcon.setThemeName( "default" ) def init_UI(self): ## Set the theme self.set_stylesheet(self.opts["theme"]) self.profiles = read_profiles() self.mainWidget = MainWidget(self) self.statusBar() self.build_menu_bar() self.setCentralWidget(self.mainWidget) self.resize(WINDOW_WIDTH, WINDOW_HEIGHT) self.center_window() self.setWindowTitle("qYoutube-DL") self.show() def center_window(self): f = self.frameGeometry() center = QDesktopWidget().availableGeometry().center() f.moveCenter(center) self.move(f.topLeft()) def build_menu_bar(self): get_icon = Icons().get_icon ## Is this a system install? sysInstall = (os.path.expanduser('~') in sys.argv[0]) ######## Actions ## Save saveAction = QAction( QIcon(get_icon("document-save-symbolic", sysInstall)), "&Save Settings", self) saveAction.setShortcut("Ctrl+S") saveAction.setStatusTip("Save current settings") saveAction.triggered.connect(self.save_settings) ## Import playlist importAction = QAction( QIcon(get_icon("document-open-symbolic", sysInstall)), "&Import URLs", self) importAction.setShortcut("Ctrl+I") importAction.setStatusTip("Import a saved list of URLs") importAction.triggered.connect(self.import_urls) ## Export playlist exportAction = QAction( QIcon(get_icon("document-save-symbolic", sysInstall)), "&Export URLs", self) exportAction.setShortcut("Ctrl+E") exportAction.setStatusTip("Export URLs to a text file") exportAction.triggered.connect(self.export_urls) ## Exit exitAction = QAction( QIcon(get_icon("application-exit-symbolic", sysInstall)), "&Exit", self) exitAction.setShortcut("Ctrl+Q") exitAction.setStatusTip("Exit the application") exitAction.triggered.connect(qApp.quit) ## Go goAction = QAction(QIcon(get_icon("go-next-symbolic", sysInstall)), "Download URLs", self) goAction.setShortcut("Return") goAction.setStatusTip("Download current URL list") goAction.triggered.connect(self.mainWidget.start_download) ## Paste pasteAction = QAction( QIcon(get_icon("edit-paste-symbolic", sysInstall)), "&Paste", self) pasteAction.setShortcut("Ctrl+V") pasteAction.setStatusTip("Add URL from clipboard") pasteAction.triggered.connect(self.mainWidget.quick_add_item) ## Set destination setDestAction = QAction( QIcon(get_icon("document-open-symbolic", sysInstall)), "Set &Download directory", self) setDestAction.setShortcut("Ctrl+D") setDestAction.setStatusTip("Choose your download directory") setDestAction.triggered.connect(self.mainWidget.set_destination) ## Allow duplicates self.dupeAction = QAction("Allow duplicates", self) self.dupeAction.setStatusTip("Allow duplicate URLs in queue") self.dupeAction.setCheckable(True) if self.opts["duplicates"] == "true": self.dupeAction.setChecked(True) self.dupeAction.triggered.connect(self.check_dupe_box) ## New folder for playlists self.playlistFolderAction = QAction("New folder for playlists", self) self.playlistFolderAction.setStatusTip( "Create a new folder for every playlist downloaded") self.playlistFolderAction.setCheckable(True) if self.opts["playlistFolder"] == "true": self.playlistFolderAction.setChecked(True) self.playlistFolderAction.triggered.connect( self.check_playlist_dir_box) ## About action aboutAction = QAction( QIcon(get_icon("help-about-symbolic", sysInstall)), "&About", self) aboutAction.setStatusTip("Information about the program") aboutAction.triggered.connect(self.about) ## ====== Theme actions ## System default theme defaultThemeAction = QAction("Default", self) defaultThemeAction.setStatusTip("Set theme to system default") defaultThemeAction.triggered.connect(self.toggle_theme_default) ## Light theme lightThemeAction = QAction("Light theme", self) lightThemeAction.setStatusTip("Use a light theme") lightThemeAction.triggered.connect(self.toggle_theme_light) ## Dark theme darkThemeAction = QAction("Dark theme", self) darkThemeAction.setStatusTip("Use a dark theme") darkThemeAction.triggered.connect(self.toggle_theme_dark) ## Create the menubar menuBar = self.menuBar() ## Create file menu fileMenu = menuBar.addMenu("&File") fileMenu.addAction(saveAction) fileMenu.addAction(exportAction) fileMenu.addSeparator() fileMenu.addAction(importAction) fileMenu.addSeparator() fileMenu.addAction(goAction) fileMenu.addSeparator() fileMenu.addAction(exitAction) ## Edit Menu editMenu = menuBar.addMenu("&Edit") editMenu.addAction(pasteAction) ## Settins Menu settingsMenu = menuBar.addMenu("&Settings") themesMenu = settingsMenu.addMenu("Theme") settingsMenu.addSeparator() settingsMenu.addAction(setDestAction) settingsMenu.addSeparator() settingsMenu.addAction(self.dupeAction) settingsMenu.addAction(self.playlistFolderAction) ## Themes submenu themesMenu.addAction(defaultThemeAction) themesMenu.addAction(lightThemeAction) themesMenu.addAction(darkThemeAction) ## Help menu helpMenu = menuBar.addMenu("&Help") helpMenu.addAction(aboutAction) def import_urls(self): dDir = self.mainWidget.destEdit.text() filename, blank = QFileDialog.getOpenFileName(self, "Import URLs", dDir) if filename != "": try: fin = open(filename, "r") rawUrls = fin.readlines() fin.close() urls = [] for r in rawUrls: urls.append(r.strip()) self.load_urls(urls) self.statusBar().showMessage("URLs imported", 2000) except (OSError, PermissionError, FileNotFoundError): print("ERROR: Cannot read from '%s'! Unable to load URLs" % filename) def export_urls(self): dDir = self.mainWidget.destEdit.text() filename, blank = QFileDialog.getSaveFileName(self, "Export URLs", dDir) if filename != "": try: urls = self.mainWidget.get_urls() fout = open(filename, "w") fout.writelines(urls) fout.close() self.statusBar().showMessage("URLs exported", 2000) except (OSError, PermissionError, FileNotFoundError): print("ERROR: Cannot write to '%s'! Unable to export URLs" % filename) def load_urls(self, urls): self.mainWidget.load_urls(urls) def write_config(self): self.opts["downloadPath"] = self.mainWidget.destEdit.text() self.opts["duplicates"] = str(self.dupeAction.isChecked()).lower() boolStr = str(self.playlistFolderAction.isChecked()).lower() self.opts["playlistFolder"] = boolStr write_config(self.opts) def save_settings(self): self.write_config() self.statusBar().showMessage("Settings saved", 2000) def check_dupe_box(self): self.opts["duplicates"] = str(self.dupeAction.isChecked()).lower() self.save_settings() def check_playlist_dir_box(self): boolStr = str(self.playlistFolderAction.isChecked()).lower() self.opts["playlistFolder"] = boolStr self.save_settings() def about(self): aboutStr = """ qYoutube-DL is a basic PyQt5 frontend to Youtube-DL. Version: %s License: GPLv3 - https://www.gnu.org/licenses/gpl-3.0.txt Author: James Hendrie - [email protected] Git: https://github.com/jahendrie/qytdl """ % qytdl_version() msg = QMessageBox.about(self, "About qYoutube-DL", aboutStr) def toggle_theme_default(self): self.set_stylesheet() self.opts["theme"] = "default" self.write_config() def toggle_theme_light(self): self.set_stylesheet("light") self.opts["theme"] = "light" self.write_config() def toggle_theme_dark(self): self.set_stylesheet("dark") self.opts["theme"] = "dark" self.write_config() def set_stylesheet(self, ssStr=""): if ssStr == "dark" or ssStr == "light": ssFile = open(stylesheets_path("%s.qss" % ssStr), "r") self.setStyleSheet(ssFile.read()) ssFile.close() QIcon.setThemeName(ssStr) else: self.setStyleSheet("") QIcon.setThemeName(self.defaultIconTheme)