Maintain compatibility with PyQt5 add-ons in PyQt6 builds (#1440)
* Alias PyQt5 to PyQt6 on PyQt6 builds Restores basic compatibility with PyQt5 add-ons * Register QtCore early to work around sip error * Monkey-patch unscoped enums that are in use by add-ons back in Enums whose namespace moved with PyQt6 were determined using the tooling in https://github.com/qutebrowser/qutebrowser/issues/5904 Relevant enums for the Anki add-on ecosystem were found by grepping through all AnkiWeb add-ons and a selection of GitHub-released add-ons. * Add full Qt.Key namespace Maintains compatibility with add-ons that allow specifying key bindings via Qt.Key enums * Reintroduce PyQt6.Qt as an alias for QtCore.Qt * Alias classes shifted from QtWidgets to QtGui * Add missing enums Adds ≈200 enums that were missed during the initial grep * Map exec_ calls to exec * Tweak section headers * Fix QtWebEngineWidgets imports failing due to delayed import Addesses: "QtWebEngineWidgets must be imported before a QCoreApplication instance is created" * Register additional aliases for top-level Qt modules Given how we have had to deal with side-effects when not registering other aliased imports ahead of time, it seems safer to also register the remaining few with sys.modules. * Handle calls to deprecated PyQt resource API graciously * Create QtWebEngineWidgets aliases for classes moved to QtWebEngineCore * Alias QShortcut * Restore QWebEnginePage.view() * Alias sip to PyQt6.sip * Alias QtCore.QRegExp to QtCore.QRegularExpression * Restructure aqt.qt into package Pre-requirement for aliasing the PyQt5.Qt namespace correctly. Should hopefully also make it easier to keep an overview as Qt-compat-related modules were proliferating. * Properly alias PyQt5.Qt PyQt5.Qt used to serve as a common namespace for all Qt classes, not just QtCore.Qt.* While this changes does not make all classes accessible via PyQt5.Qt, it does so for the most important Qt submodules, which should cover most add-on breakages. * Simplify Qt resource system legacy handling * Also alias PyQt6.Qt Covers imports of the form `from PyQt5 import import Qt` (due to previous aliasing of PyQt5 to PyQt6) * Add missing enums Better approach to grepping through add-ons yielded additional hits * Run formatters * Satisfy pylint
This commit is contained in:
parent
afc56a8398
commit
2d1c058106
@ -10,33 +10,10 @@ import traceback
|
|||||||
from typing import Callable, Union
|
from typing import Callable, Union
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from PyQt6 import sip
|
from . import compat # needs to be imported first
|
||||||
from PyQt6.QtCore import *
|
from .qt6 import *
|
||||||
|
|
||||||
# conflicting Qt and qFuzzyCompare definitions require an ignore
|
|
||||||
from PyQt6.QtGui import * # type: ignore[misc]
|
|
||||||
from PyQt6.QtNetwork import QLocalServer, QLocalSocket, QNetworkProxy
|
|
||||||
from PyQt6.QtWebChannel import QWebChannel
|
|
||||||
from PyQt6.QtWebEngineCore import *
|
|
||||||
from PyQt6.QtWebEngineWidgets import *
|
|
||||||
from PyQt6.QtWidgets import *
|
|
||||||
except:
|
except:
|
||||||
from PyQt5.QtCore import * # type: ignore
|
from .qt5 import * # type: ignore
|
||||||
from PyQt5.QtGui import * # type: ignore
|
|
||||||
from PyQt5.QtNetwork import ( # type: ignore
|
|
||||||
QLocalServer,
|
|
||||||
QLocalSocket,
|
|
||||||
QNetworkProxy,
|
|
||||||
)
|
|
||||||
from PyQt5.QtWebChannel import QWebChannel # type: ignore
|
|
||||||
from PyQt5.QtWebEngineCore import * # type: ignore
|
|
||||||
from PyQt5.QtWebEngineWidgets import * # type: ignore
|
|
||||||
from PyQt5.QtWidgets import * # type: ignore
|
|
||||||
|
|
||||||
try:
|
|
||||||
from PyQt5 import sip # type: ignore
|
|
||||||
except ImportError:
|
|
||||||
import sip # type: ignore
|
|
||||||
|
|
||||||
from anki.utils import isMac, isWin
|
from anki.utils import isMac, isWin
|
||||||
|
|
1265
qt/aqt/qt/compat.py
Normal file
1265
qt/aqt/qt/compat.py
Normal file
File diff suppressed because it is too large
Load Diff
22
qt/aqt/qt/qt5.py
Normal file
22
qt/aqt/qt/qt5.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
# make sure not to optimize imports on this file
|
||||||
|
# pylint: skip-file
|
||||||
|
|
||||||
|
"""
|
||||||
|
PyQt5 imports
|
||||||
|
"""
|
||||||
|
|
||||||
|
from PyQt5.QtCore import * # type: ignore
|
||||||
|
from PyQt5.QtGui import * # type: ignore
|
||||||
|
from PyQt5.QtNetwork import QLocalServer, QLocalSocket, QNetworkProxy # type: ignore
|
||||||
|
from PyQt5.QtWebChannel import QWebChannel # type: ignore
|
||||||
|
from PyQt5.QtWebEngineCore import * # type: ignore
|
||||||
|
from PyQt5.QtWebEngineWidgets import * # type: ignore
|
||||||
|
from PyQt5.QtWidgets import * # type: ignore
|
||||||
|
|
||||||
|
try:
|
||||||
|
from PyQt5 import sip # type: ignore
|
||||||
|
except ImportError:
|
||||||
|
import sip # type: ignore
|
@ -13,9 +13,9 @@ from typing import cast
|
|||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
|
|
||||||
from .qt import *
|
from . import * # isort:skip
|
||||||
from .sound import Recorder
|
from ..sound import Recorder # isort:skip
|
||||||
from .utils import showWarning
|
from ..utils import showWarning # isort:skip
|
||||||
|
|
||||||
|
|
||||||
class QtAudioInputRecorder(Recorder):
|
class QtAudioInputRecorder(Recorder):
|
17
qt/aqt/qt/qt5qt.py
Normal file
17
qt/aqt/qt/qt5qt.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
# make sure not to optimize imports on this file
|
||||||
|
# pylint: skip-file
|
||||||
|
|
||||||
|
"""
|
||||||
|
Compatibility shim for PyQt5.Qt
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from .qt5 import *
|
||||||
|
|
||||||
|
|
||||||
|
def __getattr__(name: str) -> Any:
|
||||||
|
return getattr(Qt, name) # type: ignore
|
20
qt/aqt/qt/qt6.py
Normal file
20
qt/aqt/qt/qt6.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
# make sure not to optimize imports on this file
|
||||||
|
# pylint: disable=unused-import
|
||||||
|
|
||||||
|
"""
|
||||||
|
PyQt6 imports
|
||||||
|
"""
|
||||||
|
|
||||||
|
from PyQt6 import sip
|
||||||
|
from PyQt6.QtCore import *
|
||||||
|
|
||||||
|
# conflicting Qt and qFuzzyCompare definitions require an ignore
|
||||||
|
from PyQt6.QtGui import * # type: ignore[misc]
|
||||||
|
from PyQt6.QtNetwork import QLocalServer, QLocalSocket, QNetworkProxy
|
||||||
|
from PyQt6.QtWebChannel import QWebChannel
|
||||||
|
from PyQt6.QtWebEngineCore import *
|
||||||
|
from PyQt6.QtWebEngineWidgets import *
|
||||||
|
from PyQt6.QtWidgets import *
|
@ -671,7 +671,7 @@ class RecordDialog(QDialog):
|
|||||||
namedtmp("rec.wav"), self.mw, self._parent
|
namedtmp("rec.wav"), self.mw, self._parent
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
from .qt5 import QtAudioInputRecorder as Qt5Recorder
|
from aqt.qt.qt5extra import QtAudioInputRecorder as Qt5Recorder
|
||||||
|
|
||||||
self._recorder = Qt5Recorder(namedtmp("rec.wav"), self.mw, self._parent)
|
self._recorder = Qt5Recorder(namedtmp("rec.wav"), self.mw, self._parent)
|
||||||
self._recorder.start(self._start_timer)
|
self._recorder.start(self._start_timer)
|
||||||
|
Loading…
Reference in New Issue
Block a user