Skip to content

Commit

Permalink
Merge pull request #21572 from ccordoba12/qt6_fixes
Browse files Browse the repository at this point in the history
PR: Initial fixes to make Spyder work with Qt 6
  • Loading branch information
ccordoba12 authored Dec 1, 2023
2 parents 404ee4b + bcc4cd0 commit e9172df
Show file tree
Hide file tree
Showing 33 changed files with 148 additions and 104 deletions.
2 changes: 1 addition & 1 deletion binder/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ dependencies:
- qstylizer >=0.2.2
- qtawesome >=1.2.1
- qtconsole >=5.5.0,<5.6.0
- qtpy >=2.1.0
- qtpy >=2.4.0
- rtree >=0.9.7
- setuptools >=49.6.0
- sphinx >=0.6.6
Expand Down
2 changes: 1 addition & 1 deletion requirements/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ dependencies:
- qstylizer >=0.2.2
- qtawesome >=1.2.1
- qtconsole >=5.5.0,<5.6.0
- qtpy >=2.1.0
- qtpy >=2.4.0
- rtree >=0.9.7
- setuptools >=49.6.0
- sphinx >=0.6.6
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def run(self):
'qstylizer>=0.2.2',
'qtawesome>=1.2.1',
'qtconsole>=5.5.0,<5.6.0',
'qtpy>=2.1.0',
'qtpy>=2.4.0',
'rtree>=0.9.7',
'setuptools>=49.6.0',
'sphinx>=0.6.6',
Expand Down
9 changes: 6 additions & 3 deletions spyder/app/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,11 @@ def __init__(self, splash=None, options=None):
# None is needed, see: https://bugreports.qt.io/browse/PYSIDE-922
self._proxy_style = SpyderProxyStyle(None)

# Enabling scaling for high dpi
qapp.setAttribute(Qt.AA_UseHighDpiPixmaps)
# Enabling scaling for high dpi. This is not required with Qt 6 where
# it is always enabled.
# See https://doc.qt.io/qt-6/portingguide.html#high-dpi
if hasattr(Qt, "AA_UseHighDpiPixmaps"):
qapp.setAttribute(Qt.AA_UseHighDpiPixmaps)

# Set Windows app icon to use .ico file
if os.name == "nt":
Expand Down Expand Up @@ -382,7 +385,7 @@ def show_plugin_compatibility_message(self, plugin_name, message):
messageBox.show()

# Center message
screen_geometry = QApplication.desktop().screenGeometry()
screen_geometry = self.screen().geometry()
x = (screen_geometry.width() - messageBox.width()) / 2
y = (screen_geometry.height() - messageBox.height()) / 2
messageBox.move(x, y)
Expand Down
11 changes: 8 additions & 3 deletions spyder/app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,23 @@ def set_opengl_implementation(option):
See spyder-ide/spyder#7447 for the details.
"""
if hasattr(QQuickWindow, "setGraphicsApi"):
set_api = QQuickWindow.setGraphicsApi # Qt 6
else:
set_api = QQuickWindow.setSceneGraphBackend # Qt 5

if option == 'software':
QCoreApplication.setAttribute(Qt.AA_UseSoftwareOpenGL)
if QQuickWindow is not None:
QQuickWindow.setSceneGraphBackend(QSGRendererInterface.Software)
set_api(QSGRendererInterface.GraphicsApi.Software)
elif option == 'desktop':
QCoreApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
if QQuickWindow is not None:
QQuickWindow.setSceneGraphBackend(QSGRendererInterface.OpenGL)
set_api(QSGRendererInterface.GraphicsApi.OpenGL)
elif option == 'gles':
QCoreApplication.setAttribute(Qt.AA_UseOpenGLES)
if QQuickWindow is not None:
QQuickWindow.setSceneGraphBackend(QSGRendererInterface.OpenGL)
set_api(QSGRendererInterface.GraphicsApi.OpenGL)


def setup_logging(cli_options):
Expand Down
6 changes: 3 additions & 3 deletions spyder/config/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

# Third party imports
from qtconsole.styles import dark_color
from qtpy import PYQT_VERSION
from qtpy import PYQT_VERSION, QT_VERSION
from qtpy.QtCore import Qt
from qtpy.QtGui import QFont, QFontDatabase, QKeySequence
from qtpy.QtWidgets import QShortcut
Expand All @@ -44,8 +44,8 @@

def font_is_installed(font):
"""Check if font is installed"""
return [fam for fam in QFontDatabase().families()
if to_text_string(fam)==font]
db = QFontDatabase() if QT_VERSION.startswith("5") else QFontDatabase
return [fam for fam in db.families() if str(fam) == font]


def get_family(families):
Expand Down
2 changes: 1 addition & 1 deletion spyder/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
QSTYLIZER_REQVER = '>=0.2.2'
QTAWESOME_REQVER = '>=1.2.1'
QTCONSOLE_REQVER = '>=5.5.0,<5.6.0'
QTPY_REQVER = '>=2.1.0'
QTPY_REQVER = '>=2.4.0'
RTREE_REQVER = '>=0.9.7'
SETUPTOOLS_REQVER = '>=49.6.0'
SPHINX_REQVER = '>=0.6.6'
Expand Down
4 changes: 2 additions & 2 deletions spyder/plugins/completion/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
# Third-party imports
from packaging.version import parse
from pkg_resources import iter_entry_points
from qtpy.QtCore import QMutex, QMutexLocker, QTimer, Slot, Signal
from qtpy.QtCore import QRecursiveMutex, QMutexLocker, QTimer, Slot, Signal

# Local imports
from spyder.config.manager import CONF
Expand Down Expand Up @@ -214,7 +214,7 @@ def __init__(self, parent, configuration=None):
self.req_id = 0

# Lock to prevent concurrent access to requests mapping
self.collection_mutex = QMutex(QMutex.Recursive)
self.collection_mutex = QRecursiveMutex()

# Completion request priority
self.source_priority = {}
Expand Down
8 changes: 4 additions & 4 deletions spyder/plugins/editor/extensions/tests/test_docstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ def test_editor_docstring_below_def_by_shortcut(qtbot, editor_auto_docstring,

cursor = editor.textCursor()
cursor.movePosition(QTextCursor.NextBlock)
cursor.setPosition(QTextCursor.End, QTextCursor.MoveAnchor)
cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor)
editor.setTextCursor(cursor)

editor.writer_docstring.write_docstring_for_shortcut()
Expand Down Expand Up @@ -376,7 +376,7 @@ def test_editor_docstring_delayed_popup(qtbot, editor_auto_docstring,

cursor = editor.textCursor()
cursor.movePosition(QTextCursor.NextBlock)
cursor.setPosition(QTextCursor.EndOfLine, QTextCursor.MoveAnchor)
cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.MoveAnchor)
editor.setTextCursor(cursor)

qtbot.keyPress(editor, Qt.Key_Space)
Expand Down Expand Up @@ -618,7 +618,7 @@ def test_docstring_annotated_call(editor_auto_docstring, text, expected):

cursor = editor.textCursor()
cursor.movePosition(QTextCursor.NextBlock)
cursor.setPosition(QTextCursor.End, QTextCursor.MoveAnchor)
cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor)
editor.setTextCursor(cursor)

editor.writer_docstring.write_docstring_for_shortcut()
Expand Down Expand Up @@ -659,7 +659,7 @@ def test_docstring_line_break(editor_auto_docstring, text, expected):

cursor = editor.textCursor()
cursor.movePosition(QTextCursor.NextBlock)
cursor.setPosition(QTextCursor.End, QTextCursor.MoveAnchor)
cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor)
editor.setTextCursor(cursor)

editor.writer_docstring.write_docstring_for_shortcut()
Expand Down
2 changes: 1 addition & 1 deletion spyder/plugins/editor/utils/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ def is_comment_or_string(self, cursor_or_block, formats=None):
pos = cursor_or_block.position() - b.position()
layout = b.layout()
if layout is not None:
additional_formats = layout.additionalFormats()
additional_formats = layout.formats()
sh = self._editor.syntax_highlighter
if sh:
ref_formats = sh.color_scheme.formats
Expand Down
3 changes: 1 addition & 2 deletions spyder/plugins/editor/widgets/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1193,8 +1193,7 @@ def wheelEvent(self, event):

def position_widget_at_cursor(self, widget):
# Retrieve current screen height
desktop = QApplication.desktop()
srect = desktop.availableGeometry(desktop.screenNumber(widget))
srect = self.screen().availableGeometry()

left, top, right, bottom = (srect.left(), srect.top(),
srect.right(), srect.bottom())
Expand Down
13 changes: 9 additions & 4 deletions spyder/plugins/editor/widgets/codeeditor/codeeditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
from packaging.version import parse
from qtpy import QT_VERSION
from qtpy.compat import to_qvariant
from qtpy.QtCore import QEvent, QRegExp, Qt, QTimer, QUrl, Signal, Slot
from qtpy.QtCore import (
QEvent, QRegularExpression, Qt, QTimer, QUrl, Signal, Slot)
from qtpy.QtGui import (QColor, QCursor, QFont, QKeySequence, QPaintEvent,
QPainter, QMouseEvent, QTextCursor, QDesktopServices,
QKeyEvent, QTextDocument, QTextFormat, QTextOption,
Expand Down Expand Up @@ -1291,15 +1292,19 @@ def __find_first(self, text):
cursor = self.textCursor()
# Scanning whole document
cursor.movePosition(QTextCursor.Start)
regexp = QRegExp(r"\b%s\b" % QRegExp.escape(text), Qt.CaseSensitive)
regexp = QRegularExpression(
r"\b%s\b" % QRegularExpression.escape(text)
)
cursor = self.document().find(regexp, cursor, flags)
self.__find_first_pos = cursor.position()
return cursor

def __find_next(self, text, cursor):
"""Find next occurrence"""
flags = QTextDocument.FindCaseSensitively|QTextDocument.FindWholeWords
regexp = QRegExp(r"\b%s\b" % QRegExp.escape(text), Qt.CaseSensitive)
regexp = QRegularExpression(
r"\b%s\b" % QRegularExpression.escape(text)
)
cursor = self.document().find(regexp, cursor, flags)
if cursor.position() != self.__find_first_pos:
return cursor
Expand Down Expand Up @@ -3082,7 +3087,7 @@ def __get_current_color(self, cursor=None):
block = cursor.block()
pos = cursor.position() - block.position() # relative pos within block
layout = block.layout()
block_formats = layout.additionalFormats()
block_formats = layout.formats()

if block_formats:
# To easily grab current format for autoinsert_colons
Expand Down
3 changes: 2 additions & 1 deletion spyder/plugins/editor/widgets/printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@

# TODO: Implement header and footer support
class SpyderPrinter(QPrinter):
def __init__(self, mode=QPrinter.ScreenResolution, header_font=None):
def __init__(self, mode=QPrinter.PrinterMode.ScreenResolution,
header_font=None):
QPrinter.__init__(self, mode)
self.setColorMode(QPrinter.Color)
self.setPageOrder(QPrinter.FirstPageFirst)
Expand Down
2 changes: 1 addition & 1 deletion spyder/plugins/editor/widgets/recover.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def add_cancel_button(self):

def center(self):
"""Center the dialog."""
screen = QApplication.desktop().screenGeometry(0)
screen = self.screen().geometry()
x = int(screen.center().x() - self.width() / 2)
y = int(screen.center().y() - self.height() / 2)
self.move(x, y)
Expand Down
6 changes: 3 additions & 3 deletions spyder/plugins/explorer/widgets/fileassociations.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

# Third party imports
from qtpy.compat import getopenfilename
from qtpy.QtCore import QRegExp, QSize, Qt, Signal, Slot
from qtpy.QtGui import QCursor, QRegExpValidator
from qtpy.QtCore import QRegularExpression, QSize, Qt, Signal, Slot
from qtpy.QtGui import QCursor, QRegularExpressionValidator
from qtpy.QtWidgets import (QApplication, QDialog, QDialogButtonBox,
QHBoxLayout, QLabel, QLineEdit,
QListWidget, QListWidgetItem, QPushButton,
Expand Down Expand Up @@ -83,7 +83,7 @@ def set_regex_validation(self, regex):
"""Set the regular expression to validate content."""
self._regex = regex
self._reg = re.compile(regex, re.IGNORECASE)
validator = QRegExpValidator(QRegExp(regex))
validator = QRegularExpressionValidator(QRegularExpression(regex))
self.lineedit.setValidator(validator)

def text(self):
Expand Down
10 changes: 3 additions & 7 deletions spyder/plugins/layout/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# Third party imports
from qtpy.QtCore import Qt, QByteArray, QSize, QPoint, Slot
from qtpy.QtGui import QIcon
from qtpy.QtWidgets import QApplication, QDesktopWidget
from qtpy.QtWidgets import QApplication

# Local imports
from spyder.api.exceptions import SpyderAPIError
Expand Down Expand Up @@ -489,7 +489,7 @@ def load_window_settings(self, prefix, default=False, section='main'):
# with the current screen. See spyder-ide/spyder#3748.
width = pos[0]
height = pos[1]
screen_shape = QApplication.desktop().geometry()
screen_shape = self.main.screen().geometry()
current_width = screen_shape.width()
current_height = screen_shape.height()
if current_width < width or current_height < height:
Expand Down Expand Up @@ -856,11 +856,7 @@ def toggle_fullscreen(self):
| Qt.FramelessWindowHint
| Qt.WindowStaysOnTopHint)

screen_number = QDesktopWidget().screenNumber(main)
if screen_number < 0:
screen_number = 0

r = QApplication.desktop().screenGeometry(screen_number)
r = main.screen().geometry()
main.setGeometry(
r.left() - 1, r.top() - 1, r.width() + 2, r.height() + 2)
main.showNormal()
Expand Down
12 changes: 6 additions & 6 deletions spyder/plugins/layout/widgets/dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,16 @@ def flags(self, index):
ui_name, name, state = self.row(row)

if name in self.read_only:
return Qt.NoItemFlags
return Qt.ItemFlag(0)
if not index.isValid():
return Qt.ItemIsEnabled
return Qt.ItemFlag.ItemIsEnabled
column = index.column()
if column in [0]:
return Qt.ItemFlags(int(Qt.ItemIsEnabled | Qt.ItemIsSelectable |
Qt.ItemIsUserCheckable |
Qt.ItemIsEditable))
return (Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable |
Qt.ItemFlag.ItemIsUserCheckable |
Qt.ItemFlag.ItemIsEditable)
else:
return Qt.ItemFlags(Qt.ItemIsEnabled)
return Qt.ItemFlag.ItemIsEnabled

def data(self, index, role=Qt.DisplayRole):
"""Override Qt method"""
Expand Down
8 changes: 5 additions & 3 deletions spyder/plugins/preferences/widgets/config_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
from qtpy import API
from qtpy.compat import (getexistingdirectory, getopenfilename, from_qvariant,
to_qvariant)
from qtpy.QtCore import Qt, Signal, Slot, QRegExp, QSize
from qtpy.QtGui import QColor, QRegExpValidator, QTextOption
from qtpy.QtCore import Qt, Signal, Slot, QRegularExpression, QSize
from qtpy.QtGui import QColor, QRegularExpressionValidator, QTextOption
from qtpy.QtWidgets import (QButtonGroup, QCheckBox, QComboBox, QDoubleSpinBox,
QFileDialog, QFontComboBox, QGridLayout, QGroupBox,
QHBoxLayout, QLabel, QLineEdit, QMessageBox,
Expand Down Expand Up @@ -550,7 +550,9 @@ def create_lineedit(self, text, option, default=NoDefault,
layout.addWidget(edit)
layout.setContentsMargins(0, 0, 0, 0)
if regex:
edit.setValidator(QRegExpValidator(QRegExp(regex)))
edit.setValidator(
QRegularExpressionValidator(QRegularExpression(regex))
)
if placeholder:
edit.setPlaceholderText(placeholder)
self.lineedits[edit] = (section, option, default)
Expand Down
6 changes: 2 additions & 4 deletions spyder/plugins/shortcuts/widgets/summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
from qtpy.QtCore import Qt
from qtpy.QtGui import QFont, QKeySequence
from qtpy.QtWidgets import (QDialog, QLabel, QGridLayout, QGroupBox,
QVBoxLayout, QHBoxLayout, QDesktopWidget,
QScrollArea, QWidget)
QVBoxLayout, QHBoxLayout, QScrollArea, QWidget)

# Local imports
from spyder.config.base import _
Expand Down Expand Up @@ -148,8 +147,7 @@ def __init__(self, parent=None):

def get_screen_resolution(self):
"""Return the screen resolution of the primary screen."""
widget = QDesktopWidget()
geometry = widget.availableGeometry(widget.primaryScreen())
geometry = self.screen().availableGeometry()
return geometry.width(), geometry.height()


Expand Down
12 changes: 6 additions & 6 deletions spyder/plugins/shortcuts/widgets/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
# Third party imports
from qtpy.compat import from_qvariant, to_qvariant
from qtpy.QtCore import (QAbstractTableModel, QEvent, QModelIndex,
QSortFilterProxyModel, Qt, Slot, QRegExp)
from qtpy.QtGui import QIcon, QKeySequence, QRegExpValidator
QSortFilterProxyModel, Qt, Slot, QRegularExpression)
from qtpy.QtGui import QIcon, QKeySequence, QRegularExpressionValidator
from qtpy.QtWidgets import (QAbstractItemView, QApplication, QDialog,
QGridLayout, QHBoxLayout, QKeySequenceEdit,
QLabel, QLineEdit, QMessageBox, QPushButton,
Expand Down Expand Up @@ -119,8 +119,8 @@ def __init__(self, parent, callback=None, main=None,
self.main = main

# Widget setup
regex = QRegExp(regex_base + "{100}")
self.setValidator(QRegExpValidator(regex))
regex = QRegularExpression(regex_base + "{100}")
self.setValidator(QRegularExpressionValidator(regex))

# Signals
if callback:
Expand Down Expand Up @@ -532,8 +532,8 @@ def sortByName(self):
def flags(self, index):
"""Qt Override."""
if not index.isValid():
return Qt.ItemIsEnabled
return Qt.ItemFlags(int(QAbstractTableModel.flags(self, index)))
return Qt.ItemFlag.ItemIsEnabled
return QAbstractTableModel.flags(self, index)

def data(self, index, role=Qt.DisplayRole):
"""Qt Override."""
Expand Down
Loading

0 comments on commit e9172df

Please sign in to comment.