diff --git a/nxt_editor/__init__.py b/nxt_editor/__init__.py index cf2523c..0a516d8 100644 --- a/nxt_editor/__init__.py +++ b/nxt_editor/__init__.py @@ -36,9 +36,9 @@ class StringSignaler(QtCore.QObject): def make_resources(qrc_path=None, result_path=None): - import PySide2 - pyside_dir = os.path.dirname(PySide2.__file__) - full_pyside2rcc_path = os.path.join(pyside_dir, 'pyside2-rcc') + import PySide6 + import subprocess + pyside_dir = os.path.dirname(PySide6.__file__) full_rcc_path = os.path.join(pyside_dir, 'rcc') this_dir = os.path.dirname(os.path.realpath(__file__)) if not qrc_path: @@ -47,24 +47,15 @@ def make_resources(qrc_path=None, result_path=None): result_path = os.path.join(this_dir, 'qresources.py') msg = 'First launch nxt resource generation from {} to {}' logger.info(msg.format(qrc_path, result_path)) - import subprocess - ver = ['-py2'] - if sys.version_info[0] == 3: - ver += ['-py3'] - args = [qrc_path] + ver + ['-o', result_path] - try: - subprocess.check_call(['pyside2-rcc'] + args) - except: - pass - else: - return + args = [qrc_path, '-o', result_path] try: - subprocess.check_call([full_pyside2rcc_path] + args) + subprocess.check_call(['rcc'] + args) except: pass else: return + try: subprocess.check_call([full_rcc_path, '-g', 'python', qrc_path, '-o', result_path], cwd=pyside_dir) @@ -77,7 +68,7 @@ def make_resources(qrc_path=None, result_path=None): '-o', result_path], cwd=pyside_dir) except: raise Exception("Failed to generate UI resources using pyside2 rcc!" - " Reinstalling pyside2 may fix the problem. If you " + " Reinstalling PySide6 may fix the problem. If you " "know how to use rcc please build from: \"{}\" and " "output to \"{}\"".format(qrc_path, result_path)) else: @@ -129,9 +120,12 @@ def launch_editor(paths=None, start_rpc=True): def show_new_editor(paths=None, start_rpc=True): path = None - if paths is not None: + if paths and isinstance(paths, list): path = paths[0] paths.pop(0) + elif isinstance(paths, str): + path = paths + paths = [] else: paths = [] # Deferred import since main window relies on us diff --git a/nxt_editor/dialogs.py b/nxt_editor/dialogs.py index c6653bc..998edaa 100644 --- a/nxt_editor/dialogs.py +++ b/nxt_editor/dialogs.py @@ -297,7 +297,7 @@ def build_widgets(self): self.save_details_button.released.connect(self.on_save_details) self.detail_buttons_layout = QtWidgets.QHBoxLayout() - self.detail_buttons_layout.addStretch(streth=1) + self.detail_buttons_layout.addStretch(1) self.detail_buttons_layout.addWidget(self.save_details_button) self.detail_buttons_layout.addWidget(self.copy_details_button) @@ -314,7 +314,7 @@ def build_widgets(self): self.top_right_layout = QtWidgets.QVBoxLayout() self.top_right_layout.addWidget(self.text_label) self.top_right_layout.addWidget(self.info_label) - self.top_right_layout.addStretch(streth=1) + self.top_right_layout.addStretch(1) self.top_right_layout.addLayout(self.buttons_layout) self.top_layout = QtWidgets.QHBoxLayout() self.top_layout.addWidget(self.icon) diff --git a/nxt_editor/dockwidgets/build_view.py b/nxt_editor/dockwidgets/build_view.py index 3d21643..768e214 100644 --- a/nxt_editor/dockwidgets/build_view.py +++ b/nxt_editor/dockwidgets/build_view.py @@ -315,7 +315,7 @@ class BuildTable(QtWidgets.QTableView): """ def __init__(self): super(BuildTable, self).__init__() - self.setSelectionMode(self.NoSelection) + self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) self.horizontalHeader().hide() self.verticalHeader().hide() self.break_delegate = LetterCheckboxDelegeate('B') @@ -342,7 +342,7 @@ def setModel(self, model): header = self.horizontalHeader() header.setStretchLastSection(False) header.setDefaultSectionSize(28) - header.setSectionResizeMode(header.Fixed) + header.setSectionResizeMode(QtWidgets.QHeaderView.Fixed) if header.count(): column = BuildModel.PATH_COLUMN header.setSectionResizeMode(column, QtWidgets.QHeaderView.Stretch) diff --git a/nxt_editor/dockwidgets/code_editor.py b/nxt_editor/dockwidgets/code_editor.py index 0005dda..307a18c 100644 --- a/nxt_editor/dockwidgets/code_editor.py +++ b/nxt_editor/dockwidgets/code_editor.py @@ -1271,7 +1271,7 @@ def paintEvent(self, event): def get_width(self): count = self.editor.blockCount() - width = self.fontMetrics().width(str(count)) + 10 + width = self.fontMetrics().horizontalAdvance(str(count)) + 10 return width def update_width(self): diff --git a/nxt_editor/dockwidgets/find_rep.py b/nxt_editor/dockwidgets/find_rep.py index bd94f67..23aaa9c 100644 --- a/nxt_editor/dockwidgets/find_rep.py +++ b/nxt_editor/dockwidgets/find_rep.py @@ -196,7 +196,7 @@ def setModel(self, model): super(SearchResultsTree, self).setModel(model) header = self.header() header.setStretchLastSection(False) - header.setSectionResizeMode(header.ResizeToContents) + header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) if self.model(): self.model().modelReset.connect(self.expandAll) diff --git a/nxt_editor/dockwidgets/layer_manager.py b/nxt_editor/dockwidgets/layer_manager.py index c65c9a1..0800400 100644 --- a/nxt_editor/dockwidgets/layer_manager.py +++ b/nxt_editor/dockwidgets/layer_manager.py @@ -100,7 +100,7 @@ def setModel(self, model): header = self.header() header.setStretchLastSection(False) header.setDefaultSectionSize(LayerTreeView.SIZE) - header.setSectionResizeMode(header.Fixed) + header.setSectionResizeMode(QtWidgets.QHeaderView.Fixed) if header.count(): header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch) self.hideColumn(LayerModel.TARGET_COLUMN) diff --git a/nxt_editor/dockwidgets/output_log.py b/nxt_editor/dockwidgets/output_log.py index b5ec502..0ec8508 100644 --- a/nxt_editor/dockwidgets/output_log.py +++ b/nxt_editor/dockwidgets/output_log.py @@ -205,7 +205,7 @@ def __init__(self, graph_model=None, parent=None): self.buttons_layout = QtWidgets.QHBoxLayout() self.buttons_layout.addWidget(self.log_filter_button) - self.buttons_layout.addStretch(stretch=1) + self.buttons_layout.addStretch(1) self.buttons_layout.addWidget(self.clear_rich_button) self.rich_output_layout = QtWidgets.QVBoxLayout() diff --git a/nxt_editor/dockwidgets/property_editor.py b/nxt_editor/dockwidgets/property_editor.py index 2f80f38..2c114e0 100644 --- a/nxt_editor/dockwidgets/property_editor.py +++ b/nxt_editor/dockwidgets/property_editor.py @@ -12,7 +12,7 @@ QtCore.QStringListModel except AttributeError: del QtCore - from PySide2 import QtCore + from PySide6 import QtCore # Internal from nxt_editor import user_dir diff --git a/nxt_editor/dockwidgets/syntax.py b/nxt_editor/dockwidgets/syntax.py index 246c23f..aae7750 100644 --- a/nxt_editor/dockwidgets/syntax.py +++ b/nxt_editor/dockwidgets/syntax.py @@ -117,7 +117,7 @@ def highlightBlock(self, text): # Do other syntax formatting for rule in self.rules: expression, nth, formatting = rule - index = expression.indexIn(text, 0) + index = expression.match(text).capturedStart() # This is here because you can't do nested logic in regex nested = 0 if rule in self.special_rules: @@ -151,17 +151,19 @@ def match_multiline(self, text, delimiter, in_state, style): add = 0 # Otherwise, look for the delimiter on this line else: - start = delimiter.indexIn(text) + match = delimiter.match(text) + start = match.capturedStart() # Move past this match - add = delimiter.matchedLength() + add = match.capturedLength() # As long as there's a delimiter match on this line... while start >= 0: + match = delimiter.match(text) # Look for the ending delimiter - end = delimiter.indexIn(text, start + add) + end = match.capturedStart() + (start + add) # Ending delimiter on this line? if end >= add: - length = end - start + add + delimiter.matchedLength() + length = end - start + add + match.capturedLength() self.setCurrentBlockState(0) # No; multi-line string else: @@ -170,7 +172,7 @@ def match_multiline(self, text, delimiter, in_state, style): # Apply formatting self.setFormat(start, length, style) # Look for the next match - start = delimiter.indexIn(text, start + length) + start = match.capturedStart() + (start + length) # Return True if still inside a multi-line string, False otherwise if self.currentBlockState() == in_state: diff --git a/nxt_editor/dockwidgets/widget_builder.py b/nxt_editor/dockwidgets/widget_builder.py index b773b2c..1ecb1a2 100644 --- a/nxt_editor/dockwidgets/widget_builder.py +++ b/nxt_editor/dockwidgets/widget_builder.py @@ -15,7 +15,7 @@ QtCore.QStringListModel except AttributeError: del QtCore - from PySide2 import QtCore + from PySide6 import QtCore # Internal import nxt_editor diff --git a/nxt_editor/node_graphics_item.py b/nxt_editor/node_graphics_item.py index b8de726..5abc1da 100644 --- a/nxt_editor/node_graphics_item.py +++ b/nxt_editor/node_graphics_item.py @@ -9,7 +9,7 @@ from Qt import QtWidgets from Qt import QtGui from Qt import QtCore -from PySide2 import __version_info__ as qt_version +from PySide6 import __version_info__ as qt_version # Internal import nxt_editor @@ -262,13 +262,13 @@ def screen_pos(self): def itemChange(self, change, value): """Override of QtWidgets.QGraphicsItem itemChange.""" # keep connections drawing to node as it moves - if change is self.ItemScenePositionHasChanged: + if change is QtWidgets.QGraphicsItem.ItemPositionChange: graphics = self.view.get_node_connection_graphics(self.node_path) for connection in graphics: connection.rebuild_line() # TODO: Take into account the positions of every selected node and snap them all to a grid as soon as # the user preses shift. This will avoid the weird wavy snapping effect we have right now - if change == self.ItemPositionChange and self.scene(): + if change == QtWidgets.QGraphicsItem.ItemPositionChange and self.scene(): ml = QtWidgets.QApplication.mouseButtons() == QtCore.Qt.LeftButton shift = QtWidgets.QApplication.keyboardModifiers() == QtCore.Qt.ShiftModifier force_snap = self.view.alignment_actions.snap_action.isChecked() diff --git a/nxt_editor/stage_view.py b/nxt_editor/stage_view.py index 11151ec..dc243f1 100644 --- a/nxt_editor/stage_view.py +++ b/nxt_editor/stage_view.py @@ -8,6 +8,7 @@ from Qt import QtWidgets from Qt import QtGui from Qt import QtCore +from Qt import QtCompat # Interal import nxt_editor @@ -79,8 +80,8 @@ def __init__(self, model, parent=None): self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.horizontalScrollBar().setValue(0) self.verticalScrollBar().setValue(0) - self.setOptimizationFlag(self.DontSavePainterState, enabled=True) - self.setOptimizationFlag(self.DontAdjustForAntialiasing, enabled=True) + self.setOptimizationFlag(QtWidgets.QGraphicsView.DontSavePainterState, enabled=True) + self.setOptimizationFlag(QtWidgets.QGraphicsView.DontAdjustForAntialiasing, enabled=True) # scene self._scene = QtWidgets.QGraphicsScene() self.setScene(self._scene) @@ -700,7 +701,7 @@ def mousePressEvent(self, event): self.zoom_start_pos = event.pos() self._previous_mouse_pos = event.pos() event.accept() - if event.buttons() == QtCore.Qt.LeftButton | QtCore.Qt.MidButton: + if event.buttons() == QtCore.Qt.LeftButton | QtCompat.QtCore.Qt.MidButton: self.zooming = True self.zoom_start_pos = event.pos() self._previous_mouse_pos = event.pos() @@ -747,7 +748,7 @@ def mousePressEvent(self, event): return # block immediate node movement # middle and right button events - elif event.button() == QtCore.Qt.MiddleButton: + elif event.button() == QtCompat.QtCore.Qt.MidButton: # start panning action self.panning = True self._previous_mouse_pos = None @@ -825,11 +826,11 @@ def mouseReleaseEvent(self, event): event.accept() if self.zooming: - if event.buttons() == QtCore.Qt.LeftButton | QtCore.Qt.MidButton: + if event.buttons() == QtCore.Qt.LeftButton | QtCompat.QtCore.Qt.MidButton: self.zooming = False elif event.buttons() == QtCore.Qt.LeftButton: self.zooming = False - elif event.buttons() == QtCore.Qt.MidButton: + elif event.buttons() == QtCompat.QtCore.Qt.MidButton: self.zooming = False if (self._rubber_band_origin is not None and event.button() is QtCore.Qt.LeftButton): @@ -967,7 +968,7 @@ def mouseReleaseEvent(self, event): self.block_context_menu = False self.contextMenuEvent(event) # complete panning action - if self.panning and event.button() == QtCore.Qt.MiddleButton: + if self.panning and event.button() == QtCompat.QtCore.Qt.MidButton: self._previous_mouse_pos = None self.panning = False self._current_pan_distance = 0.0 @@ -993,11 +994,11 @@ def mouseDoubleClickEvent(self, event): item.collapse_node() def wheelEvent(self, event): - self._view_pos = event.pos() + self._view_pos = event.position().toPoint() self._scene_pos = self.mapToScene(self._view_pos) try: - new_scale = event.delta() * .001 + 1.0 + new_scale = event.angleDelta().y() * .001 + 1.0 except AttributeError: new_scale = 1.1 diff --git a/nxt_editor/user_dir.py b/nxt_editor/user_dir.py index 6353f68..2b6c4c9 100644 --- a/nxt_editor/user_dir.py +++ b/nxt_editor/user_dir.py @@ -10,6 +10,7 @@ import json import logging +import shutil import sys if sys.version_info[0] == 2: @@ -209,10 +210,10 @@ def read(self): return try: with open(self.path, 'r+b') as fp: - if sys.version_info[0] == 2: - contents = pickle.load(fp) - else: - contents = pickle.load(fp, encoding='bytes') + contents = pickle.load(fp, encoding='bytes') + except ModuleNotFoundError as e: + if 'PySide2' in e.msg: + shutil.move(self.path, self.path + '.backup') except pickle.UnpicklingError: broken_files.setdefault(self.path, 0) times_hit = broken_files[self.path] diff --git a/setup.py b/setup.py index 7b98ff4..6161dbe 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ python_requires='>=3.7, <3.11', install_requires=['nxt-core<1.0,>=0.14', 'qt.py<3', - 'pyside2>=5.11,<=5.16' + 'PySide6>=6,<6.8' ], package_data={ # covers text nxt files