qtpy
qtpy copied to clipboard
Missing `QUndoStack` import mapping (Qt5 `QtWidgets` vs Qt6 `QtGui` )
Have ran into an issue where I'm not getting expected imports from the expected module.
import qtpy
if qtpy.API_NAME in ("PyQt5", "PySide2"):
from qtpy.QtWidgets import QUndoStack
elif qtpy.API_NAME in ("PyQt6", "PySide6"):
from qtpy.QtGui import QUndoStack
else:
raise ValueError(f"Invalid QT_API: '{qtpy.API_NAME}'")
is this something qtpy could explain/fix?
I was going to create a new issue for each but it seems I have a bunch of small ones:
Issue 1:
self._proxyModel = QSortFilterProxyModel(self)
self._proxyModel.setSourceModel(self)
self._proxyModel.setRecursiveFilteringEnabled(True) # type: ignore[arg-type]
self._proxyModel.setFilterCaseSensitivity(False if qtpy.API_NAME in ("PyQt5", "PySide2") else QtCore.Qt.CaseInsensitive) # type: ignore[arg-type]
raises an exception and includes the phrase 'incorrect signature' in the message.
Issue 2:
if qtpy.API_NAME in ("PyQt6", "PySide6"):
...
else:
from qtpy.QtWidgets import QDesktopWidget
Would love to know the correct place to import QDesktopWidget from in the above?
Issue 3:
def SomeWindow(QMainWindow):
def __init__(*args, **kwargs):
if qtpy.API_NAME in {"PySide2", "PyQt5"}:
self.player.error.connect(lambda _=None: self.handleError())
else:
self.player.errorOccurred.connect(lambda *args, **kwargs: self.handleError(*args, **kwargs))
if qtpy.API_NAME in ["PyQt5", "PySide2"]:
# PyQt5 and PySide2 code path
from qtpy.QtMultimedia import QMediaContent
def set_media(data: bytes | None):
if data:
self.buffer = QBuffer(self)
self.buffer.setData(data)
self.buffer.open(QIODevice.ReadOnly)
self.player.setMedia(QMediaContent(), self.buffer)
QtCore.QTimer.singleShot(0, self.player.play)
else:
self.blinkWindow()
elif qtpy.API_NAME in ["PyQt6", "PySide6"]:
# PyQt6 and PySide6 code path
def set_media(data: bytes | None):
if data:
self.tempFile = NamedTemporaryFile(delete=False, suffix=".wav")
self.tempFile.write(data)
self.tempFile.close()
print(f"Wrote audioplayer audio data to '{self.tempFile.name}'")
self.player.setSource(QUrl.fromLocalFile(self.tempFile.name))
else:
self.blinkWindow()
Spent hours on this but I cannot figure out how to get the media player working correctly in qt6. Works fine in pyside2/pyqt5.
Issue 4:
if qtpy.API_NAME in ("PyQt6", "PySide6"):
from qtpy.QtCore import QRegularExpression as QRegExp
from qtpy.QtGui import QRegularExpressionValidator as QRegExpValidator
else:
from qtpy.QtCore import QRegExp
from qtpy.QtGui import QRegExpValidator
def resRefValidator(self) -> QRegExpValidator:
return QRegExpValidator(QRegExp(r"^[a-zA-Z0-9_]*$"))
I'm 70% certain there's a bigger change here than the names that is required. How exactly do I unify my use of q regex objects?
Hi @th3w1zard1 and sorry for such a late response! Regarding your initial compatibilty issue related with QUndoStack I would say adding over QtPy the missing import at
https://github.com/spyder-ide/qtpy/blob/0f7b181e45186b568551cf50078e5eeda05e3953/qtpy/QtWidgets.py#L37-L44
https://github.com/spyder-ide/qtpy/blob/0f7b181e45186b568551cf50078e5eeda05e3953/qtpy/QtWidgets.py#L113-L114
https://github.com/spyder-ide/qtpy/blob/0f7b181e45186b568551cf50078e5eeda05e3953/qtpy/QtGui.py#L54-L64
and at
https://github.com/spyder-ide/qtpy/blob/0f7b181e45186b568551cf50078e5eeda05e3953/qtpy/QtGui.py#L109-L119
should be enough to enable usage either by the Qt5 or Qt6 import syntax: from qtpy.QtWidgets import QUndoStack or from qtpy.QtGui import QUndoStack
Related with the other issues you mention, we would need to give a more in depth check to them but the one I know an answer already its issue 2 which basically is that QDesktopWidget was removed over Qt6 (it was marked as deprecated already over Qt5). For more info about alternatives for its functionality you can check https://doc.qt.io/qt-6/widgets-changes-qt6.html#qdesktopwidget-and-qapplication-desktop
Let us know if you would like to help with the QUndoStack import and if the info above helps!