mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 06:22:22 -04:00
miscellaneous pyqt6 compat fixes
- add a few gates for qt5-specific behaviour - prepare for some changes to the typings in qt6 - map pickled Qt5 ByteArrays to Qt6 when running Qt6
This commit is contained in:
parent
4d0a915610
commit
dfcefaebe3
9 changed files with 44 additions and 29 deletions
|
@ -372,8 +372,6 @@ def setupGL(pm: aqt.profiles.ProfileManager) -> None:
|
||||||
category = "debug"
|
category = "debug"
|
||||||
elif category == QtFatalMsg:
|
elif category == QtFatalMsg:
|
||||||
category = "fatal"
|
category = "fatal"
|
||||||
elif category == QtSystemMsg:
|
|
||||||
category = "system"
|
|
||||||
else:
|
else:
|
||||||
category = "unknown"
|
category = "unknown"
|
||||||
context = ""
|
context = ""
|
||||||
|
|
|
@ -1032,7 +1032,7 @@ title="{}" {}>{}</button>""".format(
|
||||||
|
|
||||||
def clearStateShortcuts(self) -> None:
|
def clearStateShortcuts(self) -> None:
|
||||||
for qs in self.stateShortcuts:
|
for qs in self.stateShortcuts:
|
||||||
sip.delete(qs)
|
sip.delete(qs) # type: ignore
|
||||||
self.stateShortcuts = []
|
self.stateShortcuts = []
|
||||||
|
|
||||||
def onStudyKey(self) -> None:
|
def onStudyKey(self) -> None:
|
||||||
|
|
|
@ -163,25 +163,32 @@ class ProfileManager:
|
||||||
|
|
||||||
def _unpickle(self, data: bytes) -> Any:
|
def _unpickle(self, data: bytes) -> Any:
|
||||||
class Unpickler(pickle.Unpickler):
|
class Unpickler(pickle.Unpickler):
|
||||||
def find_class(self, module: str, name: str) -> Any:
|
def find_class(self, class_module: str, name: str) -> Any:
|
||||||
if module == "PyQt5.sip":
|
# handle sip lookup ourselves, mapping to current Qt version
|
||||||
try:
|
if class_module == "sip" or class_module.endswith(".sip"):
|
||||||
import PyQt5.sip # pylint: disable=unused-import
|
|
||||||
except:
|
|
||||||
# use old sip location
|
|
||||||
module = "sip"
|
|
||||||
fn = super().find_class(module, name)
|
|
||||||
if module == "sip" and name == "_unpickle_type":
|
|
||||||
|
|
||||||
def wrapper(mod, obj, args) -> Any: # type: ignore
|
def unpickle_type(module: str, klass: str, args: Any) -> Any:
|
||||||
if mod.startswith("PyQt4") and obj == "QByteArray":
|
if qtmajor > 5:
|
||||||
|
module = module.replace("Qt5", "Qt6")
|
||||||
|
else:
|
||||||
|
module = module.replace("Qt6", "Qt5")
|
||||||
|
if klass == "QByteArray":
|
||||||
|
if module.startswith("PyQt4"):
|
||||||
# can't trust str objects from python 2
|
# can't trust str objects from python 2
|
||||||
return QByteArray()
|
return QByteArray()
|
||||||
return fn(mod, obj, args)
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
else:
|
else:
|
||||||
return fn
|
# return the bytes directly
|
||||||
|
return args[0]
|
||||||
|
elif name == "_unpickle_enum":
|
||||||
|
if qtmajor == 5:
|
||||||
|
return sip._unpickle_enum(module, klass, args) # type: ignore
|
||||||
|
else:
|
||||||
|
# old style enums can't be unpickled
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return sip._unpickle_type(module, klass, args) # type: ignore
|
||||||
|
|
||||||
|
return unpickle_type
|
||||||
|
|
||||||
up = Unpickler(io.BytesIO(data), errors="ignore")
|
up = Unpickler(io.BytesIO(data), errors="ignore")
|
||||||
return up.load()
|
return up.load()
|
||||||
|
|
|
@ -57,6 +57,9 @@ if qtmajor < 5 or (qtmajor == 5 and qtminor < 14):
|
||||||
raise Exception("Anki does not support your Qt version.")
|
raise Exception("Anki does not support your Qt version.")
|
||||||
|
|
||||||
|
|
||||||
def qconnect(signal: Union[Callable, pyqtSignal], func: Callable) -> None:
|
def qconnect(
|
||||||
"Helper to work around type checking not working with signal.connect(func)."
|
signal: Union[Callable, pyqtSignal, pyqtBoundSignal], func: Callable
|
||||||
|
) -> None:
|
||||||
|
"""Helper to work around type checking not working with signal.connect(func).
|
||||||
|
Not needed in PyQt6"""
|
||||||
signal.connect(func) # type: ignore
|
signal.connect(func) # type: ignore
|
||||||
|
|
|
@ -23,7 +23,11 @@ class QtAudioInputRecorder(Recorder):
|
||||||
self.mw = mw
|
self.mw = mw
|
||||||
self._parent = parent
|
self._parent = parent
|
||||||
|
|
||||||
from PyQt5.QtMultimedia import QAudioDeviceInfo, QAudioFormat, QAudioInput
|
from PyQt5.QtMultimedia import ( # type: ignore
|
||||||
|
QAudioDeviceInfo,
|
||||||
|
QAudioFormat,
|
||||||
|
QAudioInput,
|
||||||
|
)
|
||||||
|
|
||||||
format = QAudioFormat()
|
format = QAudioFormat()
|
||||||
format.setChannelCount(1)
|
format.setChannelCount(1)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# Copyright: Ankitects Pty Ltd and contributors
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
from typing import cast
|
||||||
|
|
||||||
from aqt import colors
|
from aqt import colors
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
|
@ -128,7 +129,7 @@ class Switch(QAbstractButton):
|
||||||
self._animate_toggle()
|
self._animate_toggle()
|
||||||
|
|
||||||
def _animate_toggle(self) -> None:
|
def _animate_toggle(self) -> None:
|
||||||
animation = QPropertyAnimation(self, b"position", self)
|
animation = QPropertyAnimation(self, cast(QByteArray, b"position"), self)
|
||||||
animation.setDuration(100)
|
animation.setDuration(100)
|
||||||
animation.setStartValue(self.start_position)
|
animation.setStartValue(self.start_position)
|
||||||
animation.setEndValue(self.end_position)
|
animation.setEndValue(self.end_position)
|
||||||
|
|
|
@ -99,7 +99,7 @@ class TagEdit(QLineEdit):
|
||||||
self._completer.popup().hide()
|
self._completer.popup().hide()
|
||||||
|
|
||||||
def hideCompleter(self) -> None:
|
def hideCompleter(self) -> None:
|
||||||
if sip.isdeleted(self._completer):
|
if sip.isdeleted(self._completer): # type: ignore
|
||||||
return
|
return
|
||||||
self._completer.popup().hide()
|
self._completer.popup().hide()
|
||||||
|
|
||||||
|
|
|
@ -866,6 +866,8 @@ Add-ons, last update check: {}
|
||||||
|
|
||||||
# adapted from version detection in qutebrowser
|
# adapted from version detection in qutebrowser
|
||||||
def opengl_vendor() -> str | None:
|
def opengl_vendor() -> str | None:
|
||||||
|
if qtmajor != 5:
|
||||||
|
return "unknown"
|
||||||
old_context = QOpenGLContext.currentContext()
|
old_context = QOpenGLContext.currentContext()
|
||||||
old_surface = None if old_context is None else old_context.surface()
|
old_surface = None if old_context is None else old_context.surface()
|
||||||
|
|
||||||
|
@ -886,11 +888,11 @@ def opengl_vendor() -> str | None:
|
||||||
# Can't use versionFunctions there
|
# Can't use versionFunctions there
|
||||||
return None
|
return None
|
||||||
|
|
||||||
vp = QOpenGLVersionProfile()
|
vp = QOpenGLVersionProfile() # type: ignore
|
||||||
vp.setVersion(2, 0)
|
vp.setVersion(2, 0)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
vf = ctx.versionFunctions(vp)
|
vf = ctx.versionFunctions(vp) # type: ignore
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -350,9 +350,9 @@ class AnkiWebView(QWebEngineView):
|
||||||
if webscale:
|
if webscale:
|
||||||
return float(webscale)
|
return float(webscale)
|
||||||
|
|
||||||
if isMac:
|
if qtmajor > 5 or isMac:
|
||||||
return 1
|
return 1
|
||||||
screen = QApplication.desktop().screen()
|
screen = QApplication.desktop().screen() # type: ignore
|
||||||
if screen is None:
|
if screen is None:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue