Skip to content

Commit ef853cc

Browse files
committed
Qt6 support
- QRegExp fixes for Qt6 - Convert CodeHighlighter from QRegExp to python regex
1 parent 618b0ab commit ef853cc

File tree

11 files changed

+71
-55
lines changed

11 files changed

+71
-55
lines changed

preditor/about_module.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,14 @@ def text(self):
116116
pass
117117

118118
# Add info for all Qt5 bindings that have been imported
119-
if 'PyQt5.QtCore' in sys.modules:
120-
ret.append('PyQt5: {}'.format(sys.modules['PyQt5.QtCore'].PYQT_VERSION_STR))
119+
if 'PySide6.QtCore' in sys.modules:
120+
ret.append('PySide6: {}'.format(sys.modules['PySide6.QtCore'].qVersion()))
121+
if 'PyQt6.QtCore' in sys.modules:
122+
ret.append('PyQt6: {}'.format(sys.modules['PyQt6.QtCore'].PYQT_VERSION_STR))
121123
if 'PySide2.QtCore' in sys.modules:
122124
ret.append('PySide2: {}'.format(sys.modules['PySide2.QtCore'].qVersion()))
125+
if 'PyQt5.QtCore' in sys.modules:
126+
ret.append('PyQt5: {}'.format(sys.modules['PyQt5.QtCore'].PYQT_VERSION_STR))
123127

124128
# Add qt library paths for plugin debugging
125129
for i, path in enumerate(QtCore.QCoreApplication.libraryPaths()):

preditor/gui/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def dpi_awareness_args(cls):
9393
Returns:
9494
args: Extend the arguments used to intialize the QApplication.
9595
"""
96-
if settings.OS_TYPE == "Windows" and Qt.IsPyQt5:
96+
if settings.OS_TYPE == "Windows" and (Qt.IsPyQt6 or Qt.IsPyQt5):
9797
# Make Qt automatically scale based on the monitor the window is
9898
# currently located.
9999
return ["--platform", "windows:dpiawareness=0"]
@@ -156,4 +156,4 @@ def start(self):
156156
"""Exec's the QApplication if it hasn't already been started."""
157157
if self.app_created and self.app and not self.app_has_exec:
158158
self.app_has_exec = True
159-
self.app.exec_()
159+
Qt.QtCompat.QApplication.exec_()

preditor/gui/codehighlighter.py

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import os
55
import re
66

7-
from Qt.QtCore import QRegExp
87
from Qt.QtGui import QColor, QSyntaxHighlighter, QTextCharFormat
98

109
from .. import resourcePath
@@ -68,59 +67,46 @@ def highlightBlock(self, text):
6867
if parent and hasattr(parent, 'outputPrompt'):
6968
self.highlightText(
7069
text,
71-
QRegExp('%s[^\\n]*' % re.escape(parent.outputPrompt())),
70+
re.compile('%s[^\\n]*' % re.escape(parent.outputPrompt())),
7271
format,
7372
)
7473

7574
# format the keywords
7675
format = self.keywordFormat()
7776
for kwd in self._keywords:
78-
self.highlightText(text, QRegExp(r'\b%s\b' % kwd), format)
77+
self.highlightText(text, re.compile(r'\b%s\b' % kwd), format)
7978

8079
# format the strings
8180
format = self.stringFormat()
81+
8282
for string in self._strings:
8383
self.highlightText(
8484
text,
85-
QRegExp('%s[^%s]*' % (string, string)),
85+
re.compile('{s}[^{s}]*{s}'.format(s=string)),
8686
format,
87-
includeLast=True,
8887
)
8988

9089
# format the comments
9190
format = self.commentFormat()
9291
for comment in self._comments:
93-
self.highlightText(text, QRegExp(comment), format)
92+
self.highlightText(text, re.compile(comment), format)
9493

9594
def highlightText(self, text, expr, format, offset=0, includeLast=False):
9695
"""Highlights a text group with an expression and format
9796
9897
Args:
9998
text (str): text to highlight
100-
expr (QRegExp): search parameter
99+
expr (QRegularExpression): search parameter
101100
format (QTextCharFormat): formatting rule
102-
offset (int): number of characters to offset by when highlighting
103101
includeLast (bool): whether or not the last character should be highlighted
104102
"""
105-
pos = expr.indexIn(text, 0)
106-
107103
# highlight all the given matches to the expression in the text
108-
while pos != -1:
109-
pos = expr.pos(offset)
110-
length = len(expr.cap(offset))
111-
112-
# use the last character if desired
104+
for match in expr.finditer(text):
105+
start, end = match.span()
106+
length = end - start
113107
if includeLast:
114108
length += 1
115-
116-
# set the formatting
117-
self.setFormat(pos, length, format)
118-
119-
matched = expr.matchedLength()
120-
if includeLast:
121-
matched += 1
122-
123-
pos = expr.indexIn(text, pos + matched)
109+
self.setFormat(start, length, format)
124110

125111
def keywordColor(self):
126112
# pull the color from the parent if possible because this doesn't support

preditor/gui/completer.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import sys
66
from enum import Enum
77

8+
import Qt as Qt_py
89
from Qt.QtCore import QRegExp, QSortFilterProxyModel, QStringListModel, Qt
910
from Qt.QtGui import QCursor, QTextCursor
1011
from Qt.QtWidgets import QCompleter, QToolTip
@@ -155,8 +156,14 @@ def refreshList(self, scope=None):
155156
if self._completerMode == CompleterMode.FULL_FUZZY:
156157
regExStr = ".*".join(prefix)
157158

158-
regexp = QRegExp(regExStr, self._sensitivity)
159-
self.filterModel.setFilterRegExp(regexp)
159+
if Qt_py.IsPyQt6 or Qt_py.IsPySide6:
160+
regexp = QRegExp(regExStr)
161+
if self._sensitivity:
162+
regexp.setPatternOptions(QRegExp.PatternOption.CaseInsensitiveOption)
163+
self.filterModel.setFilterRegularExpression(regexp)
164+
else:
165+
regexp = QRegExp(regExStr, self._sensitivity)
166+
self.filterModel.setFilterRegExp(regexp)
160167

161168
def clear(self):
162169
self.popup().hide()

preditor/gui/console.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@
1515
import __main__
1616
from Qt import QtCompat
1717
from Qt.QtCore import QPoint, Qt, QTimer
18-
from Qt.QtGui import QColor, QFontMetrics, QTextCharFormat, QTextCursor, QTextDocument
18+
from Qt.QtGui import (
19+
QColor,
20+
QFontMetrics,
21+
QKeySequence,
22+
QTextCharFormat,
23+
QTextCursor,
24+
QTextDocument,
25+
)
1926
from Qt.QtWidgets import QAbstractItemView, QAction, QApplication, QTextEdit
2027

2128
from .. import debug, settings, stream
@@ -99,7 +106,9 @@ def __init__(self, parent):
99106

100107
self.uiClearToLastPromptACT = QAction('Clear to Last', self)
101108
self.uiClearToLastPromptACT.triggered.connect(self.clearToLastPrompt)
102-
self.uiClearToLastPromptACT.setShortcut(Qt.CTRL | Qt.SHIFT | Qt.Key_Backspace)
109+
self.uiClearToLastPromptACT.setShortcut(
110+
QKeySequence(Qt.Modifier.CTRL | Qt.Modifier.SHIFT | Qt.Key.Key_Backspace)
111+
)
103112
self.addAction(self.uiClearToLastPromptACT)
104113

105114
self.x = 0
@@ -155,8 +164,8 @@ def setConsoleFont(self, font):
155164
workbox = self.window().current_workbox()
156165
if workbox:
157166
tab_width = workbox.__tab_width__()
158-
fontPixelWidth = QFontMetrics(font).width(" ")
159-
self.setTabStopWidth(fontPixelWidth * tab_width)
167+
fontPixelWidth = QFontMetrics(font).horizontalAdvance(" ")
168+
self.setTabStopDistance(fontPixelWidth * tab_width)
160169

161170
# Scroll to same relative position where we started
162171
if origPercent is not None:

preditor/gui/loggerwindow.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,18 @@
1111
from functools import partial
1212

1313
import __main__
14+
import Qt as Qt_py
1415
import six
1516
from Qt import QtCompat, QtCore, QtWidgets
1617
from Qt.QtCore import QByteArray, Qt, QTimer, Signal, Slot
17-
from Qt.QtGui import QCursor, QFont, QIcon, QTextCursor
18+
from Qt.QtGui import QCursor, QFont, QIcon, QKeySequence, QTextCursor
1819
from Qt.QtWidgets import (
1920
QApplication,
2021
QFontDialog,
2122
QInputDialog,
2223
QMessageBox,
2324
QTextBrowser,
25+
QTextEdit,
2426
QToolTip,
2527
QVBoxLayout,
2628
)
@@ -172,7 +174,7 @@ def __init__(self, parent, name=None, run_workbox=False, standalone=False):
172174
self.uiCompleterModeMENU.addSeparator()
173175
action = self.uiCompleterModeMENU.addAction('Cycle mode')
174176
action.setObjectName('uiCycleModeACT')
175-
action.setShortcut(Qt.CTRL | Qt.Key_M)
177+
action.setShortcut(QKeySequence(Qt.Modifier.CTRL | Qt.Key.Key_M))
176178
action.triggered.connect(self.cycleCompleterMode)
177179
self.uiCompleterModeMENU.hovered.connect(self.handleMenuHovered)
178180

@@ -542,7 +544,10 @@ def handleMenuHovered(self, action):
542544
else:
543545
text = action.toolTip()
544546

545-
menu = action.parentWidget()
547+
if Qt_py.IsPyQt4:
548+
menu = action.parentWidget()
549+
else:
550+
menu = action.parent()
546551
QToolTip.showText(QCursor.pos(), text, menu)
547552

548553
def selectFont(self, monospace=False, proportional=False):
@@ -722,7 +727,7 @@ def recordPrefs(self, manual=False):
722727
pref.update(
723728
{
724729
'loggergeom': [geo.x(), geo.y(), geo.width(), geo.height()],
725-
'windowState': int(self.windowState()),
730+
'windowState': QtCompat.enumValue(self.windowState()),
726731
'SplitterVertical': self.uiEditorVerticalACT.isChecked(),
727732
'SplitterSize': self.uiSplitterSPLIT.sizes(),
728733
'tabIndent': self.uiIndentationsTabsACT.isChecked(),
@@ -846,7 +851,7 @@ def restorePrefs(self):
846851
sizes = pref.get('SplitterSize')
847852
if sizes:
848853
self.uiSplitterSPLIT.setSizes(sizes)
849-
self.setWindowState(Qt.WindowStates(pref.get('windowState', 0)))
854+
self.setWindowState(Qt.WindowState(pref.get('windowState', 0)))
850855
self.uiIndentationsTabsACT.setChecked(pref.get('tabIndent', True))
851856
self.uiCopyTabsToSpacesACT.setChecked(pref.get('copyIndentsAsSpaces', False))
852857

@@ -919,7 +924,7 @@ def restorePrefs(self):
919924
_font = pref.get('consoleFont', None)
920925
if _font:
921926
font = QFont()
922-
if font.fromString(_font):
927+
if QtCompat.QFont.fromString(font, _font):
923928
self.console().setConsoleFont(font)
924929

925930
self.dont_ask_again = pref.get('dont_ask_again', [])
@@ -1098,9 +1103,9 @@ def setFlashWindowInterval(self):
10981103

10991104
def setWordWrap(self, state):
11001105
if state:
1101-
self.uiConsoleTXT.setLineWrapMode(self.uiConsoleTXT.WidgetWidth)
1106+
self.uiConsoleTXT.setLineWrapMode(QTextEdit.WidgetWidth)
11021107
else:
1103-
self.uiConsoleTXT.setLineWrapMode(self.uiConsoleTXT.NoWrap)
1108+
self.uiConsoleTXT.setLineWrapMode(QTextEdit.NoWrap)
11041109

11051110
def show_about(self):
11061111
"""Shows `preditor.about_preditor()`'s output in a message box."""

preditor/gui/workbox_text_edit.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def __font__(self):
6464

6565
def __set_font__(self, font):
6666
metrics = QFontMetrics(font)
67-
self.setTabStopDistance(metrics.width(" ") * 4)
67+
self.setTabStopDistance(metrics.horizontalAdvance(" ") * 4)
6868
super(WorkboxTextEdit, self).setFont(font)
6969

7070
def __goto_line__(self, line):

preditor/gui/workboxwidget.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,13 @@ def keyPressEvent(self, event):
216216
when Return is pressed), so this combination is not detectable.
217217
"""
218218
if self._software == 'softimage':
219-
DocumentEditor.keyPressEvent(self, event)
219+
super(WorkboxWidget, self).keyPressEvent(event)
220220
else:
221221
if self.process_shortcut(event):
222222
return
223223
else:
224224
# Send regular keystroke
225-
DocumentEditor.keyPressEvent(self, event)
225+
super(WorkboxWidget, self).keyPressEvent(event)
226226

227227
def initShortcuts(self):
228228
"""Use this to set up shortcuts when the DocumentEditor"""

preditor/scintilla/delayables/smart_highlight.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import absolute_import, print_function
22

3+
import Qt
34
from PyQt5.Qsci import QsciScintilla
45
from Qt.QtCore import QSignalMapper
56
from Qt.QtWidgets import QWidget
@@ -36,7 +37,10 @@ def add_document(self, document):
3637
)
3738

3839
self.signal_mapper.setMapping(document, document)
39-
self.signal_mapper.mapped[QWidget].connect(self.update_highlighter)
40+
if Qt.IsPyQt4:
41+
self.signal_mapper.mapped[QWidget].connect(self.update_highlighter)
42+
else:
43+
self.signal_mapper.mappedObject.connect(self.update_highlighter)
4044
document.selectionChanged.connect(self.signal_mapper.map)
4145

4246
def clear_markings(self, document):

preditor/scintilla/documenteditor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,7 @@ def saveAs(self, filename='', setFilename=True):
11011101
self.window(),
11021102
'Error saving file...',
11031103
'There was a error saving the file. Error Code: %i' % f.error(),
1104-
QMessageBox.Ok,
1104+
QMessageBox.StandardButton.Ok,
11051105
)
11061106
f.close()
11071107
return False

0 commit comments

Comments
 (0)