diff --git a/qt/aqt/__init__.py b/qt/aqt/__init__.py index b7183af15..0eb353fdf 100644 --- a/qt/aqt/__init__.py +++ b/qt/aqt/__init__.py @@ -255,7 +255,7 @@ class AnkiApp(QApplication): # previous instance died QLocalServer.removeServer(self.KEY) self._srv = QLocalServer(self) - self._srv.newConnection.connect(self.onRecv) + qconnect(self._srv.newConnection, self.onRecv) self._srv.listen(self.KEY) return False diff --git a/qt/aqt/about.py b/qt/aqt/about.py index f2d89b345..7c3412720 100644 --- a/qt/aqt/about.py +++ b/qt/aqt/about.py @@ -86,7 +86,7 @@ def show(mw): tooltip(_("Copied to clipboard"), parent=dialog) btn = QPushButton(_("Copy Debug Info")) - btn.clicked.connect(onCopy) + qconnect(btn.clicked, onCopy) abt.buttonBox.addButton(btn, QDialogButtonBox.ActionRole) abt.buttonBox.button(QDialogButtonBox.Ok).setFocus() diff --git a/qt/aqt/addcards.py b/qt/aqt/addcards.py index 8b4da53a2..9f95736b9 100644 --- a/qt/aqt/addcards.py +++ b/qt/aqt/addcards.py @@ -65,7 +65,7 @@ class AddCards(QDialog): ar = QDialogButtonBox.ActionRole # add self.addButton = bb.addButton(_("Add"), ar) - self.addButton.clicked.connect(self.addCards) + qconnect(self.addButton.clicked, self.addCards) self.addButton.setShortcut(QKeySequence("Ctrl+Return")) self.addButton.setToolTip(shortcut(_("Add (shortcut: ctrl+enter)"))) # close @@ -84,7 +84,7 @@ class AddCards(QDialog): sc = "Ctrl+H" b.setShortcut(QKeySequence(sc)) b.setToolTip(_("Shortcut: %s") % shortcut(sc)) - b.clicked.connect(self.onHistory) + qconnect(b.clicked, self.onHistory) b.setEnabled(False) self.historyButton = b diff --git a/qt/aqt/addons.py b/qt/aqt/addons.py index c0ae496b6..489405542 100644 --- a/qt/aqt/addons.py +++ b/qt/aqt/addons.py @@ -175,7 +175,7 @@ class AddonManager: self.mw = mw self.dirty = False f = self.mw.form - f.actionAdd_ons.triggered.connect(self.onAddonsDialog) + qconnect(f.actionAdd_ons.triggered, self.onAddonsDialog) sys.path.insert(0, self.addonsFolder()) # in new code, you may want all_addon_meta() instead @@ -699,16 +699,16 @@ class AddonsDialog(QDialog): f = self.form = aqt.forms.addons.Ui_Dialog() f.setupUi(self) - f.getAddons.clicked.connect(self.onGetAddons) - f.installFromFile.clicked.connect(self.onInstallFiles) - f.checkForUpdates.clicked.connect(self.check_for_updates) - f.toggleEnabled.clicked.connect(self.onToggleEnabled) - f.viewPage.clicked.connect(self.onViewPage) - f.viewFiles.clicked.connect(self.onViewFiles) - f.delete_2.clicked.connect(self.onDelete) - f.config.clicked.connect(self.onConfig) - self.form.addonList.itemDoubleClicked.connect(self.onConfig) - self.form.addonList.currentRowChanged.connect(self._onAddonItemSelected) + qconnect(f.getAddons.clicked, self.onGetAddons) + qconnect(f.installFromFile.clicked, self.onInstallFiles) + qconnect(f.checkForUpdates.clicked, self.check_for_updates) + qconnect(f.toggleEnabled.clicked, self.onToggleEnabled) + qconnect(f.viewPage.clicked, self.onViewPage) + qconnect(f.viewFiles.clicked, self.onViewFiles) + qconnect(f.delete_2.clicked, self.onDelete) + qconnect(f.config.clicked, self.onConfig) + qconnect(self.form.addonList.itemDoubleClicked, self.onConfig) + qconnect(self.form.addonList.currentRowChanged, self._onAddonItemSelected) self.setAcceptDrops(True) self.redrawAddons() restoreGeom(self, "addons") @@ -916,7 +916,7 @@ class GetAddons(QDialog): b = self.form.buttonBox.addButton( _("Browse Add-ons"), QDialogButtonBox.ActionRole ) - b.clicked.connect(self.onBrowse) + qconnect(b.clicked, self.onBrowse) restoreGeom(self, "getaddons", adjustSize=True) self.exec_() saveGeom(self, "getaddons") @@ -1057,7 +1057,7 @@ class DownloaderInstaller(QObject): QObject.__init__(self, parent) self.mgr = mgr self.client = client - self.progressSignal.connect(self._progress_callback) # type: ignore + qconnect(self.progressSignal, self._progress_callback) def bg_thread_progress(up, down) -> None: self.progressSignal.emit(up, down) # type: ignore @@ -1283,7 +1283,7 @@ class ConfigEditor(QDialog): self.form = aqt.forms.addonconf.Ui_Dialog() self.form.setupUi(self) restore = self.form.buttonBox.button(QDialogButtonBox.RestoreDefaults) - restore.clicked.connect(self.onRestoreDefaults) + qconnect(restore.clicked, self.onRestoreDefaults) self.setupFonts() self.updateHelp() self.updateText(self.conf) diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py index f52d5cd26..4f899b5aa 100644 --- a/qt/aqt/browser.py +++ b/qt/aqt/browser.py @@ -608,53 +608,53 @@ class Browser(QMainWindow): # pylint: disable=unnecessary-lambda # actions f = self.form - f.previewButton.clicked.connect(self.onTogglePreview) + qconnect(f.previewButton.clicked, self.onTogglePreview) f.previewButton.setToolTip( _("Preview Selected Card (%s)") % shortcut("Ctrl+Shift+P") ) f.previewButton.setShortcut("Ctrl+Shift+P") - f.filter.clicked.connect(self.onFilterButton) + qconnect(f.filter.clicked, self.onFilterButton) # edit - f.actionUndo.triggered.connect(self.mw.onUndo) - f.actionInvertSelection.triggered.connect(self.invertSelection) - f.actionSelectNotes.triggered.connect(self.selectNotes) + qconnect(f.actionUndo.triggered, self.mw.onUndo) + qconnect(f.actionInvertSelection.triggered, self.invertSelection) + qconnect(f.actionSelectNotes.triggered, self.selectNotes) if not isMac: f.actionClose.setVisible(False) # notes - f.actionAdd.triggered.connect(self.mw.onAddCard) - f.actionAdd_Tags.triggered.connect(lambda: self.addTags()) - f.actionRemove_Tags.triggered.connect(lambda: self.deleteTags()) - f.actionClear_Unused_Tags.triggered.connect(self.clearUnusedTags) - f.actionToggle_Mark.triggered.connect(lambda: self.onMark()) - f.actionChangeModel.triggered.connect(self.onChangeModel) - f.actionFindDuplicates.triggered.connect(self.onFindDupes) - f.actionFindReplace.triggered.connect(self.onFindReplace) - f.actionManage_Note_Types.triggered.connect(self.mw.onNoteTypes) - f.actionDelete.triggered.connect(self.deleteNotes) + qconnect(f.actionAdd.triggered, self.mw.onAddCard) + qconnect(f.actionAdd_Tags.triggered, lambda: self.addTags()) + qconnect(f.actionRemove_Tags.triggered, lambda: self.deleteTags()) + qconnect(f.actionClear_Unused_Tags.triggered, self.clearUnusedTags) + qconnect(f.actionToggle_Mark.triggered, lambda: self.onMark()) + qconnect(f.actionChangeModel.triggered, self.onChangeModel) + qconnect(f.actionFindDuplicates.triggered, self.onFindDupes) + qconnect(f.actionFindReplace.triggered, self.onFindReplace) + qconnect(f.actionManage_Note_Types.triggered, self.mw.onNoteTypes) + qconnect(f.actionDelete.triggered, self.deleteNotes) # cards - f.actionChange_Deck.triggered.connect(self.setDeck) - f.action_Info.triggered.connect(self.showCardInfo) - f.actionReposition.triggered.connect(self.reposition) - f.actionReschedule.triggered.connect(self.reschedule) - f.actionToggle_Suspend.triggered.connect(self.onSuspend) - f.actionRed_Flag.triggered.connect(lambda: self.onSetFlag(1)) - f.actionOrange_Flag.triggered.connect(lambda: self.onSetFlag(2)) - f.actionGreen_Flag.triggered.connect(lambda: self.onSetFlag(3)) - f.actionBlue_Flag.triggered.connect(lambda: self.onSetFlag(4)) - f.actionExport.triggered.connect(lambda: self._on_export_notes()) + qconnect(f.actionChange_Deck.triggered, self.setDeck) + qconnect(f.action_Info.triggered, self.showCardInfo) + qconnect(f.actionReposition.triggered, self.reposition) + qconnect(f.actionReschedule.triggered, self.reschedule) + qconnect(f.actionToggle_Suspend.triggered, self.onSuspend) + qconnect(f.actionRed_Flag.triggered, lambda: self.onSetFlag(1)) + qconnect(f.actionOrange_Flag.triggered, lambda: self.onSetFlag(2)) + qconnect(f.actionGreen_Flag.triggered, lambda: self.onSetFlag(3)) + qconnect(f.actionBlue_Flag.triggered, lambda: self.onSetFlag(4)) + qconnect(f.actionExport.triggered, lambda: self._on_export_notes()) # jumps - f.actionPreviousCard.triggered.connect(self.onPreviousCard) - f.actionNextCard.triggered.connect(self.onNextCard) - f.actionFirstCard.triggered.connect(self.onFirstCard) - f.actionLastCard.triggered.connect(self.onLastCard) - f.actionFind.triggered.connect(self.onFind) - f.actionNote.triggered.connect(self.onNote) - f.actionTags.triggered.connect(self.onFilterButton) - f.actionSidebar.triggered.connect(self.focusSidebar) - f.actionCardList.triggered.connect(self.onCardList) + qconnect(f.actionPreviousCard.triggered, self.onPreviousCard) + qconnect(f.actionNextCard.triggered, self.onNextCard) + qconnect(f.actionFirstCard.triggered, self.onFirstCard) + qconnect(f.actionLastCard.triggered, self.onLastCard) + qconnect(f.actionFind.triggered, self.onFind) + qconnect(f.actionNote.triggered, self.onNote) + qconnect(f.actionTags.triggered, self.onFilterButton) + qconnect(f.actionSidebar.triggered, self.focusSidebar) + qconnect(f.actionCardList.triggered, self.onCardList) # help - f.actionGuide.triggered.connect(self.onHelp) + qconnect(f.actionGuide.triggered, self.onHelp) # keyboard shortcut for shift+home/end self.pgUpCut = QShortcut(QKeySequence("Shift+Home"), self) qconnect(self.pgUpCut.activated, self.onFirstCard) @@ -666,7 +666,7 @@ class Browser(QMainWindow): # context menu self.form.tableView.setContextMenuPolicy(Qt.CustomContextMenu) - self.form.tableView.customContextMenuRequested.connect(self.onContextMenu) + qconnect(self.form.tableView.customContextMenuRequested, self.onContextMenu) def onContextMenu(self, _point) -> None: m = QMenu() @@ -750,8 +750,8 @@ class Browser(QMainWindow): ###################################################################### def setupSearch(self): - self.form.searchButton.clicked.connect(self.onSearchActivated) - self.form.searchEdit.lineEdit().returnPressed.connect(self.onSearchActivated) + qconnect(self.form.searchButton.clicked, self.onSearchActivated) + qconnect(self.form.searchEdit.lineEdit().returnPressed, self.onSearchActivated) self.form.searchEdit.setCompleter(None) self._searchPrompt = _("") self.form.searchEdit.addItems( @@ -837,7 +837,9 @@ class Browser(QMainWindow): self.form.tableView.setModel(self.model) self.form.tableView.selectionModel() self.form.tableView.setItemDelegate(StatusDelegate(self, self.model)) - self.form.tableView.selectionModel().selectionChanged.connect(self.onRowChanged) + qconnect( + self.form.tableView.selectionModel().selectionChanged, self.onRowChanged + ) self.form.tableView.setWordWrap(False) if not theme_manager.night_mode: self.form.tableView.setStyleSheet( @@ -912,10 +914,10 @@ QTableView {{ gridline-color: {grid} }} hh.setSectionsMovable(True) self.setColumnSizes() hh.setContextMenuPolicy(Qt.CustomContextMenu) - hh.customContextMenuRequested.connect(self.onHeaderContext) + qconnect(hh.customContextMenuRequested, self.onHeaderContext) self.setSortIndicator() - hh.sortIndicatorChanged.connect(self.onSortChanged) - hh.sectionMoved.connect(self.onColumnMoved) + qconnect(hh.sortIndicatorChanged, self.onSortChanged) + qconnect(hh.sectionMoved, self.onColumnMoved) def onSortChanged(self, idx, ord): ord = bool(ord) @@ -969,7 +971,7 @@ QTableView {{ gridline-color: {grid} }} a = m.addAction(name) a.setCheckable(True) a.setChecked(type in self.model.activeCols) - a.toggled.connect(lambda b, t=type: self.toggleField(t)) + qconnect(a.toggled, lambda b, t=type: self.toggleField(t)) gui_hooks.browser_header_will_show_context_menu(self, m) m.exec_(gpos) @@ -1015,8 +1017,8 @@ QTableView {{ gridline-color: {grid} }} class SidebarTreeView(QTreeView): def __init__(self): super().__init__() - self.expanded.connect(self.onExpansion) - self.collapsed.connect(self.onCollapse) + qconnect(self.expanded, self.onExpansion) + qconnect(self.collapsed, self.onCollapse) def onClickCurrent(self) -> None: idx = self.currentIndex() @@ -1058,13 +1060,13 @@ QTableView {{ gridline-color: {grid} }} self.sidebarTree.setUniformRowHeights(True) self.sidebarTree.setHeaderHidden(True) self.sidebarTree.setIndentation(15) - self.sidebarTree.expanded.connect(self.onSidebarItemExpanded) # type: ignore + qconnect(self.sidebarTree.expanded, self.onSidebarItemExpanded) dw.setWidget(self.sidebarTree) # match window background color bgcolor = QPalette().window().color().name() self.sidebarTree.setStyleSheet("QTreeView { background: '%s'; }" % bgcolor) self.sidebarDockWidget.setFloating(False) - self.sidebarDockWidget.visibilityChanged.connect(self.onSidebarVisChanged) # type: ignore + qconnect(self.sidebarDockWidget.visibilityChanged, self.onSidebarVisChanged) self.sidebarDockWidget.setTitleBarWidget(QWidget()) self.addDockWidget(Qt.LeftDockWidgetArea, dw) @@ -1428,7 +1430,7 @@ QTableView {{ gridline-color: {grid} }} w.stdHtml(info + "

" + reps, context=card_info_dialog) bb = QDialogButtonBox(QDialogButtonBox.Close) l.addWidget(bb) - bb.rejected.connect(card_info_dialog.reject) + qconnect(bb.rejected, card_info_dialog.reject) card_info_dialog.setLayout(l) card_info_dialog.setWindowModality(Qt.WindowModal) card_info_dialog.resize(500, 400) @@ -1932,7 +1934,7 @@ update cards set usn=?, mod=?, did=? where id in """ frm.setupUi(d) d.setWindowModality(Qt.WindowModal) frm.field.addItems([_("All Fields")] + fields) - frm.buttonBox.helpRequested.connect(self.onFindReplaceHelp) + qconnect(frm.buttonBox.helpRequested, self.onFindReplaceHelp) restoreGeom(d, "findreplace") r = d.exec_() saveGeom(d, "findreplace") @@ -2000,7 +2002,7 @@ update cards set usn=?, mod=?, did=? where id in """ def onFin(code): saveGeom(d, "findDupes") - d.finished.connect(onFin) + qconnect(d.finished, onFin) def onClick(): field = fields[frm.fields.currentIndex()] @@ -2009,7 +2011,7 @@ update cards set usn=?, mod=?, did=? where id in """ ) search = frm.buttonBox.addButton(_("Search"), QDialogButtonBox.ActionRole) - search.clicked.connect(onClick) + qconnect(search.clicked, onClick) d.show() def duplicatesReport(self, web, fname, search, frm, web_context): @@ -2019,7 +2021,7 @@ update cards set usn=?, mod=?, did=? where id in """ self._dupesButton = b = frm.buttonBox.addButton( _("Tag Duplicates"), QDialogButtonBox.ActionRole ) - b.clicked.connect(lambda: self._onTagDupes(res)) + qconnect(b.clicked, lambda: self._onTagDupes(res)) t = "" groups = len(res) notes = sum(len(r[1]) for r in res) @@ -2179,7 +2181,7 @@ class ChangeModel(QDialog): self.browser.mw, self.form.modelChooserWidget, label=False ) self.modelChooser.models.setFocus() - self.form.buttonBox.helpRequested.connect(self.onHelp) + qconnect(self.form.buttonBox.helpRequested, self.onHelp) self.modelChanged(self.browser.mw.col.models.current()) self.pauseUpdate = False @@ -2215,8 +2217,9 @@ class ChangeModel(QDialog): idx = min(i, len(targets) - 1) cb.setCurrentIndex(idx) indices[cb] = idx - cb.currentIndexChanged.connect( - lambda i, cb=cb, key=key: self.onComboChanged(i, cb, key) + qconnect( + cb.currentIndexChanged, + lambda i, cb=cb, key=key: self.onComboChanged(i, cb, key), ) combos.append(cb) l.addWidget(cb, i, 1) diff --git a/qt/aqt/clayout.py b/qt/aqt/clayout.py index 22ca8f172..6f6b74bab 100644 --- a/qt/aqt/clayout.py +++ b/qt/aqt/clayout.py @@ -106,8 +106,8 @@ class CardLayout(QDialog): self.topAreaForm = aqt.forms.clayout_top.Ui_Form() self.topAreaForm.setupUi(self.topArea) self.topAreaForm.templateOptions.setText(_("Options") + " " + downArrow()) - self.topAreaForm.templateOptions.clicked.connect(self.onMore) - self.topAreaForm.templatesBox.currentIndexChanged.connect(self.onCardSelected) + qconnect(self.topAreaForm.templateOptions.clicked, self.onMore) + qconnect(self.topAreaForm.templatesBox.currentIndexChanged, self.onCardSelected) def updateTopArea(self): cnt = self.mw.col.models.useCount(self.model) @@ -184,13 +184,14 @@ class CardLayout(QDialog): tform.tlayout2.setContentsMargins(0, 11, 0, 0) tform.tlayout3.setContentsMargins(0, 11, 0, 0) tform.groupBox_3.setTitle(_("Styling (shared between cards)")) - tform.front.textChanged.connect(self.saveCard) - tform.css.textChanged.connect(self.saveCard) - tform.back.textChanged.connect(self.saveCard) + qconnect(tform.front.textChanged, self.saveCard) + qconnect(tform.css.textChanged, self.saveCard) + qconnect(tform.back.textChanged, self.saveCard) l.addWidget(left, 5) # preview area right = QWidget() - pform = self.pform = aqt.forms.preview.Ui_Form() + self.pform: Any = aqt.forms.preview.Ui_Form() + pform = self.pform pform.setupUi(right) if self.style().objectName() == "gtk+": # gtk+ requires margins in inner layout @@ -269,22 +270,22 @@ Please create a new card type first.""" help = QPushButton(_("Help")) help.setAutoDefault(False) l.addWidget(help) - help.clicked.connect(self.onHelp) + qconnect(help.clicked, self.onHelp) l.addStretch() addField = QPushButton(_("Add Field")) addField.setAutoDefault(False) l.addWidget(addField) - addField.clicked.connect(self.onAddField) + qconnect(addField.clicked, self.onAddField) if not self._isCloze(): flip = QPushButton(_("Flip")) flip.setAutoDefault(False) l.addWidget(flip) - flip.clicked.connect(self.onFlip) + qconnect(flip.clicked, self.onFlip) l.addStretch() close = QPushButton(_("Close")) close.setAutoDefault(False) l.addWidget(close) - close.clicked.connect(self.accept) + qconnect(close.clicked, self.accept) # Cards ########################################################################## @@ -471,16 +472,16 @@ adjust the template manually to switch the question and answer.""" if not self._isCloze(): a = m.addAction(_("Add Card Type...")) - a.triggered.connect(self.onAddCard) + qconnect(a.triggered, self.onAddCard) a = m.addAction(_("Remove Card Type...")) - a.triggered.connect(self.onRemove) + qconnect(a.triggered, self.onRemove) a = m.addAction(_("Rename Card Type...")) - a.triggered.connect(self.onRename) + qconnect(a.triggered, self.onRename) a = m.addAction(_("Reposition Card Type...")) - a.triggered.connect(self.onReorder) + qconnect(a.triggered, self.onReorder) m.addSeparator() @@ -490,10 +491,10 @@ adjust the template manually to switch the question and answer.""" else: s = _(" (off)") a = m.addAction(_("Deck Override...") + s) - a.triggered.connect(self.onTargetDeck) + qconnect(a.triggered, self.onTargetDeck) a = m.addAction(_("Browser Appearance...")) - a.triggered.connect(self.onBrowserDisplay) + qconnect(a.triggered, self.onBrowserDisplay) m.exec_(self.topAreaForm.templateOptions.mapToGlobal(QPoint(0, 0))) @@ -508,7 +509,7 @@ adjust the template manually to switch the question and answer.""" f.overrideFont.setChecked(True) f.font.setCurrentFont(QFont(t.get("bfont", "Arial"))) f.fontSize.setValue(t.get("bsize", 12)) - f.buttonBox.accepted.connect(lambda: self.onBrowserDisplayOk(f)) + qconnect(f.buttonBox.accepted, lambda: self.onBrowserDisplayOk(f)) d.exec_() def onBrowserDisplayOk(self, f): @@ -547,7 +548,7 @@ Enter deck to place new %s cards in, or leave blank:""" te.setText(self.col.decks.get(t["did"])["name"]) te.selectAll() bb = QDialogButtonBox(QDialogButtonBox.Close) - bb.rejected.connect(d.close) + qconnect(bb.rejected, d.close) l.addWidget(bb) d.setLayout(l) d.exec_() diff --git a/qt/aqt/customstudy.py b/qt/aqt/customstudy.py index 5353b295a..a32a0f87b 100644 --- a/qt/aqt/customstudy.py +++ b/qt/aqt/customstudy.py @@ -37,12 +37,12 @@ class CustomStudy(QDialog): def setupSignals(self): f = self.form - f.radioNew.clicked.connect(lambda: self.onRadioChange(RADIO_NEW)) - f.radioRev.clicked.connect(lambda: self.onRadioChange(RADIO_REV)) - f.radioForgot.clicked.connect(lambda: self.onRadioChange(RADIO_FORGOT)) - f.radioAhead.clicked.connect(lambda: self.onRadioChange(RADIO_AHEAD)) - f.radioPreview.clicked.connect(lambda: self.onRadioChange(RADIO_PREVIEW)) - f.radioCram.clicked.connect(lambda: self.onRadioChange(RADIO_CRAM)) + qconnect(f.radioNew.clicked, lambda: self.onRadioChange(RADIO_NEW)) + qconnect(f.radioRev.clicked, lambda: self.onRadioChange(RADIO_REV)) + qconnect(f.radioForgot.clicked, lambda: self.onRadioChange(RADIO_FORGOT)) + qconnect(f.radioAhead.clicked, lambda: self.onRadioChange(RADIO_AHEAD)) + qconnect(f.radioPreview.clicked, lambda: self.onRadioChange(RADIO_PREVIEW)) + qconnect(f.radioCram.clicked, lambda: self.onRadioChange(RADIO_CRAM)) def onRadioChange(self, idx): f = self.form diff --git a/qt/aqt/deckconf.py b/qt/aqt/deckconf.py index 507883bba..b0c8dafff 100644 --- a/qt/aqt/deckconf.py +++ b/qt/aqt/deckconf.py @@ -36,10 +36,11 @@ class DeckConf(QDialog): self.setupCombos() self.setupConfs() self.setWindowModality(Qt.WindowModal) - self.form.buttonBox.helpRequested.connect(lambda: openHelp("deckoptions")) - self.form.confOpts.clicked.connect(self.confOpts) - self.form.buttonBox.button(QDialogButtonBox.RestoreDefaults).clicked.connect( - self.onRestore + qconnect(self.form.buttonBox.helpRequested, lambda: openHelp("deckoptions")) + qconnect(self.form.confOpts.clicked, self.confOpts) + qconnect( + self.form.buttonBox.button(QDialogButtonBox.RestoreDefaults).clicked, + self.onRestore, ) self.setWindowTitle(_("Options for %s") % self.deck["name"]) # qt doesn't size properly with altered fonts otherwise @@ -54,13 +55,13 @@ class DeckConf(QDialog): f = self.form f.newOrder.addItems(list(cs.newCardOrderLabels().values())) - f.newOrder.currentIndexChanged.connect(self.onNewOrderChanged) + qconnect(f.newOrder.currentIndexChanged, self.onNewOrderChanged) # Conf list ###################################################################### def setupConfs(self): - self.form.dconf.currentIndexChanged.connect(self.onConfChange) + qconnect(self.form.dconf.currentIndexChanged, self.onConfChange) self.conf = None self.loadConfs() @@ -84,13 +85,13 @@ class DeckConf(QDialog): def confOpts(self): m = QMenu(self.mw) a = m.addAction(_("Add")) - a.triggered.connect(self.addGroup) + qconnect(a.triggered, self.addGroup) a = m.addAction(_("Delete")) - a.triggered.connect(self.remGroup) + qconnect(a.triggered, self.remGroup) a = m.addAction(_("Rename")) - a.triggered.connect(self.renameGroup) + qconnect(a.triggered, self.renameGroup) a = m.addAction(_("Set for all subdecks")) - a.triggered.connect(self.setChildren) + qconnect(a.triggered, self.setChildren) if not self.childDids: a.setEnabled(False) m.exec_(QCursor.pos()) diff --git a/qt/aqt/dyndeckconf.py b/qt/aqt/dyndeckconf.py index ab7dcff9a..1c656aafd 100644 --- a/qt/aqt/dyndeckconf.py +++ b/qt/aqt/dyndeckconf.py @@ -23,7 +23,7 @@ class DeckConf(QDialog): self.ok = self.form.buttonBox.addButton(label, QDialogButtonBox.AcceptRole) self.mw.checkpoint(_("Options")) self.setWindowModality(Qt.WindowModal) - self.form.buttonBox.helpRequested.connect(lambda: openHelp("filtered")) + qconnect(self.form.buttonBox.helpRequested, lambda: openHelp("filtered")) self.setWindowTitle(_("Options for %s") % self.deck["name"]) restoreGeom(self, "dyndeckconf") self.initialSetup() @@ -46,7 +46,7 @@ class DeckConf(QDialog): self.form.order.addItems(list(cs.dynOrderLabels().values())) self.form.order_2.addItems(list(cs.dynOrderLabels().values())) - self.form.resched.stateChanged.connect(self._onReschedToggled) + qconnect(self.form.resched.stateChanged, self._onReschedToggled) def _onReschedToggled(self, _state): self.form.previewDelayWidget.setVisible( diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index b269df969..f964a5699 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -521,7 +521,7 @@ class Editor: d = QDialog(self.widget) form = aqt.forms.edithtml.Ui_Dialog() form.setupUi(d) - form.buttonBox.helpRequested.connect(lambda: openHelp("editor")) + qconnect(form.buttonBox.helpRequested, lambda: openHelp("editor")) form.textEdit.setPlainText(self.note.fields[field]) d.show() form.textEdit.moveCursor(QTextCursor.End) @@ -553,7 +553,7 @@ class Editor: l = QLabel(_("Tags")) tb.addWidget(l, 1, 0) self.tags = aqt.tagedit.TagEdit(self.widget) - self.tags.lostFocus.connect(self.saveTags) + qconnect(self.tags.lostFocus, self.saveTags) self.tags.setToolTip(shortcut(_("Jump to tags with Ctrl+Shift+T"))) border = theme_manager.str_color("border") self.tags.setStyleSheet(f"border: 1px solid {border}") @@ -921,7 +921,7 @@ to a cloze type first, via Edit>Change Note Type.""" (_("Edit HTML"), self.onHtmlEdit, "Ctrl+Shift+X"), ): a = m.addAction(text) - a.triggered.connect(handler) + qconnect(a.triggered, handler) a.setShortcut(QKeySequence(shortcut)) qtMenuShortcutWorkaround(m) @@ -985,7 +985,7 @@ class EditorWebView(AnkiWebView): self.setAcceptDrops(True) self._markInternal = False clip = self.editor.mw.app.clipboard() - clip.dataChanged.connect(self._onClipboardChange) + qconnect(clip.dataChanged, self._onClipboardChange) gui_hooks.editor_web_view_did_init(self) def _onClipboardChange(self): diff --git a/qt/aqt/errors.py b/qt/aqt/errors.py index 30092fd51..de73435d4 100644 --- a/qt/aqt/errors.py +++ b/qt/aqt/errors.py @@ -34,7 +34,7 @@ class ErrorHandler(QObject): QObject.__init__(self, mw) self.mw = mw self.timer = None - self.errorTimer.connect(self._setTimer) + qconnect(self.errorTimer, self._setTimer) self.pool = "" self._oldstderr = sys.stderr sys.stderr = self @@ -59,7 +59,7 @@ class ErrorHandler(QObject): def _setTimer(self): if not self.timer: self.timer = QTimer(self.mw) - self.timer.timeout.connect(self.onTimeout) + qconnect(self.timer.timeout, self.onTimeout) self.timer.setInterval(self.ivl) self.timer.setSingleShot(True) self.timer.start() diff --git a/qt/aqt/exporting.py b/qt/aqt/exporting.py index 0b2bfdf21..ced41aa95 100644 --- a/qt/aqt/exporting.py +++ b/qt/aqt/exporting.py @@ -11,7 +11,7 @@ from typing import List, Optional import aqt from anki import hooks -from anki.exporting import exporters +from anki.exporting import Exporter, exporters from anki.lang import _, ngettext from aqt.qt import * from aqt.utils import checkInvalidFilename, getSaveFile, showWarning, tooltip @@ -29,7 +29,7 @@ class ExportDialog(QDialog): self.col = mw.col.weakref() self.frm = aqt.forms.exporting.Ui_ExportDialog() self.frm.setupUi(self) - self.exporter = None + self.exporter: Optional[Exporter] = None self.cids = cids self.setup(did) self.exec_() @@ -45,7 +45,7 @@ class ExportDialog(QDialog): break self.frm.format.insertItems(0, [e[0] for e in self.exporters]) self.frm.format.setCurrentIndex(idx) - self.frm.format.activated.connect(self.exporterChanged) + qconnect(self.frm.format.activated, self.exporterChanged) self.exporterChanged(idx) # deck list if self.cids is None: diff --git a/qt/aqt/fields.py b/qt/aqt/fields.py index c5cfd79ba..40cc963a1 100644 --- a/qt/aqt/fields.py +++ b/qt/aqt/fields.py @@ -42,13 +42,13 @@ class FieldDialog(QDialog): def setupSignals(self): f = self.form - f.fieldList.currentRowChanged.connect(self.onRowChange) - f.fieldAdd.clicked.connect(self.onAdd) - f.fieldDelete.clicked.connect(self.onDelete) - f.fieldRename.clicked.connect(self.onRename) - f.fieldPosition.clicked.connect(self.onPosition) - f.sortField.clicked.connect(self.onSortField) - f.buttonBox.helpRequested.connect(self.onHelp) + qconnect(f.fieldList.currentRowChanged, self.onRowChange) + qconnect(f.fieldAdd.clicked, self.onAdd) + qconnect(f.fieldDelete.clicked, self.onDelete) + qconnect(f.fieldRename.clicked, self.onRename) + qconnect(f.fieldPosition.clicked, self.onPosition) + qconnect(f.sortField.clicked, self.onSortField) + qconnect(f.buttonBox.helpRequested, self.onHelp) def onDrop(self, ev): fieldList = self.form.fieldList diff --git a/qt/aqt/importing.py b/qt/aqt/importing.py index 92ffd64cf..7c5204202 100644 --- a/qt/aqt/importing.py +++ b/qt/aqt/importing.py @@ -83,18 +83,18 @@ class ImportDialog(QDialog): self.importer = importer self.frm = aqt.forms.importing.Ui_ImportDialog() self.frm.setupUi(self) - self.frm.buttonBox.button(QDialogButtonBox.Help).clicked.connect( - self.helpRequested + qconnect( + self.frm.buttonBox.button(QDialogButtonBox.Help).clicked, self.helpRequested ) self.setupMappingFrame() self.setupOptions() self.modelChanged() self.frm.autoDetect.setVisible(self.importer.needDelimiter) gui_hooks.current_note_type_did_change.append(self.modelChanged) - self.frm.autoDetect.clicked.connect(self.onDelimiter) + qconnect(self.frm.autoDetect.clicked, self.onDelimiter) self.updateDelimiterButtonText() self.frm.allowHTML.setChecked(self.mw.pm.profile.get("allowHTML", True)) - self.frm.importMode.currentIndexChanged.connect(self.importModeChanged) + qconnect(self.frm.importMode.currentIndexChanged, self.importModeChanged) self.frm.importMode.setCurrentIndex(self.mw.pm.profile.get("importMode", 1)) self.frm.tagModified.setText(self.mw.pm.profile.get("tagModified", "")) self.frm.tagModified.setCol(self.mw.col) @@ -266,7 +266,7 @@ you can enter it here. Use \\t to represent tab.""" self.grid.addWidget(QLabel(text), num, 1) button = QPushButton(_("Change")) self.grid.addWidget(button, num, 2) - button.clicked.connect(lambda _, s=self, n=num: s.changeMappingNum(n)) + qconnect(button.clicked, lambda _, s=self, n=num: s.changeMappingNum(n)) def changeMappingNum(self, n): f = ChangeMap(self.mw, self.importer.model, self.mapping[n]).getField() diff --git a/qt/aqt/legacy.py b/qt/aqt/legacy.py index 79fd1f942..8c11c1d28 100644 --- a/qt/aqt/legacy.py +++ b/qt/aqt/legacy.py @@ -38,9 +38,9 @@ def fmtTimeSpan(time, pad=0, point=0, short=False, inTime=False, unit=99): return aqt.mw.col.backend.format_time_span(time) -def install_pylib_legacy(): - anki.utils.bodyClass = bodyClass - anki.utils.fmtTimeSpan = fmtTimeSpan - anki.sound._soundReg = r"\[sound:(.*?)\]" - anki.sound.allSounds = allSounds - anki.sound.stripSounds = stripSounds +def install_pylib_legacy() -> None: + anki.utils.bodyClass = bodyClass # type: ignore + anki.utils.fmtTimeSpan = fmtTimeSpan # type: ignore + anki.sound._soundReg = r"\[sound:(.*?)\]" # type: ignore + anki.sound.allSounds = allSounds # type: ignore + anki.sound.stripSounds = stripSounds # type: ignore diff --git a/qt/aqt/main.py b/qt/aqt/main.py index 25ba3311b..2049b22d2 100644 --- a/qt/aqt/main.py +++ b/qt/aqt/main.py @@ -204,17 +204,17 @@ class AnkiQt(QMainWindow): d = self.profileDiag = self.ProfileManager() f = self.profileForm = aqt.forms.profiles.Ui_MainWindow() f.setupUi(d) - f.login.clicked.connect(self.onOpenProfile) - f.profiles.itemDoubleClicked.connect(self.onOpenProfile) - f.openBackup.clicked.connect(self.onOpenBackup) - f.quit.clicked.connect(d.close) - d.onClose.connect(self.cleanupAndExit) - f.add.clicked.connect(self.onAddProfile) - f.rename.clicked.connect(self.onRenameProfile) - f.delete_2.clicked.connect(self.onRemProfile) - f.profiles.currentRowChanged.connect(self.onProfileRowChange) + qconnect(f.login.clicked, self.onOpenProfile) + qconnect(f.profiles.itemDoubleClicked, self.onOpenProfile) + qconnect(f.openBackup.clicked, self.onOpenBackup) + qconnect(f.quit.clicked, d.close) + qconnect(d.onClose, self.cleanupAndExit) + qconnect(f.add.clicked, self.onAddProfile) + qconnect(f.rename.clicked, self.onRenameProfile) + qconnect(f.delete_2.clicked, self.onRemProfile) + qconnect(f.profiles.currentRowChanged, self.onProfileRowChange) f.statusbar.setVisible(False) - f.downgrade_button.clicked.connect(self._on_downgrade) + qconnect(f.downgrade_button.clicked, self._on_downgrade) # enter key opens profile QShortcut(QKeySequence("Return"), d, activated=self.onOpenProfile) # type: ignore self.refreshProfilesList() @@ -1128,23 +1128,25 @@ title="%s" %s>%s""" % ( def setupMenus(self) -> None: m = self.form - m.actionSwitchProfile.triggered.connect(self.unloadProfileAndShowProfileManager) - m.actionImport.triggered.connect(self.onImport) - m.actionExport.triggered.connect(self.onExport) - m.actionExit.triggered.connect(self.close) - m.actionPreferences.triggered.connect(self.onPrefs) - m.actionAbout.triggered.connect(self.onAbout) - m.actionUndo.triggered.connect(self.onUndo) + qconnect( + m.actionSwitchProfile.triggered, self.unloadProfileAndShowProfileManager + ) + qconnect(m.actionImport.triggered, self.onImport) + qconnect(m.actionExport.triggered, self.onExport) + qconnect(m.actionExit.triggered, self.close) + qconnect(m.actionPreferences.triggered, self.onPrefs) + qconnect(m.actionAbout.triggered, self.onAbout) + qconnect(m.actionUndo.triggered, self.onUndo) if qtminor < 11: m.actionUndo.setShortcut(QKeySequence("Ctrl+Alt+Z")) - m.actionFullDatabaseCheck.triggered.connect(self.onCheckDB) - m.actionCheckMediaDatabase.triggered.connect(self.on_check_media_db) - m.actionDocumentation.triggered.connect(self.onDocumentation) - m.actionDonate.triggered.connect(self.onDonate) - m.actionStudyDeck.triggered.connect(self.onStudyDeck) - m.actionCreateFiltered.triggered.connect(self.onCram) - m.actionEmptyCards.triggered.connect(self.onEmptyCards) - m.actionNoteTypes.triggered.connect(self.onNoteTypes) + qconnect(m.actionFullDatabaseCheck.triggered, self.onCheckDB) + qconnect(m.actionCheckMediaDatabase.triggered, self.on_check_media_db) + qconnect(m.actionDocumentation.triggered, self.onDocumentation) + qconnect(m.actionDonate.triggered, self.onDonate) + qconnect(m.actionStudyDeck.triggered, self.onStudyDeck) + qconnect(m.actionCreateFiltered.triggered, self.onCram) + qconnect(m.actionEmptyCards.triggered, self.onEmptyCards) + qconnect(m.actionNoteTypes.triggered, self.onNoteTypes) def updateTitleBar(self) -> None: self.setWindowTitle("Anki") @@ -1156,9 +1158,9 @@ title="%s" %s>%s""" % ( import aqt.update self.autoUpdate = aqt.update.LatestVersionFinder(self) - self.autoUpdate.newVerAvail.connect(self.newVerAvail) # type: ignore - self.autoUpdate.newMsg.connect(self.newMsg) # type: ignore - self.autoUpdate.clockIsOff.connect(self.clockIsOff) # type: ignore + qconnect(self.autoUpdate.newVerAvail, self.newVerAvail) + qconnect(self.autoUpdate.newMsg, self.newMsg) + qconnect(self.autoUpdate.clockIsOff, self.clockIsOff) self.autoUpdate.start() def newVerAvail(self, ver): @@ -1360,7 +1362,7 @@ will be lost. Continue?""" ) self.reset() - box.accepted.connect(onDelete) + qconnect(box.accepted, onDelete) diag.show() # Debugging @@ -1376,13 +1378,13 @@ will be lost. Continue?""" frm.text.setFont(font) frm.log.setFont(font) s = self.debugDiagShort = QShortcut(QKeySequence("ctrl+return"), d) - s.activated.connect(lambda: self.onDebugRet(frm)) + qconnect(s.activated, lambda: self.onDebugRet(frm)) s = self.debugDiagShort = QShortcut(QKeySequence("ctrl+shift+return"), d) - s.activated.connect(lambda: self.onDebugPrint(frm)) + qconnect(s.activated, lambda: self.onDebugPrint(frm)) s = self.debugDiagShort = QShortcut(QKeySequence("ctrl+l"), d) - s.activated.connect(frm.log.clear) + qconnect(s.activated, frm.log.clear) s = self.debugDiagShort = QShortcut(QKeySequence("ctrl+shift+l"), d) - s.activated.connect(frm.text.clear) + qconnect(s.activated, frm.text.clear) def addContextMenu(ev: QCloseEvent, name: str) -> None: ev.accept() @@ -1514,7 +1516,7 @@ will be lost. Continue?""" if isMac: # mac users expect a minimize option self.minimizeShortcut = QShortcut("Ctrl+M", self) - self.minimizeShortcut.activated.connect(self.onMacMinimize) # type: ignore + qconnect(self.minimizeShortcut.activated, self.onMacMinimize) self.hideMenuAccels = True self.maybeHideAccelerators() self.hideStatusTips() @@ -1546,7 +1548,7 @@ will be lost. Continue?""" ########################################################################## def setupAppMsg(self) -> None: - self.app.appMsg.connect(self.onAppMsg) + qconnect(self.app.appMsg, self.onAppMsg) def onAppMsg(self, buf: str) -> Optional[QTimer]: is_addon = self._isAddon(buf) @@ -1606,7 +1608,7 @@ Please ensure a profile is open and Anki is not busy, then try again.""" # ensure gc runs in main thread def setupDialogGC(self, obj: Any) -> None: - obj.finished.connect(lambda: self.gcWindow(obj)) + qconnect(obj.finished, lambda: self.gcWindow(obj)) def gcWindow(self, obj: Any) -> None: obj.deleteLater() diff --git a/qt/aqt/mediacheck.py b/qt/aqt/mediacheck.py index b3c4c547e..2d1fdc1d5 100644 --- a/qt/aqt/mediacheck.py +++ b/qt/aqt/mediacheck.py @@ -6,7 +6,7 @@ from __future__ import annotations import itertools import time from concurrent.futures import Future -from typing import Iterable, List, Optional, TypeVar +from typing import Iterable, List, Optional, Sequence, TypeVar import aqt from anki import hooks @@ -84,27 +84,27 @@ class MediaChecker: b = QPushButton(tr(TR.MEDIA_CHECK_DELETE_UNUSED)) b.setAutoDefault(False) box.addButton(b, QDialogButtonBox.RejectRole) - b.clicked.connect(lambda c: self._on_trash_files(output.unused)) # type: ignore + qconnect(b.clicked, lambda c: self._on_trash_files(output.unused)) if output.missing: if any(map(lambda x: x.startswith("latex-"), output.missing)): b = QPushButton(tr(TR.MEDIA_CHECK_RENDER_LATEX)) b.setAutoDefault(False) box.addButton(b, QDialogButtonBox.RejectRole) - b.clicked.connect(self._on_render_latex) # type: ignore + qconnect(b.clicked, self._on_render_latex) if output.have_trash: b = QPushButton(tr(TR.MEDIA_CHECK_EMPTY_TRASH)) b.setAutoDefault(False) box.addButton(b, QDialogButtonBox.RejectRole) - b.clicked.connect(lambda c: self._on_empty_trash()) # type: ignore + qconnect(b.clicked, lambda c: self._on_empty_trash()) b = QPushButton(tr(TR.MEDIA_CHECK_RESTORE_TRASH)) b.setAutoDefault(False) box.addButton(b, QDialogButtonBox.RejectRole) - b.clicked.connect(lambda c: self._on_restore_trash()) # type: ignore + qconnect(b.clicked, lambda c: self._on_restore_trash()) - box.rejected.connect(diag.reject) # type: ignore + qconnect(box.rejected, diag.reject) diag.setMinimumHeight(400) diag.setMinimumWidth(500) restoreGeom(diag, "checkmediadb") @@ -137,7 +137,7 @@ class MediaChecker: self.mw.progress.update(tr(TR.MEDIA_CHECK_CHECKED, count=count)) return True - def _on_trash_files(self, fnames: List[str]): + def _on_trash_files(self, fnames: Sequence[str]): if not askUser(tr(TR.MEDIA_CHECK_DELETE_UNUSED_CONFIRM)): return diff --git a/qt/aqt/mediasync.py b/qt/aqt/mediasync.py index 44fc8b3e7..4b77a8559 100644 --- a/qt/aqt/mediasync.py +++ b/qt/aqt/mediasync.py @@ -22,7 +22,7 @@ from anki.rsbackend import ( from anki.types import assert_impossible from anki.utils import intTime from aqt import gui_hooks -from aqt.qt import QDialog, QDialogButtonBox, QPushButton +from aqt.qt import QDialog, QDialogButtonBox, QPushButton, qconnect from aqt.utils import showWarning, tr LogEntry = Union[MediaSyncProgress, str] @@ -167,7 +167,7 @@ class MediaSyncDialog(QDialog): self.form.setupUi(self) self.setWindowTitle(tr(TR.SYNC_MEDIA_LOG_TITLE)) self.abort_button = QPushButton(tr(TR.SYNC_ABORT_BUTTON)) - self.abort_button.clicked.connect(self._on_abort) # type: ignore + qconnect(self.abort_button.clicked, self._on_abort) self.abort_button.setAutoDefault(False) self.form.buttonBox.addButton(self.abort_button, QDialogButtonBox.ActionRole) self.abort_button.setHidden(not self._syncer.is_syncing()) diff --git a/qt/aqt/modelchooser.py b/qt/aqt/modelchooser.py index 57b5c8db8..98ba9dfdb 100644 --- a/qt/aqt/modelchooser.py +++ b/qt/aqt/modelchooser.py @@ -32,7 +32,7 @@ class ModelChooser(QHBoxLayout): s = QShortcut(QKeySequence("Ctrl+N"), self.widget, activated=self.onModelChange) self.models.setAutoDefault(False) self.addWidget(self.models) - self.models.clicked.connect(self.onModelChange) + qconnect(self.models.clicked, self.onModelChange) # layout sizePolicy = QSizePolicy(QSizePolicy.Policy(7), QSizePolicy.Policy(0)) self.models.setSizePolicy(sizePolicy) diff --git a/qt/aqt/models.py b/qt/aqt/models.py index f1a4f2cd1..aac73abfc 100644 --- a/qt/aqt/models.py +++ b/qt/aqt/models.py @@ -3,6 +3,7 @@ import collections import re from operator import itemgetter +from typing import Optional import aqt.clayout from anki import stdmodels @@ -32,7 +33,7 @@ class Models(QDialog): self.mw.checkpoint(_("Note Types")) self.form = aqt.forms.models.Ui_Dialog() self.form.setupUi(self) - self.form.buttonBox.helpRequested.connect(lambda: openHelp("notetypes")) + qconnect(self.form.buttonBox.helpRequested, lambda: openHelp("notetypes")) self.setupModels() restoreGeom(self, "models") self.exec_() @@ -46,20 +47,20 @@ class Models(QDialog): box = f.buttonBox t = QDialogButtonBox.ActionRole b = box.addButton(_("Add"), t) - b.clicked.connect(self.onAdd) + qconnect(b.clicked, self.onAdd) b = box.addButton(_("Rename"), t) - b.clicked.connect(self.onRename) + qconnect(b.clicked, self.onRename) b = box.addButton(_("Delete"), t) - b.clicked.connect(self.onDelete) + qconnect(b.clicked, self.onDelete) if self.fromMain: b = box.addButton(_("Fields..."), t) - b.clicked.connect(self.onFields) + qconnect(b.clicked, self.onFields) b = box.addButton(_("Cards..."), t) - b.clicked.connect(self.onCards) + qconnect(b.clicked, self.onCards) b = box.addButton(_("Options..."), t) - b.clicked.connect(self.onAdvanced) - f.modelsList.currentRowChanged.connect(self.modelChanged) - f.modelsList.itemDoubleClicked.connect(self.onRename) + qconnect(b.clicked, self.onAdvanced) + qconnect(f.modelsList.currentRowChanged, self.modelChanged) + qconnect(f.modelsList.itemDoubleClicked, self.onRename) self.updateModelsList() f.modelsList.setCurrentRow(0) maybeHideClose(box) @@ -123,7 +124,7 @@ class Models(QDialog): frm.latexHeader.setText(self.model["latexPre"]) frm.latexFooter.setText(self.model["latexPost"]) d.setWindowTitle(_("Options for %s") % self.model["name"]) - frm.buttonBox.helpRequested.connect(lambda: openHelp("latex")) + qconnect(frm.buttonBox.helpRequested, lambda: openHelp("latex")) restoreGeom(d, "modelopts") gui_hooks.models_advanced_will_show(d) d.exec_() @@ -180,19 +181,19 @@ class Models(QDialog): class AddModel(QDialog): - def __init__(self, mw, parent=None): - self.parent = parent or mw + def __init__(self, mw: AnkiQt, parent: Optional[QWidget] = None): + self.parent_ = parent or mw self.mw = mw self.col = mw.col - QDialog.__init__(self, self.parent, Qt.Window) + QDialog.__init__(self, self.parent_, Qt.Window) self.model = None self.dialog = aqt.forms.addmodel.Ui_Dialog() self.dialog.setupUi(self) # standard models self.models = [] for (name, func) in stdmodels.models: - if isinstance(name, collections.Callable): - name = name() + if isinstance(name, collections.Callable): # type: ignore + name = name() # type: ignore item = QListWidgetItem(_("Add: %s") % name) self.dialog.models.addItem(item) self.models.append((True, func)) @@ -204,9 +205,9 @@ class AddModel(QDialog): self.dialog.models.setCurrentRow(0) # the list widget will swallow the enter key s = QShortcut(QKeySequence("Return"), self) - s.activated.connect(self.accept) + qconnect(s.activated, self.accept) # help - self.dialog.buttonBox.helpRequested.connect(self.onHelp) + qconnect(self.dialog.buttonBox.helpRequested, self.onHelp) def get(self): self.exec_() diff --git a/qt/aqt/mpv.py b/qt/aqt/mpv.py index 59e63947d..7a13c5b7d 100644 --- a/qt/aqt/mpv.py +++ b/qt/aqt/mpv.py @@ -42,6 +42,7 @@ from queue import Empty, Full, Queue from typing import Dict, Optional from anki.utils import isWin +from aqt import qconnect class MPVError(Exception): @@ -180,7 +181,7 @@ class MPVBase: # unix socket try: self._sock = socket.socket(socket.AF_UNIX) - self._sock.connect(self._sock_filename) + qconnect(self._sock, self._sock_filename) except (FileNotFoundError, ConnectionRefusedError): self._sock.close() continue diff --git a/qt/aqt/preferences.py b/qt/aqt/preferences.py index af9f36958..5f6f705a1 100644 --- a/qt/aqt/preferences.py +++ b/qt/aqt/preferences.py @@ -22,7 +22,7 @@ class Preferences(QDialog): self.form.setupUi(self) self.form.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False) self.form.buttonBox.button(QDialogButtonBox.Close).setAutoDefault(False) - self.form.buttonBox.helpRequested.connect(lambda: openHelp("profileprefs")) + qconnect(self.form.buttonBox.helpRequested, lambda: openHelp("profileprefs")) self.silentlyClose = True self.setupLang() self.setupCollection() @@ -54,7 +54,7 @@ class Preferences(QDialog): f = self.form f.lang.addItems([x[0] for x in anki.lang.langs]) f.lang.setCurrentIndex(self.langIdx()) - f.lang.currentIndexChanged.connect(self.onLangIdxChanged) + qconnect(f.lang.currentIndexChanged, self.onLangIdxChanged) def langIdx(self): codes = [x[1] for x in anki.lang.langs] @@ -193,14 +193,14 @@ class Preferences(QDialog): def setupNetwork(self): self.form.media_log.setText(tr(TR.SYNC_MEDIA_LOG_BUTTON)) - self.form.media_log.clicked.connect(self.on_media_log) + qconnect(self.form.media_log.clicked, self.on_media_log) self.form.syncOnProgramOpen.setChecked(self.prof["autoSync"]) self.form.syncMedia.setChecked(self.prof["syncMedia"]) if not self.prof["syncKey"]: self._hideAuth() else: self.form.syncUser.setText(self.prof.get("syncUser", "")) - self.form.syncDeauth.clicked.connect(self.onSyncDeauth) + qconnect(self.form.syncDeauth.clicked, self.onSyncDeauth) def on_media_log(self): self.mw.media_syncer.show_sync_log() diff --git a/qt/aqt/profiles.py b/qt/aqt/profiles.py index b8dff8abb..345b0a9b2 100644 --- a/qt/aqt/profiles.py +++ b/qt/aqt/profiles.py @@ -416,8 +416,8 @@ create table if not exists profiles d = self.langDiag = NoCloseDiag() f = self.langForm = aqt.forms.setlang.Ui_Dialog() f.setupUi(d) - d.accepted.connect(self._onLangSelected) - d.rejected.connect(lambda: True) + qconnect(d.accepted, self._onLangSelected) + qconnect(d.rejected, lambda: True) # default to the system language try: (lang, enc) = locale.getdefaultlocale() diff --git a/qt/aqt/progress.py b/qt/aqt/progress.py index acb14e362..29202287c 100644 --- a/qt/aqt/progress.py +++ b/qt/aqt/progress.py @@ -45,7 +45,7 @@ class ProgressManager: t = QTimer(self.mw) if not repeat: t.setSingleShot(True) - t.timeout.connect(handler) + qconnect(t.timeout, handler) t.start(ms) return t @@ -74,7 +74,7 @@ class ProgressManager: self._win.setWindowModality(Qt.ApplicationModal) self._win.setMinimumWidth(300) self._setBusy() - self._shown = False + self._shown = 0 self._counter = min self._min = min self._max = max @@ -84,10 +84,10 @@ class ProgressManager: self._show_timer = QTimer(self.mw) self._show_timer.setSingleShot(True) self._show_timer.start(600) - self._show_timer.timeout.connect(self._on_show_timer) # type: ignore + qconnect(self._show_timer.timeout, self._on_show_timer) return self._win - def update(self, label=None, value=None, process=True, maybeShow=True): + def update(self, label=None, value=None, process=True, maybeShow=True) -> None: # print self._min, self._counter, self._max, label, time.time() - self._lastTime if not self.mw.inMainThread(): print("progress.update() called on wrong thread") @@ -141,7 +141,7 @@ class ProgressManager: self._shown = time.time() self._win.show() - def _closeWin(self): + def _closeWin(self) -> None: if self._shown: while True: # give the window system a second to present @@ -154,7 +154,7 @@ class ProgressManager: self.app.processEvents(QEventLoop.ExcludeUserInputEvents) self._win.cancel() self._win = None - self._shown = False + self._shown = 0 def _setBusy(self): self.mw.app.setOverrideCursor(QCursor(Qt.WaitCursor)) diff --git a/qt/aqt/qt.py b/qt/aqt/qt.py index 194e1be34..a9557c28d 100644 --- a/qt/aqt/qt.py +++ b/qt/aqt/qt.py @@ -7,7 +7,7 @@ import os import sys import traceback -from typing import Callable +from typing import Callable, Union from PyQt5.Qt import * # type: ignore from PyQt5.QtCore import * @@ -55,6 +55,6 @@ if qtmajor != 5 or qtminor < 9 or qtminor == 10: raise Exception("Anki does not support your Qt version.") -def qconnect(signal: Callable, func: Callable) -> None: +def qconnect(signal: Union[Callable, pyqtSignal], func: Callable) -> None: "Helper to work around type checking not working with signal.connect(func)." signal.connect(func) # type: ignore diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index 40e4bdef5..743cc3087 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -757,7 +757,7 @@ time = %(time)d; if opts.get("checked"): a.setCheckable(True) a.setChecked(True) - a.triggered.connect(func) + qconnect(a.triggered, func) def onOptions(self) -> None: self.mw.onDeckConf(self.mw.col.decks.get(self.card.odid or self.card.did)) diff --git a/qt/aqt/stats.py b/qt/aqt/stats.py index 3a57d85f0..2d64208d1 100644 --- a/qt/aqt/stats.py +++ b/qt/aqt/stats.py @@ -38,14 +38,14 @@ class DeckStats(QDialog): f.setupUi(self) restoreGeom(self, self.name) b = f.buttonBox.addButton(_("Save PDF"), QDialogButtonBox.ActionRole) - b.clicked.connect(self.saveImage) + qconnect(b.clicked, self.saveImage) b.setAutoDefault(False) - f.groups.clicked.connect(lambda: self.changeScope("deck")) + qconnect(f.groups.clicked, lambda: self.changeScope("deck")) f.groups.setShortcut("g") - f.all.clicked.connect(lambda: self.changeScope("collection")) - f.month.clicked.connect(lambda: self.changePeriod(0)) - f.year.clicked.connect(lambda: self.changePeriod(1)) - f.life.clicked.connect(lambda: self.changePeriod(2)) + qconnect(f.all.clicked, lambda: self.changeScope("collection")) + qconnect(f.month.clicked, lambda: self.changePeriod(0)) + qconnect(f.year.clicked, lambda: self.changePeriod(1)) + qconnect(f.life.clicked, lambda: self.changePeriod(2)) maybeHideClose(self.form.buttonBox) addCloseShortcut(self) self.show() diff --git a/qt/aqt/studydeck.py b/qt/aqt/studydeck.py index 00538a880..9e0f02f8d 100644 --- a/qt/aqt/studydeck.py +++ b/qt/aqt/studydeck.py @@ -48,7 +48,7 @@ class StudyDeck(QDialog): b.setShortcut(QKeySequence("Ctrl+N")) b.setToolTip(shortcut(_("Add New Deck (Ctrl+N)"))) self.form.buttonBox.addButton(b, QDialogButtonBox.ActionRole) - b.clicked.connect(self.onAddDeck) + qconnect(b.clicked, self.onAddDeck) if title: self.setWindowTitle(title) if not names: @@ -66,9 +66,9 @@ class StudyDeck(QDialog): accept or _("Study"), QDialogButtonBox.AcceptRole ) self.setWindowModality(Qt.WindowModal) - self.form.buttonBox.helpRequested.connect(lambda: openHelp(help)) - self.form.filter.textEdited.connect(self.redraw) - self.form.list.itemDoubleClicked.connect(self.accept) + qconnect(self.form.buttonBox.helpRequested, lambda: openHelp(help)) + qconnect(self.form.filter.textEdited, self.redraw) + qconnect(self.form.list.itemDoubleClicked, self.accept) self.show() # redraw after show so position at center correct self.redraw("", current) diff --git a/qt/aqt/sync.py b/qt/aqt/sync.py index c43493fb6..2c805b6a7 100644 --- a/qt/aqt/sync.py +++ b/qt/aqt/sync.py @@ -44,8 +44,8 @@ class SyncManager(QObject): auth=auth, hostNum=self.pm.profile.get("hostNum"), ) - t._event.connect(self.onEvent) - t.progress_event.connect(self.on_progress) + qconnect(t._event, self.onEvent) + qconnect(t.progress_event, self.on_progress) self.label = _("Connecting...") prog = self.mw.progress.start(immediate=True, label=self.label) self.sentBytes = self.recvBytes = 0 @@ -268,8 +268,8 @@ enter your details below.""" vbox.addLayout(g) bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.button(QDialogButtonBox.Ok).setAutoDefault(True) - bb.accepted.connect(d.accept) - bb.rejected.connect(d.reject) + qconnect(bb.accepted, d.accept) + qconnect(bb.rejected, d.reject) vbox.addWidget(bb) d.setLayout(vbox) d.show() diff --git a/qt/aqt/tagedit.py b/qt/aqt/tagedit.py index bb050d40c..4f1fd86f3 100644 --- a/qt/aqt/tagedit.py +++ b/qt/aqt/tagedit.py @@ -18,12 +18,12 @@ class TagEdit(QLineEdit): self.model = QStringListModel() self.type = type if type == 0: - self.completer = TagCompleter(self.model, parent, self) + self.completer_ = TagCompleter(self.model, parent, self) else: - self.completer = QCompleter(self.model, parent) - self.completer.setCompletionMode(QCompleter.PopupCompletion) - self.completer.setCaseSensitivity(Qt.CaseInsensitive) - self.setCompleter(self.completer) + self.completer_ = QCompleter(self.model, parent) + self.completer_.setCompletionMode(QCompleter.PopupCompletion) + self.completer_.setCaseSensitivity(Qt.CaseInsensitive) + self.setCompleter(self.completer_) def setCol(self, col): "Set the current col, updating list of available tags." @@ -40,26 +40,26 @@ class TagEdit(QLineEdit): def keyPressEvent(self, evt): if evt.key() in (Qt.Key_Up, Qt.Key_Down): # show completer on arrow key up/down - if not self.completer.popup().isVisible(): + if not self.completer_.popup().isVisible(): self.showCompleter() return if evt.key() == Qt.Key_Tab and evt.modifiers() & Qt.ControlModifier: # select next completion - if not self.completer.popup().isVisible(): + if not self.completer_.popup().isVisible(): self.showCompleter() - index = self.completer.currentIndex() - self.completer.popup().setCurrentIndex(index) + index = self.completer_.currentIndex() + self.completer_.popup().setCurrentIndex(index) cur_row = index.row() - if not self.completer.setCurrentRow(cur_row + 1): - self.completer.setCurrentRow(0) + if not self.completer_.setCurrentRow(cur_row + 1): + self.completer_.setCurrentRow(0) return if evt.key() in (Qt.Key_Enter, Qt.Key_Return): # apply first completion if no suggestion selected - selected_row = self.completer.popup().currentIndex().row() + selected_row = self.completer_.popup().currentIndex().row() if selected_row == -1: - self.completer.setCurrentRow(0) - index = self.completer.currentIndex() - self.completer.popup().setCurrentIndex(index) + self.completer_.setCurrentRow(0) + index = self.completer_.currentIndex() + self.completer_.popup().setCurrentIndex(index) self.hideCompleter() QWidget.keyPressEvent(self, evt) return @@ -80,18 +80,18 @@ class TagEdit(QLineEdit): gui_hooks.tag_editor_did_process_key(self, evt) def showCompleter(self): - self.completer.setCompletionPrefix(self.text()) - self.completer.complete() + self.completer_.setCompletionPrefix(self.text()) + self.completer_.complete() - def focusOutEvent(self, evt): + def focusOutEvent(self, evt) -> None: QLineEdit.focusOutEvent(self, evt) - self.lostFocus.emit() - self.completer.popup().hide() + self.lostFocus.emit() # type: ignore + self.completer_.popup().hide() def hideCompleter(self): - if sip.isdeleted(self.completer): + if sip.isdeleted(self.completer_): return - self.completer.popup().hide() + self.completer_.popup().hide() class TagCompleter(QCompleter): diff --git a/qt/aqt/taglimit.py b/qt/aqt/taglimit.py index f7fce1164..0cb164683 100644 --- a/qt/aqt/taglimit.py +++ b/qt/aqt/taglimit.py @@ -17,11 +17,11 @@ class TagLimit(QDialog): s = QShortcut( QKeySequence("ctrl+d"), self.dialog.activeList, context=Qt.WidgetShortcut ) - s.activated.connect(self.dialog.activeList.clearSelection) + qconnect(s.activated, self.dialog.activeList.clearSelection) s = QShortcut( QKeySequence("ctrl+d"), self.dialog.inactiveList, context=Qt.WidgetShortcut ) - s.activated.connect(self.dialog.inactiveList.clearSelection) + qconnect(s.activated, self.dialog.inactiveList.clearSelection) self.rebuildTagList() restoreGeom(self, "tagLimit") self.exec_() diff --git a/qt/aqt/taskman.py b/qt/aqt/taskman.py index d3cb257b4..44718a04d 100644 --- a/qt/aqt/taskman.py +++ b/qt/aqt/taskman.py @@ -12,6 +12,8 @@ from typing import Any, Callable, Dict, List, Optional from PyQt5.QtCore import QObject, pyqtSignal +from aqt.qt import qconnect + Closure = Callable[[], None] @@ -23,7 +25,7 @@ class TaskManager(QObject): self._executor = ThreadPoolExecutor() self._closures: List[Closure] = [] self._closures_lock = Lock() - self._closures_pending.connect(self._on_closures_pending) # type: ignore + qconnect(self._closures_pending, self._on_closures_pending) def run_on_main(self, closure: Closure): "Run the provided closure on the main thread." diff --git a/qt/aqt/utils.py b/qt/aqt/utils.py index a0e123622..d92476268 100644 --- a/qt/aqt/utils.py +++ b/qt/aqt/utils.py @@ -100,7 +100,7 @@ def showInfo( b.setDefault(True) if help: b = mb.addButton(QMessageBox.Help) - b.clicked.connect(lambda: openHelp(help)) + qconnect(b.clicked, lambda: openHelp(help)) b.setAutoDefault(False) return mb.exec_() @@ -137,7 +137,7 @@ def showText( QApplication.clipboard().setText(text.toPlainText()) btn = QPushButton(_("Copy to Clipboard")) - btn.clicked.connect(onCopy) + qconnect(btn.clicked, onCopy) box.addButton(btn, QDialogButtonBox.ActionRole) def onReject(): @@ -145,13 +145,13 @@ def showText( saveGeom(diag, geomKey) QDialog.reject(diag) - box.rejected.connect(onReject) + qconnect(box.rejected, onReject) def onFinish(): if geomKey: saveGeom(diag, geomKey) - box.accepted.connect(onFinish) + qconnect(box.accepted, onFinish) diag.setMinimumHeight(minHeight) diag.setMinimumWidth(minWidth) if geomKey: @@ -257,10 +257,10 @@ class GetTextDialog(QDialog): b = QDialogButtonBox(buts) v.addWidget(b) self.setLayout(v) - b.button(QDialogButtonBox.Ok).clicked.connect(self.accept) - b.button(QDialogButtonBox.Cancel).clicked.connect(self.reject) + qconnect(b.button(QDialogButtonBox.Ok).clicked, self.accept) + qconnect(b.button(QDialogButtonBox.Cancel).clicked, self.reject) if help: - b.button(QDialogButtonBox.Help).clicked.connect(self.helpRequested) + qconnect(b.button(QDialogButtonBox.Help).clicked, self.helpRequested) def accept(self): return QDialog.accept(self) @@ -319,7 +319,7 @@ def chooseList(prompt, choices, startrow=0, parent=None): c.setCurrentRow(startrow) l.addWidget(c) bb = QDialogButtonBox(QDialogButtonBox.Ok) - bb.accepted.connect(d.accept) + qconnect(bb.accepted, d.accept) l.addWidget(bb) d.exec_() return c.currentRow() @@ -366,7 +366,7 @@ def getFile(parent, title, cb, filter="*.*", dir=None, key=None, multi=False): cb(result) ret.append(result) - d.accepted.connect(accept) + qconnect(d.accepted, accept) if key: restoreState(d, key) d.exec_() @@ -520,7 +520,7 @@ def addCloseShortcut(widg): if not isMac: return widg._closeShortcut = QShortcut(QKeySequence("Ctrl+W"), widg) - widg._closeShortcut.activated.connect(widg.reject) + qconnect(widg._closeShortcut.activated, widg.reject) def downArrow(): @@ -680,7 +680,7 @@ class MenuItem: def renderTo(self, qmenu): a = qmenu.addAction(self.title) - a.triggered.connect(self.func) + qconnect(a.triggered, self.func) def qtMenuShortcutWorkaround(qmenu): diff --git a/qt/aqt/webview.py b/qt/aqt/webview.py index 1e1da0ede..1c5f78f6e 100644 --- a/qt/aqt/webview.py +++ b/qt/aqt/webview.py @@ -268,7 +268,7 @@ class AnkiWebView(QWebEngineView): # type: ignore def contextMenuEvent(self, evt) -> None: m = QMenu(self) a = m.addAction(_("Copy")) - a.triggered.connect(self.onCopy) # type: ignore + qconnect(a.triggered, self.onCopy) gui_hooks.webview_will_show_context_menu(self, m) m.popup(QCursor.pos()) diff --git a/qt/mypy.ini b/qt/mypy.ini index a69375016..e43060eed 100644 --- a/qt/mypy.ini +++ b/qt/mypy.ini @@ -6,7 +6,12 @@ show_error_codes = true disallow_untyped_decorators = True warn_redundant_casts = True warn_unused_configs = True +#check_untyped_defs = true +[mypy-aqt.forms.*] +check_untyped_defs=false +[mypy-aqt.mpv] +ignore_errors=true [mypy-win32file] ignore_missing_imports = True [mypy-win32pipe]