def sip_is_deleted(obj): """ :return: True if object no longer exists """ if obj is None or (isinstance(obj, sip.simplewrapper) and sip.isdeleted(obj)): return True return False
def get_themes(self): self.usage = {} def get_usage(): try: self.usage = json.loads( bz2.decompress( get_https_resource_securely(BASE_URL + '/usage.json.bz2'))) except Exception: import traceback traceback.print_exc() t = Thread(name='IconThemeUsage', target=get_usage) t.daemon = True t.start() try: self.themes = json.loads( bz2.decompress( get_https_resource_securely(BASE_URL + '/themes.json.bz2'))) except Exception: import traceback self.themes = traceback.format_exc() t.join() if not sip.isdeleted(self): self.themes_downloaded.emit()
def should_create_widget(widget: QtWidgets.QWidget = None) -> bool: """Returns whether or not the widget should be recreated.""" if widget is not None: return sip.isdeleted(widget) else: return True
def break_cycles(self): self.dev_tools_container.change_widget() for tab in self.tabs: if not sip.isdeleted(tab): self.stack.removeWidget(tab) tab.break_cycles() tab.deleteLater() self.tabs = []
def xxx(): if not sip.isdeleted(child) and \ child.inherits('QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget'): self._rwhvqt = child self._rwhvqt.installEventFilter(self) w = self._rwhvqt if isinstance(w, QQuickWidget): w.setClearColor(self.palette().color(QPalette.Window))
def extension_context_details(self): """Invoked when the user clicks "details" on the extension table's context menu.""" # Declarations app: QtWidgets.QApplication = QtWidgets.QApplication.instance() selected: typing.List[ QtWidgets.QTableWidgetItem] = self.extensions_table.selectedItems( ) # Individually show all selected extension displays for selection in selected: row: int = selection.row() item: QtWidgets.QTableWidgetItem = self.extensions_table.verticalHeaderItem( row) name: str = item.text() if name not in app.client.extensions: self.LOGGER.warning( f"Extension {name} doesn't exist in the internal extensions cache!" ) continue else: ext: dataclasses.Extension = app.client.extensions[name] # Stub instance check if isinstance(ext, dataclasses.ExtensionStub): return self.LOGGER.warning(f"Extension {name} isn't loaded!") try: ext.widget.show() except AttributeError: self.LOGGER.warning( f"Extension {name} hasn't implemented a widget display!") self.LOGGER.debug('Informing the user of what happened...') self.LOGGER.debug('Creating display...') m = QtWidgets.QMessageBox( QtWidgets.QMessageBox.Warning, 'Extension Display', f"{ext.DISPLAY_NAME} hasn't created a display for itself.", QtWidgets.QMessageBox.Ok, app.client) if ext.WEBSITE: self.LOGGER.debug( 'Adding a link to the extension\'s issue tracker') m.setInformativeText( f"You can report this to the author " f'<a href="{ext.WEBSITE.toDisplayString()}/issues/new">here</a>' ) self.LOGGER.debug('Displaying dialog...') m.exec() self.LOGGER.debug('Ensuring dialog is properly disposed of.') if not sip.isdeleted(m): m.deleteLater()
def about_to_show(self): if sip.isdeleted(self.clone): return cm = self.clone.menu() if cm is None: return before = list(QMenu.actions(cm)) cm.aboutToShow.emit() after = list(QMenu.actions(cm)) if before != after: self.clone_menu()
def set_editor_data(self, name, editor): if sip.isdeleted(editor): return editor.setText(name) ext_pos = name.rfind('.') slash_pos = name.rfind('/') if slash_pos == -1 and ext_pos > 0: editor.setSelection(0, ext_pos) elif ext_pos > -1 and slash_pos > -1 and ext_pos > slash_pos + 1: editor.setSelection(slash_pos+1, ext_pos - slash_pos - 1) else: editor.selectAll()
def set_editor_data(self, name, editor): if sip.isdeleted(editor): return editor.setText(name) ext_pos = name.rfind('.') slash_pos = name.rfind('/') if slash_pos == -1 and ext_pos > 0: editor.setSelection(0, ext_pos) elif ext_pos > -1 and slash_pos > -1 and ext_pos > slash_pos + 1: editor.setSelection(slash_pos + 1, ext_pos - slash_pos - 1) else: editor.selectAll()
def is_deleted(obj) -> bool: if qt.API == "pyside2": import shiboken2 return not shiboken2.isValid(obj) elif qt.API == "pyside6": import shiboken6 return not shiboken6.isValid(obj) elif qt.API == "pyqt5": try: from PyQt5 import sip except ImportError: import sip # type: ignore[import, no-redef] return sip.isdeleted(obj) else: try: from PyQt6 import sip except ImportError: import sip # type: ignore[import, no-redef] return sip.isdeleted(obj)
def render(self): self.current_tdir = os.path.join(self.tdir, unicode_type(self.first)) self.error = None try: os.mkdir(self.current_tdir) page_images(self.pdfpath, self.current_tdir, first=self.first, last=self.first + PAGES_PER_RENDER - 1) except Exception as e: if self.covers.count(): pass else: self.error = as_unicode(e) if not sip.isdeleted(self) and self.isVisible(): self.rendering_done.emit()
def open_pokemon(self): if self.data.datamon.edited: response = self.save_and_continue() if response == QtWidgets.QMessageBox.Cancel: return if self.child and not sip.isdeleted(self.child): self.child.close() self.child = list_view.ListView(util.pokemon_list()) self.modern = qtmodern.windows.ModernWindow(self.child) self.child.finish_function = self._open_pokemon self.modern.show()
def render(self): self.current_tdir = os.path.join(self.tdir, str(self.first)) self.error = None try: os.mkdir(self.current_tdir) page_images(self.pdfpath, self.current_tdir, first=self.first, last=self.first + PAGES_PER_RENDER - 1) except Exception as e: if self.covers.count(): pass else: self.error = as_unicode(e) if not sip.isdeleted(self) and self.isVisible(): self.rendering_done.emit()
def send_reply(rq, mime_type, data): if sip.isdeleted(rq): return # make the buf a child of rq so that it is automatically deleted when # rq is deleted buf = QBuffer(parent=rq) buf.open(QIODevice.OpenModeFlag.WriteOnly) # we have to copy data into buf as it will be garbage # collected by python buf.write(data) buf.seek(0) buf.close() rq.reply(mime_type.encode('ascii'), buf)
def itertabs(self): remove = [] for tabref in self.tabrefs: tab = tabref() if tab is not None: if not sip.isdeleted(tab) and tab.url() == DOWNLOADS_URL: yield tab else: remove.append(tabref) else: remove.append(tabref) for tabref in remove: self.tabrefs.remove(tabref)
def send_text_using_keys(self, text): if self.host_widget is not None and not sip.isdeleted( self.host_widget): self.host_widget.setFocus(Qt.OtherFocusReason) with QApplication.instance().key_filter.disable_filtering: for ch in text: key = getattr(Qt, f'Key_{ch.upper()}', Qt.Key_A) QApplication.sendEvent( self.host_widget, QKeyEvent(QKeyEvent.KeyPress, key, Qt.KeyboardModifiers(0), ch)) # Ensure key events are delivered before any other processing while QApplication.instance().processEvents(): pass
def finalize(shortcuts, custom_keys_map={}): # {{{ ''' Resolve conflicts and assign keys to every action in shortcuts, which must be a OrderedDict. User specified mappings of unique names to keys (as a list of strings) should be passed in in custom_keys_map. Return a mapping of unique names to resolved keys. Also sets the set_to_default member correctly for each shortcut. ''' seen, keys_map = {}, {} for unique_name, shortcut in iteritems(shortcuts): custom_keys = custom_keys_map.get(unique_name, None) if custom_keys is None: candidates = shortcut['default_keys'] shortcut['set_to_default'] = True else: candidates = custom_keys shortcut['set_to_default'] = False keys = [] for x in candidates: ks = QKeySequence(x, QKeySequence.SequenceFormat.PortableText) x = unicode_type( ks.toString(QKeySequence.SequenceFormat.PortableText)) if x in seen: if DEBUG: prints('Key %r for shortcut %s is already used by' ' %s, ignoring' % (x, shortcut['name'], seen[x]['name'])) keys_map[unique_name] = () continue seen[x] = shortcut keys.append(ks) keys = tuple(keys) keys_map[unique_name] = keys ac = shortcut['action'] if ac is None or sip.isdeleted(ac): if ac is not None and DEBUG: prints('Shortcut %r has a deleted action' % unique_name) continue ac.setShortcuts(list(keys)) return keys_map
def finalize(shortcuts, custom_keys_map={}): # {{{ ''' Resolve conflicts and assign keys to every action in shortcuts, which must be a OrderedDict. User specified mappings of unique names to keys (as a list of strings) should be passed in in custom_keys_map. Return a mapping of unique names to resolved keys. Also sets the set_to_default member correctly for each shortcut. ''' seen, keys_map = {}, {} for unique_name, shortcut in iteritems(shortcuts): custom_keys = custom_keys_map.get(unique_name, None) if custom_keys is None: candidates = shortcut['default_keys'] shortcut['set_to_default'] = True else: candidates = custom_keys shortcut['set_to_default'] = False keys = [] for x in candidates: ks = QKeySequence(x, QKeySequence.PortableText) x = unicode_type(ks.toString(QKeySequence.PortableText)) if x in seen: if DEBUG: prints('Key %r for shortcut %s is already used by' ' %s, ignoring'%(x, shortcut['name'], seen[x]['name'])) keys_map[unique_name] = () continue seen[x] = shortcut keys.append(ks) keys = tuple(keys) keys_map[unique_name] = keys ac = shortcut['action'] if ac is None or sip.isdeleted(ac): if ac is not None and DEBUG: prints('Shortcut %r has a deleted action' % unique_name) continue ac.setShortcuts(list(keys)) return keys_map
def closeEvent(self, event: QtGui.QCloseEvent): """An override for the QMainWindow's default closeEvent. This override is responsible for processing closing operations, like saving user settings.""" self.LOGGER.info('Performing closing operations...') self.LOGGER.info('Serializing settings...') try: d = json.dumps(self.settings.to_data()) except ValueError as e: self.LOGGER.warning('Settings could not be serialized!') self.LOGGER.warning(f'Reason: {e.__cause__}') else: if not self._settings_file.isOpen(): self._settings_file.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text | QtCore.QFile.Truncate) if self._settings_file.isWritable(): self.LOGGER.info('Saving settings...') self._settings_file.write(d.encode(encoding='UTF-8')) else: self.LOGGER.warning('Settings could not be saved!') self.LOGGER.warning( f'Reason: #{self._settings_file.error()} - {self._settings_file.errorString()}' ) finally: if self._settings_file.isOpen(): self._settings_file.close() if not sip.isdeleted(self.settings): self.settings.close() self.LOGGER.info('Done!')
def host_widget(self): ans = self._host_widget if ans is not None and not sip.isdeleted(ans): return ans
def createOrUpdateResultMenu(self, compareResult): if self.resultMenu and sip.isdeleted(self.resultMenu) == False: self.resultMenu.destroy() self.resultMenu = ResultWidget(compareResult)
def createOrUpdateSelectMenu(self): if self.selectMenu and sip.isdeleted(self.selectMenu) == False: self.selectMenu.destroy() self.selectMenu = SelectWidgetView()
def safe_delete(x): if not sip.isdeleted(x): sip.delete(x)
def initiate(self): """Initiates the OAuth flow.""" # Declarations app: QtWidgets.QApplication = QtWidgets.QApplication.instance() # Extension validation if 'twitch' not in app.client.extensions: # This shouldn't happen self.LOGGER.warning("The twitch extension isn't loaded!") self.LOGGER.debug( 'If this converter was reimplemented by another extension, the author should consider ' 'reviewing it.') self.LOGGER.debug('Creating informative dialog...') _m = QtWidgets.QMessageBox( QtWidgets.QMessageBox.Warning, 'Token Generator', 'The twitch extension must be loaded before you can generate a new token.', QtWidgets.QMessageBox.Ok, app.client.settings) self.LOGGER.debug('Displaying dialog...') _m.exec() self.LOGGER.debug('Ensuring dialog is deleted properly...') if not sip.isdeleted(_m): _m.deleteLater() return # Get the client ID try: self.LOGGER.debug('Getting client id from the Twitch extension...') client_id = app.client.settings['extensions']['twitch'][ 'client_id'].value except KeyError: self.LOGGER.warning( "The Twitch extension's settings are invalid! Did someone modify them?" ) client_id = None else: if not client_id: self.LOGGER.warning( "Cannot locate the Twitch extension's client id!") client_id = None # Client id validation if client_id is None: self.LOGGER.warning('There is no client id!') self.LOGGER.debug('Creating informative dialog...') _m = QtWidgets.QMessageBox( QtWidgets.QMessageBox.Critical, 'Token Generator', 'A token cannot be generated without a client id!', QtWidgets.QMessageBox.Ok, app.client.settings) self.LOGGER.debug('Displaying dialog...') _m.exec() self.LOGGER.debug('Ensuring dialog is deleted properly...') if not sip.isdeleted(_m): _m.deleteLater() return # Ensure the browser is visible if self.stacked.currentWidget() != self.browser_container: self.LOGGER.debug('Displaying QWebEngineView...') self.stacked.setCurrentWidget(self.browser_container) if self.browser.isHidden(): self.browser.show() if self.label.isVisible(): self.label.hide() # Clear any existing state self.LOGGER.debug('Clearing existing state, if one existed...') self._state = None # Generate a new state self.LOGGER.debug('Generating a new state...') self._state = secrets.token_urlsafe(256) # Gather the scopes s = [] for row in range(self.scopes.count()): i = self.scopes.item(row) if i.checkState() == QtCore.Qt.Checked: s.append(i.text()) # Clone the endpoint u = QtCore.QUrl(self.ENDPOINT) # Declare & assign a query to the clone p = QtCore.QUrlQuery() p.addQueryItem('force_verify', 'true') # Since users may want to switch accounts p.addQueryItem('state', self._state) p.addQueryItem('redirect_uri', 'http://localhost') p.addQueryItem('response_type', 'token') p.addQueryItem('client_id', str(client_id)) p.addQueryItem('scope', '+'.join(s)) u.setQuery(p) # Set the browser self.browser.load(u) self.browser.show() self.browser.setHidden(False) self.browser_container.show() self.browser_container.setHidden(False)
def eventFilter(self, obj, e): 'Redirect key presses from the popup to the widget' widget = self.completer_widget() if widget is None or sip.isdeleted(widget): return False etype = e.type() if obj is not self: return QObject.eventFilter(self, obj, e) # self.debug_event(e) if etype == e.KeyPress: try: key = e.key() except AttributeError: return QObject.eventFilter(self, obj, e) if key == Qt.Key_Escape: self.hide() e.accept() return True if key == Qt.Key_F4 and e.modifiers() & Qt.AltModifier: self.hide() e.accept() return True if key in (Qt.Key_Enter, Qt.Key_Return): # We handle this explicitly because on OS X activated() is # not emitted on pressing Enter. idx = self.currentIndex() if idx.isValid(): self.item_chosen(idx) self.hide() e.accept() return True if key == Qt.Key_Tab: idx = self.currentIndex() if idx.isValid(): self.item_chosen(idx) self.hide() elif self.model().rowCount() > 0: self.next_match() e.accept() return True if key in (Qt.Key_PageUp, Qt.Key_PageDown): # Let the list view handle these keys return False if key in (Qt.Key_Up, Qt.Key_Down): self.next_match(previous=key == Qt.Key_Up) e.accept() return True # Send to widget widget.eat_focus_out = False widget.keyPressEvent(e) widget.eat_focus_out = True if not widget.hasFocus(): # Widget lost focus hide the popup self.hide() if e.isAccepted(): return True elif isosx and etype == e.InputMethodQuery and e.queries() == ( Qt.ImHints | Qt.ImEnabled) and self.isVisible(): # In Qt 5 the Esc key causes this event and the line edit does not # handle it, which causes the parent dialog to be closed # See https://bugreports.qt-project.org/browse/QTBUG-41806 e.accept() return True elif etype == e.MouseButtonPress and hasattr( e, 'globalPos') and not self.rect().contains( self.mapFromGlobal(e.globalPos())): # A click outside the popup, close it if isinstance(widget, QComboBox): # This workaround is needed to ensure clicking on the drop down # arrow of the combobox closes the popup opt = QStyleOptionComboBox() widget.initStyleOption(opt) sc = widget.style().hitTestComplexControl( QStyle.CC_ComboBox, opt, widget.mapFromGlobal(e.globalPos()), widget) if sc == QStyle.SC_ComboBoxArrow: QTimer.singleShot(0, self.hide) e.accept() return True self.hide() e.accept() return True elif etype in (e.InputMethod, e.ShortcutOverride): QApplication.sendEvent(widget, e) return False
def do_trigger(self, checked=False): if not sip.isdeleted(self.clone): self.clone.trigger()
def rewrap_button(w): if not sip.isdeleted(w): w.setText(wrap_button_text(w.defaultAction().text()))
def isQObjectAlive(obj): return not sip.isdeleted(obj)
def eventFilter(self, obj, e): 'Redirect key presses from the popup to the widget' widget = self.completer_widget() if widget is None or sip.isdeleted(widget): return False etype = e.type() if obj is not self: return QObject.eventFilter(self, obj, e) # self.debug_event(e) if etype == e.KeyPress: try: key = e.key() except AttributeError: return QObject.eventFilter(self, obj, e) if key == Qt.Key_Escape: self.hide() e.accept() return True if key == Qt.Key_F4 and e.modifiers() & Qt.AltModifier: self.hide() e.accept() return True if key in (Qt.Key_Enter, Qt.Key_Return): # We handle this explicitly because on OS X activated() is # not emitted on pressing Enter. idx = self.currentIndex() if idx.isValid(): self.item_chosen(idx) self.hide() e.accept() return True if key == Qt.Key_Tab: idx = self.currentIndex() if idx.isValid(): self.item_chosen(idx) self.hide() elif self.model().rowCount() > 0: self.next_match() e.accept() return True if key in (Qt.Key_PageUp, Qt.Key_PageDown): # Let the list view handle these keys return False if key in (Qt.Key_Up, Qt.Key_Down): self.next_match(previous=key == Qt.Key_Up) e.accept() return True # Send to widget widget.eat_focus_out = False widget.keyPressEvent(e) widget.eat_focus_out = True if not widget.hasFocus(): # Widget lost focus hide the popup self.hide() if e.isAccepted(): return True elif isosx and etype == e.InputMethodQuery and e.queries() == (Qt.ImHints | Qt.ImEnabled) and self.isVisible(): # In Qt 5 the Esc key causes this event and the line edit does not # handle it, which causes the parent dialog to be closed # See https://bugreports.qt-project.org/browse/QTBUG-41806 e.accept() return True elif etype == e.MouseButtonPress and hasattr(e, 'globalPos') and not self.rect().contains(self.mapFromGlobal(e.globalPos())): # A click outside the popup, close it if isinstance(widget, QComboBox): # This workaround is needed to ensure clicking on the drop down # arrow of the combobox closes the popup opt = QStyleOptionComboBox() widget.initStyleOption(opt) sc = widget.style().hitTestComplexControl(QStyle.CC_ComboBox, opt, widget.mapFromGlobal(e.globalPos()), widget) if sc == QStyle.SC_ComboBoxArrow: QTimer.singleShot(0, self.hide) e.accept() return True self.hide() e.accept() return True elif etype in (e.InputMethod, e.ShortcutOverride): QApplication.sendEvent(widget, e) return False
def rewrap_button(w): if not sip.isdeleted(w) and w.defaultAction() is not None: w.setText(wrap_button_text(w.defaultAction().text()))
def clear_dialog(self): if self.dialog is not None: if not sip.isdeleted(self.dialog): self.dialog.accept() self.dialog = None
def update_state(self, *args): if sip.isdeleted(self) or sip.isdeleted(self.page_action): return if self.isCheckable(): self.setChecked(self.page_action.isChecked()) self.setEnabled(self.page_action.isEnabled())
def url_watcher(self, url: QtCore.QUrl): """Watches the QWebEngineView for url changes.""" if url.host() not in [ 'twitch.tv', 'localhost', self.ENDPOINT.host(), 'passport.twitch.tv' ] and url.host() != '': self.LOGGER.warning( f'Redirected to an unsupported host! ({url.host()})') self.LOGGER.debug('Creating informative dialog...') _m = QtWidgets.QMessageBox( QtWidgets.QMessageBox.Critical, 'Token Generator', f'You were redirected to an unsupported host. ({url.host()})', QtWidgets.QMessageBox.Ok, self) self.LOGGER.debug('Displaying dialog...') self.hide() _m.exec() self.LOGGER.debug('Ensuring dialog is deleted properly...') if not sip.isdeleted(_m): _m.deleteLater() self.browser.setUrl(QtCore.QUrl('about:blank')) return self.reject() if url.hasFragment(): query = QtCore.QUrlQuery(url.fragment()) else: query = QtCore.QUrlQuery(url.query()) if not query.hasQueryItem('state') and url.path() != '/two_factor/new': self.LOGGER.warning('No state sent!') self.LOGGER.debug('Creating informative dialog...') _m = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Token Generator', "The state parameter wasn't passed.", QtWidgets.QMessageBox.Ok, self) self.LOGGER.debug('Displaying dialog...') self.hide() _m.exec() self.LOGGER.debug('Ensuring dialog is deleted properly...') if not sip.isdeleted(_m): _m.deleteLater() self.browser.setUrl(QtCore.QUrl('about:blank')) return self.reject() if query.hasQueryItem( 'state') and self._state != query.queryItemValue('state'): self.LOGGER.warning('Sent state is not our state!') self.LOGGER.debug('Creating informative dialog...') _m = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Token Generator', 'Sent state is not our state.', QtWidgets.QMessageBox.Ok, self) self.LOGGER.debug('Displaying dialog...') _m.exec() self.hide() self.LOGGER.debug('Ensuring dialog is deleted properly...') if not sip.isdeleted(_m): _m.deleteLater() self.browser.setUrl(QtCore.QUrl('about:blank')) return self.reject() if query.hasQueryItem('access_token'): # Declarations app: QtWidgets.QApplication = QtWidgets.QApplication.instance() client_id = app.client.settings['extensions']['twitch'][ 'client_id'].value scopes: typing.List[Scopes] = [ Scopes(s) for s in parse.unquote(query.queryItemValue( 'scope')).split('+') ] self.GENERATED.emit( token.Token(client_id, query.queryItemValue('access_token'), scopes)) self.accept()
def callback(metadata, x): if not sip.isdeleted(dialog) and not dialog.dialog_closed: dialog.cover_downloaded.emit(metadata, x)
def remove_c(self,x): # self.fo.removeWidget(x) sip.delete(x) print(sip.isdeleted(x))