From 227c61d20e5fe7a2746175ebee3e229355312454 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:48:15 +0100 Subject: [PATCH 01/42] use qtpy in publisher tool --- openpype/tools/publisher/constants.py | 2 +- openpype/tools/publisher/control_qt.py | 2 +- openpype/tools/publisher/publish_report_viewer/__init__.py | 2 +- openpype/tools/publisher/publish_report_viewer/constants.py | 2 +- openpype/tools/publisher/publish_report_viewer/delegates.py | 2 +- openpype/tools/publisher/publish_report_viewer/model.py | 2 +- openpype/tools/publisher/publish_report_viewer/widgets.py | 2 +- openpype/tools/publisher/publish_report_viewer/window.py | 2 +- openpype/tools/publisher/widgets/assets_widget.py | 2 +- openpype/tools/publisher/widgets/border_label_widget.py | 2 +- openpype/tools/publisher/widgets/card_view_widgets.py | 2 +- openpype/tools/publisher/widgets/create_widget.py | 2 +- openpype/tools/publisher/widgets/help_widget.py | 2 +- openpype/tools/publisher/widgets/icons.py | 2 +- openpype/tools/publisher/widgets/list_view_widgets.py | 2 +- openpype/tools/publisher/widgets/overview_widget.py | 2 +- openpype/tools/publisher/widgets/precreate_widget.py | 2 +- openpype/tools/publisher/widgets/publish_frame.py | 2 +- openpype/tools/publisher/widgets/tabs_widget.py | 2 +- openpype/tools/publisher/widgets/tasks_widget.py | 2 +- openpype/tools/publisher/widgets/thumbnail_widget.py | 2 +- openpype/tools/publisher/widgets/validations_widget.py | 2 +- openpype/tools/publisher/widgets/widgets.py | 2 +- openpype/tools/publisher/window.py | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/openpype/tools/publisher/constants.py b/openpype/tools/publisher/constants.py index 96f74a5a5c3..e9fdd4774a6 100644 --- a/openpype/tools/publisher/constants.py +++ b/openpype/tools/publisher/constants.py @@ -1,4 +1,4 @@ -from Qt import QtCore +from qtpy import QtCore # ID of context item in instance view CONTEXT_ID = "context" diff --git a/openpype/tools/publisher/control_qt.py b/openpype/tools/publisher/control_qt.py index 8b5856f2343..3639c4bb300 100644 --- a/openpype/tools/publisher/control_qt.py +++ b/openpype/tools/publisher/control_qt.py @@ -1,7 +1,7 @@ import collections from abc import abstractmethod, abstractproperty -from Qt import QtCore +from qtpy import QtCore from openpype.lib.events import Event from openpype.pipeline.create import CreatedInstance diff --git a/openpype/tools/publisher/publish_report_viewer/__init__.py b/openpype/tools/publisher/publish_report_viewer/__init__.py index bf77a6d30b8..2c51e5d7366 100644 --- a/openpype/tools/publisher/publish_report_viewer/__init__.py +++ b/openpype/tools/publisher/publish_report_viewer/__init__.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets +from qtpy import QtWidgets from .report_items import ( PublishReport diff --git a/openpype/tools/publisher/publish_report_viewer/constants.py b/openpype/tools/publisher/publish_report_viewer/constants.py index 8fbb9342cab..529ecfc5c00 100644 --- a/openpype/tools/publisher/publish_report_viewer/constants.py +++ b/openpype/tools/publisher/publish_report_viewer/constants.py @@ -1,4 +1,4 @@ -from Qt import QtCore +from qtpy import QtCore ITEM_ID_ROLE = QtCore.Qt.UserRole + 1 diff --git a/openpype/tools/publisher/publish_report_viewer/delegates.py b/openpype/tools/publisher/publish_report_viewer/delegates.py index 9cd4f52174b..fc06b23900d 100644 --- a/openpype/tools/publisher/publish_report_viewer/delegates.py +++ b/openpype/tools/publisher/publish_report_viewer/delegates.py @@ -1,5 +1,5 @@ import collections -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from .constants import ( ITEM_IS_GROUP_ROLE, ITEM_ERRORED_ROLE, diff --git a/openpype/tools/publisher/publish_report_viewer/model.py b/openpype/tools/publisher/publish_report_viewer/model.py index 704feeb4bd9..37da4ab3f24 100644 --- a/openpype/tools/publisher/publish_report_viewer/model.py +++ b/openpype/tools/publisher/publish_report_viewer/model.py @@ -1,5 +1,5 @@ import uuid -from Qt import QtCore, QtGui +from qtpy import QtCore, QtGui import pyblish.api diff --git a/openpype/tools/publisher/publish_report_viewer/widgets.py b/openpype/tools/publisher/publish_report_viewer/widgets.py index 0d35ac35120..7066efed325 100644 --- a/openpype/tools/publisher/publish_report_viewer/widgets.py +++ b/openpype/tools/publisher/publish_report_viewer/widgets.py @@ -1,5 +1,5 @@ from math import ceil -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.widgets.nice_checkbox import NiceCheckbox diff --git a/openpype/tools/publisher/publish_report_viewer/window.py b/openpype/tools/publisher/publish_report_viewer/window.py index 646ae69e7f1..127a65dd9bf 100644 --- a/openpype/tools/publisher/publish_report_viewer/window.py +++ b/openpype/tools/publisher/publish_report_viewer/window.py @@ -4,7 +4,7 @@ import uuid import appdirs -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype import style from openpype.resources import get_openpype_icon_filepath diff --git a/openpype/tools/publisher/widgets/assets_widget.py b/openpype/tools/publisher/widgets/assets_widget.py index 996c9029d4d..583e70ad5a9 100644 --- a/openpype/tools/publisher/widgets/assets_widget.py +++ b/openpype/tools/publisher/widgets/assets_widget.py @@ -1,6 +1,6 @@ import collections -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.tools.utils import ( PlaceholderLineEdit, diff --git a/openpype/tools/publisher/widgets/border_label_widget.py b/openpype/tools/publisher/widgets/border_label_widget.py index 8e09dd817ef..db575d7b906 100644 --- a/openpype/tools/publisher/widgets/border_label_widget.py +++ b/openpype/tools/publisher/widgets/border_label_widget.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.style import get_objected_colors diff --git a/openpype/tools/publisher/widgets/card_view_widgets.py b/openpype/tools/publisher/widgets/card_view_widgets.py index 57336f9304c..47f8ebb914c 100644 --- a/openpype/tools/publisher/widgets/card_view_widgets.py +++ b/openpype/tools/publisher/widgets/card_view_widgets.py @@ -23,7 +23,7 @@ import re import collections -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.widgets.nice_checkbox import NiceCheckbox diff --git a/openpype/tools/publisher/widgets/create_widget.py b/openpype/tools/publisher/widgets/create_widget.py index 7bdac46273e..07b124f6163 100644 --- a/openpype/tools/publisher/widgets/create_widget.py +++ b/openpype/tools/publisher/widgets/create_widget.py @@ -1,6 +1,6 @@ import re -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.pipeline.create import ( SUBSET_NAME_ALLOWED_SYMBOLS, diff --git a/openpype/tools/publisher/widgets/help_widget.py b/openpype/tools/publisher/widgets/help_widget.py index 00901118893..5d474613dff 100644 --- a/openpype/tools/publisher/widgets/help_widget.py +++ b/openpype/tools/publisher/widgets/help_widget.py @@ -3,7 +3,7 @@ except Exception: commonmark = None -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore class HelpButton(QtWidgets.QPushButton): diff --git a/openpype/tools/publisher/widgets/icons.py b/openpype/tools/publisher/widgets/icons.py index fd5c45f9010..8aa82f580f5 100644 --- a/openpype/tools/publisher/widgets/icons.py +++ b/openpype/tools/publisher/widgets/icons.py @@ -1,6 +1,6 @@ import os -from Qt import QtGui +from qtpy import QtGui def get_icon_path(icon_name=None, filename=None): diff --git a/openpype/tools/publisher/widgets/list_view_widgets.py b/openpype/tools/publisher/widgets/list_view_widgets.py index 1cdb4cdcdbf..57c1e769e48 100644 --- a/openpype/tools/publisher/widgets/list_view_widgets.py +++ b/openpype/tools/publisher/widgets/list_view_widgets.py @@ -24,7 +24,7 @@ """ import collections -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.style import get_objected_colors from openpype.widgets.nice_checkbox import NiceCheckbox diff --git a/openpype/tools/publisher/widgets/overview_widget.py b/openpype/tools/publisher/widgets/overview_widget.py index b1aeda9cd4e..2566806228c 100644 --- a/openpype/tools/publisher/widgets/overview_widget.py +++ b/openpype/tools/publisher/widgets/overview_widget.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from .border_label_widget import BorderedLabelWidget diff --git a/openpype/tools/publisher/widgets/precreate_widget.py b/openpype/tools/publisher/widgets/precreate_widget.py index b688a830539..3037a0e12d3 100644 --- a/openpype/tools/publisher/widgets/precreate_widget.py +++ b/openpype/tools/publisher/widgets/precreate_widget.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.tools.attribute_defs import create_widget_for_attr_def diff --git a/openpype/tools/publisher/widgets/publish_frame.py b/openpype/tools/publisher/widgets/publish_frame.py index 00597451a9d..fe349e52a60 100644 --- a/openpype/tools/publisher/widgets/publish_frame.py +++ b/openpype/tools/publisher/widgets/publish_frame.py @@ -2,7 +2,7 @@ import json import time -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from .widgets import ( StopBtn, diff --git a/openpype/tools/publisher/widgets/tabs_widget.py b/openpype/tools/publisher/widgets/tabs_widget.py index d8ad19cfc09..4b87b761786 100644 --- a/openpype/tools/publisher/widgets/tabs_widget.py +++ b/openpype/tools/publisher/widgets/tabs_widget.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.tools.utils import set_style_property diff --git a/openpype/tools/publisher/widgets/tasks_widget.py b/openpype/tools/publisher/widgets/tasks_widget.py index f31fffb9ea4..1b1ddd0c7d5 100644 --- a/openpype/tools/publisher/widgets/tasks_widget.py +++ b/openpype/tools/publisher/widgets/tasks_widget.py @@ -1,4 +1,4 @@ -from Qt import QtCore, QtGui +from qtpy import QtCore, QtGui from openpype.tools.utils.tasks_widget import TasksWidget, TASK_NAME_ROLE from openpype.tools.utils.lib import get_default_task_icon diff --git a/openpype/tools/publisher/widgets/thumbnail_widget.py b/openpype/tools/publisher/widgets/thumbnail_widget.py index 035ec4b04b8..07423d47648 100644 --- a/openpype/tools/publisher/widgets/thumbnail_widget.py +++ b/openpype/tools/publisher/widgets/thumbnail_widget.py @@ -1,7 +1,7 @@ import os import uuid -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.style import get_objected_colors from openpype.lib import ( diff --git a/openpype/tools/publisher/widgets/validations_widget.py b/openpype/tools/publisher/widgets/validations_widget.py index 935a12bc730..c5b5a00883e 100644 --- a/openpype/tools/publisher/widgets/validations_widget.py +++ b/openpype/tools/publisher/widgets/validations_widget.py @@ -4,7 +4,7 @@ except Exception: commonmark = None -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.tools.utils import BaseClickableFrame, ClickableFrame from .widgets import ( diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index 4b9626154d6..16641bfb6c5 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -6,7 +6,7 @@ import uuid import shutil import collections -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui import qtawesome from openpype.lib.attribute_definitions import UnknownDef diff --git a/openpype/tools/publisher/window.py b/openpype/tools/publisher/window.py index 0f7fd2c7e33..097e289f325 100644 --- a/openpype/tools/publisher/window.py +++ b/openpype/tools/publisher/window.py @@ -1,6 +1,6 @@ import collections import copy -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype import ( resources, From fa48c9dce3bf393bf268fcab45270c801b72de0e Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:48:23 +0100 Subject: [PATCH 02/42] use qtpy in workfiles tool --- openpype/tools/workfiles/files_widget.py | 6 +++--- openpype/tools/workfiles/lock_dialog.py | 2 +- openpype/tools/workfiles/model.py | 2 +- openpype/tools/workfiles/save_as_dialog.py | 2 +- openpype/tools/workfiles/window.py | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/openpype/tools/workfiles/files_widget.py b/openpype/tools/workfiles/files_widget.py index b7d31e4af4f..52ec348e459 100644 --- a/openpype/tools/workfiles/files_widget.py +++ b/openpype/tools/workfiles/files_widget.py @@ -3,8 +3,8 @@ import shutil import copy -import Qt -from Qt import QtWidgets, QtCore +import qtpy +from qtpy import QtWidgets, QtCore from openpype.host import IWorkfileHost from openpype.client import get_asset_by_id @@ -618,7 +618,7 @@ def on_browse_pressed(self): "caption": "Work Files", "filter": ext_filter } - if Qt.__binding__ in ("PySide", "PySide2"): + if qtpy.API in ("pyside", "pyside2"): kwargs["dir"] = self._workfiles_root else: kwargs["directory"] = self._workfiles_root diff --git a/openpype/tools/workfiles/lock_dialog.py b/openpype/tools/workfiles/lock_dialog.py index c574a74e32b..29e0d3bd9b8 100644 --- a/openpype/tools/workfiles/lock_dialog.py +++ b/openpype/tools/workfiles/lock_dialog.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.style import load_stylesheet, get_app_icon_path from openpype.pipeline.workfile.lock_workfile import get_workfile_lock_data diff --git a/openpype/tools/workfiles/model.py b/openpype/tools/workfiles/model.py index 9a7fd659a9a..bbd67c9b985 100644 --- a/openpype/tools/workfiles/model.py +++ b/openpype/tools/workfiles/model.py @@ -1,7 +1,7 @@ import os import logging -from Qt import QtCore, QtGui +from qtpy import QtCore, QtGui import qtawesome from openpype.client import ( diff --git a/openpype/tools/workfiles/save_as_dialog.py b/openpype/tools/workfiles/save_as_dialog.py index cded4eb1a50..de21deee424 100644 --- a/openpype/tools/workfiles/save_as_dialog.py +++ b/openpype/tools/workfiles/save_as_dialog.py @@ -3,7 +3,7 @@ import copy import logging -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.pipeline import ( registered_host, diff --git a/openpype/tools/workfiles/window.py b/openpype/tools/workfiles/window.py index de42b80d643..31ecf50d3b8 100644 --- a/openpype/tools/workfiles/window.py +++ b/openpype/tools/workfiles/window.py @@ -1,7 +1,7 @@ import os import datetime import copy -from Qt import QtCore, QtWidgets, QtGui +from qtpy import QtCore, QtWidgets, QtGui from openpype.client import ( get_asset_by_name, From 0b5b7f57755543d7f2c13211d9d819e82426333d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:48:48 +0100 Subject: [PATCH 03/42] use qtpy in subset manager --- openpype/tools/subsetmanager/model.py | 2 +- openpype/tools/subsetmanager/widgets.py | 2 +- openpype/tools/subsetmanager/window.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/tools/subsetmanager/model.py b/openpype/tools/subsetmanager/model.py index 760a167b42f..2df0cb7067b 100644 --- a/openpype/tools/subsetmanager/model.py +++ b/openpype/tools/subsetmanager/model.py @@ -1,6 +1,6 @@ import uuid -from Qt import QtCore, QtGui +from qtpy import QtCore, QtGui from openpype.pipeline import registered_host diff --git a/openpype/tools/subsetmanager/widgets.py b/openpype/tools/subsetmanager/widgets.py index 7a8cb15cbf4..1067474c445 100644 --- a/openpype/tools/subsetmanager/widgets.py +++ b/openpype/tools/subsetmanager/widgets.py @@ -1,5 +1,5 @@ import json -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore class InstanceDetail(QtWidgets.QWidget): diff --git a/openpype/tools/subsetmanager/window.py b/openpype/tools/subsetmanager/window.py index 6314e670154..30de83c142e 100644 --- a/openpype/tools/subsetmanager/window.py +++ b/openpype/tools/subsetmanager/window.py @@ -1,7 +1,7 @@ import os import sys -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore import qtawesome from openpype import style From e6a7de51335ff712d4c8cbd892ebc444f966d24f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:49:00 +0100 Subject: [PATCH 04/42] use qtpy in scene inventory --- openpype/tools/sceneinventory/lib.py | 2 +- openpype/tools/sceneinventory/model.py | 2 +- openpype/tools/sceneinventory/switch_dialog.py | 2 +- openpype/tools/sceneinventory/view.py | 2 +- openpype/tools/sceneinventory/widgets.py | 2 +- openpype/tools/sceneinventory/window.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openpype/tools/sceneinventory/lib.py b/openpype/tools/sceneinventory/lib.py index 7653e1da89b..5db3c479c5a 100644 --- a/openpype/tools/sceneinventory/lib.py +++ b/openpype/tools/sceneinventory/lib.py @@ -1,7 +1,7 @@ import os from openpype_modules import sync_server -from Qt import QtGui +from qtpy import QtGui def walk_hierarchy(node): diff --git a/openpype/tools/sceneinventory/model.py b/openpype/tools/sceneinventory/model.py index 1a3b7c70551..9b45ed6cc1b 100644 --- a/openpype/tools/sceneinventory/model.py +++ b/openpype/tools/sceneinventory/model.py @@ -3,7 +3,7 @@ from collections import defaultdict -from Qt import QtCore, QtGui +from qtpy import QtCore, QtGui import qtawesome from openpype.host import ILoadHost diff --git a/openpype/tools/sceneinventory/switch_dialog.py b/openpype/tools/sceneinventory/switch_dialog.py index 1d1d5cbb918..47baeaebeab 100644 --- a/openpype/tools/sceneinventory/switch_dialog.py +++ b/openpype/tools/sceneinventory/switch_dialog.py @@ -1,6 +1,6 @@ import collections import logging -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore import qtawesome from bson.objectid import ObjectId diff --git a/openpype/tools/sceneinventory/view.py b/openpype/tools/sceneinventory/view.py index e0e43aaba7c..ba3aa069f23 100644 --- a/openpype/tools/sceneinventory/view.py +++ b/openpype/tools/sceneinventory/view.py @@ -2,7 +2,7 @@ import logging from functools import partial -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore import qtawesome from bson.objectid import ObjectId diff --git a/openpype/tools/sceneinventory/widgets.py b/openpype/tools/sceneinventory/widgets.py index 4c4aafad3a0..994e6c8108d 100644 --- a/openpype/tools/sceneinventory/widgets.py +++ b/openpype/tools/sceneinventory/widgets.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype import style diff --git a/openpype/tools/sceneinventory/window.py b/openpype/tools/sceneinventory/window.py index 8bac1beb305..7b305e8e8f1 100644 --- a/openpype/tools/sceneinventory/window.py +++ b/openpype/tools/sceneinventory/window.py @@ -1,7 +1,7 @@ import os import sys -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore import qtawesome from openpype import style From 40d44898fd244953b431d3a13c5eecb55073fda0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:49:25 +0100 Subject: [PATCH 05/42] use qtpy in pyblish pype --- openpype/tools/pyblish_pype/app.py | 3 ++- openpype/tools/pyblish_pype/constants.py | 2 +- openpype/tools/pyblish_pype/control.py | 2 +- openpype/tools/pyblish_pype/delegate.py | 2 +- openpype/tools/pyblish_pype/model.py | 2 +- openpype/tools/pyblish_pype/util.py | 2 +- openpype/tools/pyblish_pype/vendor/qtawesome/animation.py | 2 +- openpype/tools/pyblish_pype/vendor/qtawesome/iconic_font.py | 2 +- openpype/tools/pyblish_pype/view.py | 2 +- openpype/tools/pyblish_pype/widgets.py | 2 +- openpype/tools/pyblish_pype/window.py | 2 +- 11 files changed, 12 insertions(+), 11 deletions(-) diff --git a/openpype/tools/pyblish_pype/app.py b/openpype/tools/pyblish_pype/app.py index a252b964278..bdc204bfbdd 100644 --- a/openpype/tools/pyblish_pype/app.py +++ b/openpype/tools/pyblish_pype/app.py @@ -6,8 +6,9 @@ import platform import contextlib +from qtpy import QtCore, QtGui, QtWidgets + from . import control, settings, util, window -from Qt import QtCore, QtGui, QtWidgets self = sys.modules[__name__] diff --git a/openpype/tools/pyblish_pype/constants.py b/openpype/tools/pyblish_pype/constants.py index 03536fb8297..10f95ca4af2 100644 --- a/openpype/tools/pyblish_pype/constants.py +++ b/openpype/tools/pyblish_pype/constants.py @@ -1,4 +1,4 @@ -from Qt import QtCore +from qtpy import QtCore EXPANDER_WIDTH = 20 diff --git a/openpype/tools/pyblish_pype/control.py b/openpype/tools/pyblish_pype/control.py index 90bb002ba52..f8c6a3e0bcd 100644 --- a/openpype/tools/pyblish_pype/control.py +++ b/openpype/tools/pyblish_pype/control.py @@ -11,7 +11,7 @@ import logging import collections -from Qt import QtCore +from qtpy import QtCore import pyblish.api import pyblish.util diff --git a/openpype/tools/pyblish_pype/delegate.py b/openpype/tools/pyblish_pype/delegate.py index bf3fbc18535..bb253dd1a39 100644 --- a/openpype/tools/pyblish_pype/delegate.py +++ b/openpype/tools/pyblish_pype/delegate.py @@ -1,6 +1,6 @@ import platform -from Qt import QtWidgets, QtGui, QtCore +from qtpy import QtWidgets, QtGui, QtCore from . import model from .awesome import tags as awesome diff --git a/openpype/tools/pyblish_pype/model.py b/openpype/tools/pyblish_pype/model.py index 383d8304a5b..774c3054acb 100644 --- a/openpype/tools/pyblish_pype/model.py +++ b/openpype/tools/pyblish_pype/model.py @@ -29,7 +29,7 @@ from . import settings, util from .awesome import tags as awesome -from Qt import QtCore, QtGui +from qtpy import QtCore, QtGui import qtawesome from six import text_type from .constants import PluginStates, InstanceStates, GroupStates, Roles diff --git a/openpype/tools/pyblish_pype/util.py b/openpype/tools/pyblish_pype/util.py index 9f3697be167..81266370607 100644 --- a/openpype/tools/pyblish_pype/util.py +++ b/openpype/tools/pyblish_pype/util.py @@ -11,7 +11,7 @@ import copy import collections -from Qt import QtCore +from qtpy import QtCore from six import text_type import pyblish.api diff --git a/openpype/tools/pyblish_pype/vendor/qtawesome/animation.py b/openpype/tools/pyblish_pype/vendor/qtawesome/animation.py index e2a701785ad..ac695074448 100644 --- a/openpype/tools/pyblish_pype/vendor/qtawesome/animation.py +++ b/openpype/tools/pyblish_pype/vendor/qtawesome/animation.py @@ -1,4 +1,4 @@ -from Qt import QtCore +from qtpy import QtCore class Spin: diff --git a/openpype/tools/pyblish_pype/vendor/qtawesome/iconic_font.py b/openpype/tools/pyblish_pype/vendor/qtawesome/iconic_font.py index cd937d7e7fb..c25739aff81 100644 --- a/openpype/tools/pyblish_pype/vendor/qtawesome/iconic_font.py +++ b/openpype/tools/pyblish_pype/vendor/qtawesome/iconic_font.py @@ -6,7 +6,7 @@ import os import six -from Qt import QtCore, QtGui +from qtpy import QtCore, QtGui _default_options = { diff --git a/openpype/tools/pyblish_pype/view.py b/openpype/tools/pyblish_pype/view.py index 3b75e67d4c1..69dda6618d3 100644 --- a/openpype/tools/pyblish_pype/view.py +++ b/openpype/tools/pyblish_pype/view.py @@ -1,4 +1,4 @@ -from Qt import QtCore, QtWidgets +from qtpy import QtCore, QtWidgets from . import model from .constants import Roles, EXPANDER_WIDTH # Imported when used diff --git a/openpype/tools/pyblish_pype/widgets.py b/openpype/tools/pyblish_pype/widgets.py index dc4919c13f0..6adcc55f068 100644 --- a/openpype/tools/pyblish_pype/widgets.py +++ b/openpype/tools/pyblish_pype/widgets.py @@ -1,5 +1,5 @@ import sys -from Qt import QtCore, QtWidgets, QtGui +from qtpy import QtCore, QtWidgets, QtGui from . import model, delegate, view, awesome from .constants import PluginStates, InstanceStates, Roles diff --git a/openpype/tools/pyblish_pype/window.py b/openpype/tools/pyblish_pype/window.py index e1674053252..01d373d841c 100644 --- a/openpype/tools/pyblish_pype/window.py +++ b/openpype/tools/pyblish_pype/window.py @@ -45,7 +45,7 @@ from . import delegate, model, settings, util, view, widgets from .awesome import tags as awesome -from Qt import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets from .constants import ( PluginStates, PluginActionStates, InstanceStates, GroupStates, Roles ) From d8d99f8bd80393b9a9d69a5d2f62e9dceb639ed1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:51:33 +0100 Subject: [PATCH 06/42] use qtpy in loader --- openpype/tools/loader/app.py | 2 +- openpype/tools/loader/delegates.py | 2 +- openpype/tools/loader/lib.py | 2 +- openpype/tools/loader/model.py | 2 +- openpype/tools/loader/widgets.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/tools/loader/app.py b/openpype/tools/loader/app.py index 1917f23c60e..302fe6c366e 100644 --- a/openpype/tools/loader/app.py +++ b/openpype/tools/loader/app.py @@ -1,7 +1,7 @@ import sys import traceback -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.client import get_projects, get_project from openpype import style diff --git a/openpype/tools/loader/delegates.py b/openpype/tools/loader/delegates.py index e6663d48f11..0686fe78cde 100644 --- a/openpype/tools/loader/delegates.py +++ b/openpype/tools/loader/delegates.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtGui, QtCore +from qtpy import QtWidgets, QtGui, QtCore class LoadedInSceneDelegate(QtWidgets.QStyledItemDelegate): diff --git a/openpype/tools/loader/lib.py b/openpype/tools/loader/lib.py index 78a25d8d85f..552dc91a10b 100644 --- a/openpype/tools/loader/lib.py +++ b/openpype/tools/loader/lib.py @@ -1,5 +1,5 @@ import inspect -from Qt import QtGui +from qtpy import QtGui import qtawesome from openpype.lib.attribute_definitions import AbtractAttrDef diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 77a8669c460..5944808f8bb 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -4,7 +4,7 @@ import time from uuid import uuid4 -from Qt import QtCore, QtGui +from qtpy import QtCore, QtGui import qtawesome from openpype.client import ( diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 826c7110da8..c2c6c5dfcd3 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -5,7 +5,7 @@ import traceback import collections -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.client import ( get_subset_families, From 678f6c6c28a92ab5fb24c36af9b8a5027bb6ce12 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:51:46 +0100 Subject: [PATCH 07/42] use qtpy in library loader --- openpype/tools/libraryloader/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/libraryloader/app.py b/openpype/tools/libraryloader/app.py index d2af1b71517..bd105953339 100644 --- a/openpype/tools/libraryloader/app.py +++ b/openpype/tools/libraryloader/app.py @@ -1,6 +1,6 @@ import sys -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype import style from openpype.client import get_projects, get_project From 9f616c2bcbc7197a5d5b24636fc84fed33c36215 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:51:57 +0100 Subject: [PATCH 08/42] use qtpy in mayalookassigner --- openpype/tools/mayalookassigner/app.py | 2 +- openpype/tools/mayalookassigner/models.py | 2 +- openpype/tools/mayalookassigner/views.py | 2 +- openpype/tools/mayalookassigner/widgets.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/tools/mayalookassigner/app.py b/openpype/tools/mayalookassigner/app.py index 5665acea427..f9508657e50 100644 --- a/openpype/tools/mayalookassigner/app.py +++ b/openpype/tools/mayalookassigner/app.py @@ -2,7 +2,7 @@ import time import logging -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.client import get_last_version_by_subset_id from openpype import style diff --git a/openpype/tools/mayalookassigner/models.py b/openpype/tools/mayalookassigner/models.py index 77a3c8a5903..ed6a68bee0d 100644 --- a/openpype/tools/mayalookassigner/models.py +++ b/openpype/tools/mayalookassigner/models.py @@ -1,6 +1,6 @@ from collections import defaultdict -from Qt import QtCore +from qtpy import QtCore import qtawesome from openpype.tools.utils import models diff --git a/openpype/tools/mayalookassigner/views.py b/openpype/tools/mayalookassigner/views.py index 8e676ebc7f1..87459ad897c 100644 --- a/openpype/tools/mayalookassigner/views.py +++ b/openpype/tools/mayalookassigner/views.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore class View(QtWidgets.QTreeView): diff --git a/openpype/tools/mayalookassigner/widgets.py b/openpype/tools/mayalookassigner/widgets.py index 10e573342a1..f2df17e68cf 100644 --- a/openpype/tools/mayalookassigner/widgets.py +++ b/openpype/tools/mayalookassigner/widgets.py @@ -1,7 +1,7 @@ import logging from collections import defaultdict -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.tools.utils.models import TreeModel from openpype.tools.utils.lib import ( From e9ca36dcfbbee8ca71e4fd8b45f0068182d920d4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:52:08 +0100 Subject: [PATCH 09/42] use qtpy in creator --- openpype/tools/creator/constants.py | 2 +- openpype/tools/creator/model.py | 2 +- openpype/tools/creator/widgets.py | 2 +- openpype/tools/creator/window.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/tools/creator/constants.py b/openpype/tools/creator/constants.py index 26a25dc0107..5c4bbdcca3e 100644 --- a/openpype/tools/creator/constants.py +++ b/openpype/tools/creator/constants.py @@ -1,4 +1,4 @@ -from Qt import QtCore +from qtpy import QtCore FAMILY_ROLE = QtCore.Qt.UserRole + 1 diff --git a/openpype/tools/creator/model.py b/openpype/tools/creator/model.py index 307993103bf..d7f13885f54 100644 --- a/openpype/tools/creator/model.py +++ b/openpype/tools/creator/model.py @@ -1,5 +1,5 @@ import uuid -from Qt import QtGui, QtCore +from qtpy import QtGui, QtCore from openpype.pipeline import discover_legacy_creator_plugins diff --git a/openpype/tools/creator/widgets.py b/openpype/tools/creator/widgets.py index 43df08496bd..8ea3cbd03f8 100644 --- a/openpype/tools/creator/widgets.py +++ b/openpype/tools/creator/widgets.py @@ -1,7 +1,7 @@ import re import inspect -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui import qtawesome diff --git a/openpype/tools/creator/window.py b/openpype/tools/creator/window.py index e2396ed29e0..57e2c49576e 100644 --- a/openpype/tools/creator/window.py +++ b/openpype/tools/creator/window.py @@ -2,7 +2,7 @@ import traceback import re -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.client import get_asset_by_name, get_subsets from openpype import style From 88939540f743a2c90d4b3a9af3da5564543fc788 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:52:28 +0100 Subject: [PATCH 10/42] use qtpy in attribute definitions --- openpype/tools/attribute_defs/dialog.py | 2 +- openpype/tools/attribute_defs/files_widget.py | 2 +- openpype/tools/attribute_defs/widgets.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/tools/attribute_defs/dialog.py b/openpype/tools/attribute_defs/dialog.py index 69923d54e59..ef717d576a1 100644 --- a/openpype/tools/attribute_defs/dialog.py +++ b/openpype/tools/attribute_defs/dialog.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets +from qtpy import QtWidgets from .widgets import AttributeDefinitionsWidget diff --git a/openpype/tools/attribute_defs/files_widget.py b/openpype/tools/attribute_defs/files_widget.py index 2c8ed729c23..71714fdf161 100644 --- a/openpype/tools/attribute_defs/files_widget.py +++ b/openpype/tools/attribute_defs/files_widget.py @@ -3,7 +3,7 @@ import uuid import json -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.lib import FileDefItem from openpype.tools.utils import ( diff --git a/openpype/tools/attribute_defs/widgets.py b/openpype/tools/attribute_defs/widgets.py index 1ffb3d37994..ecc899c748d 100644 --- a/openpype/tools/attribute_defs/widgets.py +++ b/openpype/tools/attribute_defs/widgets.py @@ -1,7 +1,7 @@ import uuid import copy -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.lib.attribute_definitions import ( AbtractAttrDef, From 3468a285c1d263af0da9c163a9a011476baf0d56 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:52:52 +0100 Subject: [PATCH 11/42] use qtpy in remaining qt utils --- openpype/tools/assetlinks/widgets.py | 2 +- openpype/tools/experimental_tools/dialog.py | 2 +- openpype/tools/flickcharm.py | 2 +- openpype/tools/resources/__init__.py | 2 +- openpype/tools/utils/assets_widget.py | 8 ++++---- openpype/tools/utils/constants.py | 2 +- openpype/tools/utils/delegates.py | 8 +------- openpype/tools/utils/error_dialog.py | 2 +- openpype/tools/utils/lib.py | 2 +- openpype/tools/utils/models.py | 6 +++--- openpype/tools/utils/overlay_messages.py | 2 +- openpype/tools/utils/tasks_widget.py | 2 +- openpype/tools/utils/views.py | 3 +-- openpype/tools/utils/widgets.py | 2 +- openpype/tools/workfile_template_build/window.py | 2 +- 15 files changed, 20 insertions(+), 27 deletions(-) diff --git a/openpype/tools/assetlinks/widgets.py b/openpype/tools/assetlinks/widgets.py index 1b168e542c7..7b05eef2d76 100644 --- a/openpype/tools/assetlinks/widgets.py +++ b/openpype/tools/assetlinks/widgets.py @@ -6,7 +6,7 @@ get_output_link_versions, ) -from Qt import QtWidgets +from qtpy import QtWidgets class SimpleLinkView(QtWidgets.QWidget): diff --git a/openpype/tools/experimental_tools/dialog.py b/openpype/tools/experimental_tools/dialog.py index 0099492207b..00b6ae07a40 100644 --- a/openpype/tools/experimental_tools/dialog.py +++ b/openpype/tools/experimental_tools/dialog.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.style import ( load_stylesheet, diff --git a/openpype/tools/flickcharm.py b/openpype/tools/flickcharm.py index a5ea5a79d80..8d85dacce41 100644 --- a/openpype/tools/flickcharm.py +++ b/openpype/tools/flickcharm.py @@ -16,7 +16,7 @@ """ import copy -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui class FlickData(object): diff --git a/openpype/tools/resources/__init__.py b/openpype/tools/resources/__init__.py index fd5c45f9010..8aa82f580f5 100644 --- a/openpype/tools/resources/__init__.py +++ b/openpype/tools/resources/__init__.py @@ -1,6 +1,6 @@ import os -from Qt import QtGui +from qtpy import QtGui def get_icon_path(icon_name=None, filename=None): diff --git a/openpype/tools/utils/assets_widget.py b/openpype/tools/utils/assets_widget.py index 2a1fb4567c3..c92e68aa979 100644 --- a/openpype/tools/utils/assets_widget.py +++ b/openpype/tools/utils/assets_widget.py @@ -1,8 +1,8 @@ import time import collections -import Qt -from Qt import QtWidgets, QtCore, QtGui +import qtpy +from qtpy import QtWidgets, QtCore, QtGui import qtawesome from openpype.client import ( @@ -26,9 +26,9 @@ get_asset_icon ) -if Qt.__binding__ == "PySide": +if qtpy.API == "pyside": from PySide.QtGui import QStyleOptionViewItemV4 -elif Qt.__binding__ == "PyQt4": +elif qtpy.API == "pyqt4": from PyQt4.QtGui import QStyleOptionViewItemV4 ASSET_ID_ROLE = QtCore.Qt.UserRole + 1 diff --git a/openpype/tools/utils/constants.py b/openpype/tools/utils/constants.py index 8f12c573211..a3b1557f264 100644 --- a/openpype/tools/utils/constants.py +++ b/openpype/tools/utils/constants.py @@ -1,4 +1,4 @@ -from Qt import QtCore +from qtpy import QtCore DEFAULT_PROJECT_LABEL = "< Default >" diff --git a/openpype/tools/utils/delegates.py b/openpype/tools/utils/delegates.py index d6c2d69e768..17479488003 100644 --- a/openpype/tools/utils/delegates.py +++ b/openpype/tools/utils/delegates.py @@ -3,13 +3,7 @@ import logging import numbers -import Qt -from Qt import QtWidgets, QtGui, QtCore - -if Qt.__binding__ == "PySide": - from PySide.QtGui import QStyleOptionViewItemV4 -elif Qt.__binding__ == "PyQt4": - from PyQt4.QtGui import QStyleOptionViewItemV4 +from qtpy import QtWidgets, QtGui, QtCore from openpype.client import ( get_versions, diff --git a/openpype/tools/utils/error_dialog.py b/openpype/tools/utils/error_dialog.py index 5fe49a53af4..4c275a213b8 100644 --- a/openpype/tools/utils/error_dialog.py +++ b/openpype/tools/utils/error_dialog.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from .widgets import ClickableFrame, ExpandBtn, SeparatorWidget diff --git a/openpype/tools/utils/lib.py b/openpype/tools/utils/lib.py index 5302946c28b..403811699d6 100644 --- a/openpype/tools/utils/lib.py +++ b/openpype/tools/utils/lib.py @@ -4,7 +4,7 @@ import collections import traceback -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui import qtawesome from openpype.client import ( diff --git a/openpype/tools/utils/models.py b/openpype/tools/utils/models.py index 2e93d94d7ec..b26ec566fee 100644 --- a/openpype/tools/utils/models.py +++ b/openpype/tools/utils/models.py @@ -1,8 +1,8 @@ import re import logging -import Qt -from Qt import QtCore, QtGui +import qtpy +from qtpy import QtCore, QtGui from openpype.client import get_projects from .constants import ( PROJECT_IS_ACTIVE_ROLE, @@ -69,7 +69,7 @@ def setData(self, index, value, role=QtCore.Qt.EditRole): item[key] = value # passing `list()` for PyQt5 (see PYSIDE-462) - if Qt.__binding__ in ("PyQt4", "PySide"): + if qtpy.API in ("pyqt4", "pyside"): self.dataChanged.emit(index, index) else: self.dataChanged.emit(index, index, [role]) diff --git a/openpype/tools/utils/overlay_messages.py b/openpype/tools/utils/overlay_messages.py index b58cd897410..180d7eae97c 100644 --- a/openpype/tools/utils/overlay_messages.py +++ b/openpype/tools/utils/overlay_messages.py @@ -1,6 +1,6 @@ import uuid -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.style import get_objected_colors diff --git a/openpype/tools/utils/tasks_widget.py b/openpype/tools/utils/tasks_widget.py index 0353f3dd2f2..0605fd77433 100644 --- a/openpype/tools/utils/tasks_widget.py +++ b/openpype/tools/utils/tasks_widget.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui import qtawesome from openpype.client import ( diff --git a/openpype/tools/utils/views.py b/openpype/tools/utils/views.py index a2f1f15b957..01919d67457 100644 --- a/openpype/tools/utils/views.py +++ b/openpype/tools/utils/views.py @@ -1,6 +1,5 @@ -import os from openpype.resources import get_image_path -from Qt import QtWidgets, QtCore, QtGui, QtSvg +from qtpy import QtWidgets, QtCore, QtGui, QtSvg class DeselectableTreeView(QtWidgets.QTreeView): diff --git a/openpype/tools/utils/widgets.py b/openpype/tools/utils/widgets.py index 88893a57d52..c64b6e3400d 100644 --- a/openpype/tools/utils/widgets.py +++ b/openpype/tools/utils/widgets.py @@ -1,6 +1,6 @@ import logging -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui import qargparse import qtawesome diff --git a/openpype/tools/workfile_template_build/window.py b/openpype/tools/workfile_template_build/window.py index 22e26be451c..24d91052232 100644 --- a/openpype/tools/workfile_template_build/window.py +++ b/openpype/tools/workfile_template_build/window.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets +from qtpy import QtWidgets from openpype import style from openpype.lib import Logger From 5361cfa9a5a7ecf91d7a4d73b57e2cfe439fd0b3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:53:02 +0100 Subject: [PATCH 12/42] use qtpy in style --- openpype/style/__init__.py | 2 +- openpype/style/color_defs.py | 2 +- openpype/style/qrc_resources.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/style/__init__.py b/openpype/style/__init__.py index 473fb42bb5f..48e943beb1a 100644 --- a/openpype/style/__init__.py +++ b/openpype/style/__init__.py @@ -157,7 +157,7 @@ def _load_stylesheet(): def _load_font(): """Load and register fonts into Qt application.""" - from Qt import QtGui + from qtpy import QtGui # Check if font ids are still loaded if _Cache.font_ids is not None: diff --git a/openpype/style/color_defs.py b/openpype/style/color_defs.py index f1eab38c243..69703583c45 100644 --- a/openpype/style/color_defs.py +++ b/openpype/style/color_defs.py @@ -47,7 +47,7 @@ def create_qcolor(*args): *args (tuple): It is possible to pass initialization arguments for Qcolor. """ - from Qt import QtGui + from qtpy import QtGui return QtGui.QColor(*args) diff --git a/openpype/style/qrc_resources.py b/openpype/style/qrc_resources.py index a9e219c9ad4..beacb75f2cd 100644 --- a/openpype/style/qrc_resources.py +++ b/openpype/style/qrc_resources.py @@ -1,11 +1,11 @@ -import Qt +import qtpy initialized = False resources = None -if Qt.__binding__ == "PySide2": +if qtpy.API == "pyside2": from . import pyside2_resources as resources -elif Qt.__binding__ == "PyQt5": +elif qtpy.API == "pyqt5": from . import pyqt5_resources as resources From c45c1c7e7e071e66f577ba50761a2d4f3bfa9b4d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:53:16 +0100 Subject: [PATCH 13/42] non-python host launch script uses qtpy --- openpype/scripts/non_python_host_launch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/scripts/non_python_host_launch.py b/openpype/scripts/non_python_host_launch.py index f795af7bb3c..79fb1cbb523 100644 --- a/openpype/scripts/non_python_host_launch.py +++ b/openpype/scripts/non_python_host_launch.py @@ -14,7 +14,7 @@ def show_error_messagebox(title, message, detail_message=None): """Function will show message and process ends after closing it.""" - from Qt import QtWidgets, QtCore + from qtpy import QtWidgets, QtCore from openpype import style app = QtWidgets.QApplication([]) From ab2299f9212bc86897cd852f6f6bbe2b7824a50a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:53:30 +0100 Subject: [PATCH 14/42] use qtpy in helper widgets --- openpype/widgets/color_widgets/color_inputs.py | 2 +- openpype/widgets/color_widgets/color_picker_widget.py | 2 +- openpype/widgets/color_widgets/color_screen_pick.py | 6 +++--- openpype/widgets/color_widgets/color_triangle.py | 2 +- openpype/widgets/color_widgets/color_view.py | 2 +- openpype/widgets/message_window.py | 2 +- openpype/widgets/nice_checkbox.py | 2 +- openpype/widgets/password_dialog.py | 2 +- openpype/widgets/popup.py | 3 +-- openpype/widgets/sliders.py | 2 +- 10 files changed, 12 insertions(+), 13 deletions(-) diff --git a/openpype/widgets/color_widgets/color_inputs.py b/openpype/widgets/color_widgets/color_inputs.py index d6564ca29bb..9c8e7b92e87 100644 --- a/openpype/widgets/color_widgets/color_inputs.py +++ b/openpype/widgets/color_widgets/color_inputs.py @@ -1,5 +1,5 @@ import re -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from .color_view import draw_checkerboard_tile diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py index 228d35a77c5..688c4f9863c 100644 --- a/openpype/widgets/color_widgets/color_picker_widget.py +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -1,5 +1,5 @@ import os -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from .color_triangle import QtColorTriangle from .color_view import ColorViewer diff --git a/openpype/widgets/color_widgets/color_screen_pick.py b/openpype/widgets/color_widgets/color_screen_pick.py index 87f50745eb9..542db2831a1 100644 --- a/openpype/widgets/color_widgets/color_screen_pick.py +++ b/openpype/widgets/color_widgets/color_screen_pick.py @@ -1,5 +1,5 @@ -import Qt -from Qt import QtWidgets, QtCore, QtGui +import qtpy +from qtpy import QtWidgets, QtCore, QtGui class PickScreenColorWidget(QtWidgets.QWidget): @@ -78,7 +78,7 @@ def pick_color(self, screen_obj): QtWidgets.QApplication.desktop().winId(), geo.x(), geo.y(), geo.width(), geo.height() ) - if Qt.__binding__ in ("PyQt4", "PySide"): + if qtpy.API in ("pyqt4", "pyside"): pix = QtGui.QPixmap.grabWindow(*args) else: pix = screen_obj.grabWindow(*args) diff --git a/openpype/widgets/color_widgets/color_triangle.py b/openpype/widgets/color_widgets/color_triangle.py index e15b9e9f650..290a33f0b07 100644 --- a/openpype/widgets/color_widgets/color_triangle.py +++ b/openpype/widgets/color_widgets/color_triangle.py @@ -1,6 +1,6 @@ from enum import Enum from math import floor, ceil, sqrt, sin, cos, acos, pi as PI -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui TWOPI = PI * 2 diff --git a/openpype/widgets/color_widgets/color_view.py b/openpype/widgets/color_widgets/color_view.py index b5fce288940..76354b6be86 100644 --- a/openpype/widgets/color_widgets/color_view.py +++ b/openpype/widgets/color_widgets/color_view.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui def draw_checkerboard_tile(piece_size=None, color_1=None, color_2=None): diff --git a/openpype/widgets/message_window.py b/openpype/widgets/message_window.py index 94e51f5d4f7..1895ba1b5d5 100644 --- a/openpype/widgets/message_window.py +++ b/openpype/widgets/message_window.py @@ -1,6 +1,6 @@ import sys import logging -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore log = logging.getLogger(__name__) diff --git a/openpype/widgets/nice_checkbox.py b/openpype/widgets/nice_checkbox.py index 6952cb41da0..d28a09a5dc2 100644 --- a/openpype/widgets/nice_checkbox.py +++ b/openpype/widgets/nice_checkbox.py @@ -1,5 +1,5 @@ from math import floor, sqrt, ceil -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.style import get_objected_colors diff --git a/openpype/widgets/password_dialog.py b/openpype/widgets/password_dialog.py index 58add7832f3..41329617168 100644 --- a/openpype/widgets/password_dialog.py +++ b/openpype/widgets/password_dialog.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype import style from openpype.resources import get_resource diff --git a/openpype/widgets/popup.py b/openpype/widgets/popup.py index 9fc33ccbb89..97a84610602 100644 --- a/openpype/widgets/popup.py +++ b/openpype/widgets/popup.py @@ -1,8 +1,7 @@ import sys import contextlib - -from Qt import QtCore, QtWidgets +from qtpy import QtCore, QtWidgets class Popup(QtWidgets.QDialog): diff --git a/openpype/widgets/sliders.py b/openpype/widgets/sliders.py index 32ade58af57..ea1e01b9eac 100644 --- a/openpype/widgets/sliders.py +++ b/openpype/widgets/sliders.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui class NiceSlider(QtWidgets.QSlider): From b03947b8d725c5f54127ce56185ab9a2435292c6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:53:37 +0100 Subject: [PATCH 15/42] use qtpy in qargparse --- openpype/vendor/python/common/qargparse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/vendor/python/common/qargparse.py b/openpype/vendor/python/common/qargparse.py index ebde9ae76d2..172c594d1dd 100644 --- a/openpype/vendor/python/common/qargparse.py +++ b/openpype/vendor/python/common/qargparse.py @@ -7,7 +7,7 @@ import logging from collections import OrderedDict as odict -from Qt import QtCore, QtWidgets, QtGui +from qtpy import QtCore, QtWidgets, QtGui import qtawesome __version__ = "0.5.2" From ddba1741da76ae64e7e4b1cd77b00bd6abd0f896 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:53:46 +0100 Subject: [PATCH 16/42] scriptsmenu is using qtpy --- .../python/common/scriptsmenu/action.py | 2 +- .../common/scriptsmenu/launchformari.py | 2 +- .../common/scriptsmenu/launchformaya.py | 2 +- .../common/scriptsmenu/launchfornuke.py | 2 +- .../python/common/scriptsmenu/scriptsmenu.py | 2 +- .../python/common/scriptsmenu/vendor/Qt.py | 1989 ----------------- .../common/scriptsmenu/vendor/__init__.py | 0 7 files changed, 5 insertions(+), 1994 deletions(-) delete mode 100644 openpype/vendor/python/common/scriptsmenu/vendor/Qt.py delete mode 100644 openpype/vendor/python/common/scriptsmenu/vendor/__init__.py diff --git a/openpype/vendor/python/common/scriptsmenu/action.py b/openpype/vendor/python/common/scriptsmenu/action.py index 5e68628406d..49b08788f9c 100644 --- a/openpype/vendor/python/common/scriptsmenu/action.py +++ b/openpype/vendor/python/common/scriptsmenu/action.py @@ -1,6 +1,6 @@ import os -from .vendor.Qt import QtWidgets +from qtpy import QtWidgets class Action(QtWidgets.QAction): diff --git a/openpype/vendor/python/common/scriptsmenu/launchformari.py b/openpype/vendor/python/common/scriptsmenu/launchformari.py index 25cfc80d96c..86362a78d3b 100644 --- a/openpype/vendor/python/common/scriptsmenu/launchformari.py +++ b/openpype/vendor/python/common/scriptsmenu/launchformari.py @@ -1,6 +1,6 @@ # Import third-party modules -from vendor.Qt import QtWidgets +from qtpy import QtWidgets # Import local modules import scriptsmenu diff --git a/openpype/vendor/python/common/scriptsmenu/launchformaya.py b/openpype/vendor/python/common/scriptsmenu/launchformaya.py index 7ad66f0ad25..01880b94d79 100644 --- a/openpype/vendor/python/common/scriptsmenu/launchformaya.py +++ b/openpype/vendor/python/common/scriptsmenu/launchformaya.py @@ -4,7 +4,7 @@ import maya.mel as mel import scriptsmenu -from .vendor.Qt import QtCore, QtWidgets +from qtpy import QtCore, QtWidgets log = logging.getLogger(__name__) diff --git a/openpype/vendor/python/common/scriptsmenu/launchfornuke.py b/openpype/vendor/python/common/scriptsmenu/launchfornuke.py index 72302a79a61..3043d22d1c5 100644 --- a/openpype/vendor/python/common/scriptsmenu/launchfornuke.py +++ b/openpype/vendor/python/common/scriptsmenu/launchfornuke.py @@ -1,5 +1,5 @@ import scriptsmenu -from .vendor.Qt import QtWidgets +from qtpy import QtWidgets def _nuke_main_window(): diff --git a/openpype/vendor/python/common/scriptsmenu/scriptsmenu.py b/openpype/vendor/python/common/scriptsmenu/scriptsmenu.py index 9e7c0949023..6f6d0b5715b 100644 --- a/openpype/vendor/python/common/scriptsmenu/scriptsmenu.py +++ b/openpype/vendor/python/common/scriptsmenu/scriptsmenu.py @@ -3,7 +3,7 @@ import logging from collections import defaultdict -from .vendor.Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from . import action log = logging.getLogger(__name__) diff --git a/openpype/vendor/python/common/scriptsmenu/vendor/Qt.py b/openpype/vendor/python/common/scriptsmenu/vendor/Qt.py deleted file mode 100644 index fe4b45f18fe..00000000000 --- a/openpype/vendor/python/common/scriptsmenu/vendor/Qt.py +++ /dev/null @@ -1,1989 +0,0 @@ -"""Minimal Python 2 & 3 shim around all Qt bindings - -DOCUMENTATION - Qt.py was born in the film and visual effects industry to address - the growing need for the development of software capable of running - with more than one flavour of the Qt bindings for Python - PySide, - PySide2, PyQt4 and PyQt5. - - 1. Build for one, run with all - 2. Explicit is better than implicit - 3. Support co-existence - - Default resolution order: - - PySide2 - - PyQt5 - - PySide - - PyQt4 - - Usage: - >> import sys - >> from Qt import QtWidgets - >> app = QtWidgets.QApplication(sys.argv) - >> button = QtWidgets.QPushButton("Hello World") - >> button.show() - >> app.exec_() - - All members of PySide2 are mapped from other bindings, should they exist. - If no equivalent member exist, it is excluded from Qt.py and inaccessible. - The idea is to highlight members that exist across all supported binding, - and guarantee that code that runs on one binding runs on all others. - - For more details, visit https://github.com/mottosso/Qt.py - -LICENSE - - See end of file for license (MIT, BSD) information. - -""" - -import os -import sys -import types -import shutil -import importlib - - -__version__ = "1.2.3" - -# Enable support for `from Qt import *` -__all__ = [] - -# Flags from environment variables -QT_VERBOSE = bool(os.getenv("QT_VERBOSE")) -QT_PREFERRED_BINDING = os.getenv("QT_PREFERRED_BINDING", "") -QT_SIP_API_HINT = os.getenv("QT_SIP_API_HINT") - -# Reference to Qt.py -Qt = sys.modules[__name__] -Qt.QtCompat = types.ModuleType("QtCompat") - -try: - long -except NameError: - # Python 3 compatibility - long = int - - -"""Common members of all bindings - -This is where each member of Qt.py is explicitly defined. -It is based on a "lowest common denominator" of all bindings; -including members found in each of the 4 bindings. - -The "_common_members" dictionary is generated using the -build_membership.sh script. - -""" - -_common_members = { - "QtCore": [ - "QAbstractAnimation", - "QAbstractEventDispatcher", - "QAbstractItemModel", - "QAbstractListModel", - "QAbstractState", - "QAbstractTableModel", - "QAbstractTransition", - "QAnimationGroup", - "QBasicTimer", - "QBitArray", - "QBuffer", - "QByteArray", - "QByteArrayMatcher", - "QChildEvent", - "QCoreApplication", - "QCryptographicHash", - "QDataStream", - "QDate", - "QDateTime", - "QDir", - "QDirIterator", - "QDynamicPropertyChangeEvent", - "QEasingCurve", - "QElapsedTimer", - "QEvent", - "QEventLoop", - "QEventTransition", - "QFile", - "QFileInfo", - "QFileSystemWatcher", - "QFinalState", - "QGenericArgument", - "QGenericReturnArgument", - "QHistoryState", - "QItemSelectionRange", - "QIODevice", - "QLibraryInfo", - "QLine", - "QLineF", - "QLocale", - "QMargins", - "QMetaClassInfo", - "QMetaEnum", - "QMetaMethod", - "QMetaObject", - "QMetaProperty", - "QMimeData", - "QModelIndex", - "QMutex", - "QMutexLocker", - "QObject", - "QParallelAnimationGroup", - "QPauseAnimation", - "QPersistentModelIndex", - "QPluginLoader", - "QPoint", - "QPointF", - "QProcess", - "QProcessEnvironment", - "QPropertyAnimation", - "QReadLocker", - "QReadWriteLock", - "QRect", - "QRectF", - "QRegExp", - "QResource", - "QRunnable", - "QSemaphore", - "QSequentialAnimationGroup", - "QSettings", - "QSignalMapper", - "QSignalTransition", - "QSize", - "QSizeF", - "QSocketNotifier", - "QState", - "QStateMachine", - "QSysInfo", - "QSystemSemaphore", - "QT_TRANSLATE_NOOP", - "QT_TR_NOOP", - "QT_TR_NOOP_UTF8", - "QTemporaryFile", - "QTextBoundaryFinder", - "QTextCodec", - "QTextDecoder", - "QTextEncoder", - "QTextStream", - "QTextStreamManipulator", - "QThread", - "QThreadPool", - "QTime", - "QTimeLine", - "QTimer", - "QTimerEvent", - "QTranslator", - "QUrl", - "QVariantAnimation", - "QWaitCondition", - "QWriteLocker", - "QXmlStreamAttribute", - "QXmlStreamAttributes", - "QXmlStreamEntityDeclaration", - "QXmlStreamEntityResolver", - "QXmlStreamNamespaceDeclaration", - "QXmlStreamNotationDeclaration", - "QXmlStreamReader", - "QXmlStreamWriter", - "Qt", - "QtCriticalMsg", - "QtDebugMsg", - "QtFatalMsg", - "QtMsgType", - "QtSystemMsg", - "QtWarningMsg", - "qAbs", - "qAddPostRoutine", - "qChecksum", - "qCritical", - "qDebug", - "qFatal", - "qFuzzyCompare", - "qIsFinite", - "qIsInf", - "qIsNaN", - "qIsNull", - "qRegisterResourceData", - "qUnregisterResourceData", - "qVersion", - "qWarning", - "qrand", - "qsrand" - ], - "QtGui": [ - "QAbstractTextDocumentLayout", - "QActionEvent", - "QBitmap", - "QBrush", - "QClipboard", - "QCloseEvent", - "QColor", - "QConicalGradient", - "QContextMenuEvent", - "QCursor", - "QDesktopServices", - "QDoubleValidator", - "QDrag", - "QDragEnterEvent", - "QDragLeaveEvent", - "QDragMoveEvent", - "QDropEvent", - "QFileOpenEvent", - "QFocusEvent", - "QFont", - "QFontDatabase", - "QFontInfo", - "QFontMetrics", - "QFontMetricsF", - "QGradient", - "QHelpEvent", - "QHideEvent", - "QHoverEvent", - "QIcon", - "QIconDragEvent", - "QIconEngine", - "QImage", - "QImageIOHandler", - "QImageReader", - "QImageWriter", - "QInputEvent", - "QInputMethodEvent", - "QIntValidator", - "QKeyEvent", - "QKeySequence", - "QLinearGradient", - "QMatrix2x2", - "QMatrix2x3", - "QMatrix2x4", - "QMatrix3x2", - "QMatrix3x3", - "QMatrix3x4", - "QMatrix4x2", - "QMatrix4x3", - "QMatrix4x4", - "QMouseEvent", - "QMoveEvent", - "QMovie", - "QPaintDevice", - "QPaintEngine", - "QPaintEngineState", - "QPaintEvent", - "QPainter", - "QPainterPath", - "QPainterPathStroker", - "QPalette", - "QPen", - "QPicture", - "QPictureIO", - "QPixmap", - "QPixmapCache", - "QPolygon", - "QPolygonF", - "QQuaternion", - "QRadialGradient", - "QRegExpValidator", - "QRegion", - "QResizeEvent", - "QSessionManager", - "QShortcutEvent", - "QShowEvent", - "QStandardItem", - "QStandardItemModel", - "QStatusTipEvent", - "QSyntaxHighlighter", - "QTabletEvent", - "QTextBlock", - "QTextBlockFormat", - "QTextBlockGroup", - "QTextBlockUserData", - "QTextCharFormat", - "QTextCursor", - "QTextDocument", - "QTextDocumentFragment", - "QTextFormat", - "QTextFragment", - "QTextFrame", - "QTextFrameFormat", - "QTextImageFormat", - "QTextInlineObject", - "QTextItem", - "QTextLayout", - "QTextLength", - "QTextLine", - "QTextList", - "QTextListFormat", - "QTextObject", - "QTextObjectInterface", - "QTextOption", - "QTextTable", - "QTextTableCell", - "QTextTableCellFormat", - "QTextTableFormat", - "QTouchEvent", - "QTransform", - "QValidator", - "QVector2D", - "QVector3D", - "QVector4D", - "QWhatsThisClickedEvent", - "QWheelEvent", - "QWindowStateChangeEvent", - "qAlpha", - "qBlue", - "qGray", - "qGreen", - "qIsGray", - "qRed", - "qRgb", - "qRgba" - ], - "QtHelp": [ - "QHelpContentItem", - "QHelpContentModel", - "QHelpContentWidget", - "QHelpEngine", - "QHelpEngineCore", - "QHelpIndexModel", - "QHelpIndexWidget", - "QHelpSearchEngine", - "QHelpSearchQuery", - "QHelpSearchQueryWidget", - "QHelpSearchResultWidget" - ], - "QtMultimedia": [ - "QAbstractVideoBuffer", - "QAbstractVideoSurface", - "QAudio", - "QAudioDeviceInfo", - "QAudioFormat", - "QAudioInput", - "QAudioOutput", - "QVideoFrame", - "QVideoSurfaceFormat" - ], - "QtNetwork": [ - "QAbstractNetworkCache", - "QAbstractSocket", - "QAuthenticator", - "QHostAddress", - "QHostInfo", - "QLocalServer", - "QLocalSocket", - "QNetworkAccessManager", - "QNetworkAddressEntry", - "QNetworkCacheMetaData", - "QNetworkConfiguration", - "QNetworkConfigurationManager", - "QNetworkCookie", - "QNetworkCookieJar", - "QNetworkDiskCache", - "QNetworkInterface", - "QNetworkProxy", - "QNetworkProxyFactory", - "QNetworkProxyQuery", - "QNetworkReply", - "QNetworkRequest", - "QNetworkSession", - "QSsl", - "QTcpServer", - "QTcpSocket", - "QUdpSocket" - ], - "QtOpenGL": [ - "QGL", - "QGLContext", - "QGLFormat", - "QGLWidget" - ], - "QtPrintSupport": [ - "QAbstractPrintDialog", - "QPageSetupDialog", - "QPrintDialog", - "QPrintEngine", - "QPrintPreviewDialog", - "QPrintPreviewWidget", - "QPrinter", - "QPrinterInfo" - ], - "QtSql": [ - "QSql", - "QSqlDatabase", - "QSqlDriver", - "QSqlDriverCreatorBase", - "QSqlError", - "QSqlField", - "QSqlIndex", - "QSqlQuery", - "QSqlQueryModel", - "QSqlRecord", - "QSqlRelation", - "QSqlRelationalDelegate", - "QSqlRelationalTableModel", - "QSqlResult", - "QSqlTableModel" - ], - "QtSvg": [ - "QGraphicsSvgItem", - "QSvgGenerator", - "QSvgRenderer", - "QSvgWidget" - ], - "QtTest": [ - "QTest" - ], - "QtWidgets": [ - "QAbstractButton", - "QAbstractGraphicsShapeItem", - "QAbstractItemDelegate", - "QAbstractItemView", - "QAbstractScrollArea", - "QAbstractSlider", - "QAbstractSpinBox", - "QAction", - "QActionGroup", - "QApplication", - "QBoxLayout", - "QButtonGroup", - "QCalendarWidget", - "QCheckBox", - "QColorDialog", - "QColumnView", - "QComboBox", - "QCommandLinkButton", - "QCommonStyle", - "QCompleter", - "QDataWidgetMapper", - "QDateEdit", - "QDateTimeEdit", - "QDesktopWidget", - "QDial", - "QDialog", - "QDialogButtonBox", - "QDirModel", - "QDockWidget", - "QDoubleSpinBox", - "QErrorMessage", - "QFileDialog", - "QFileIconProvider", - "QFileSystemModel", - "QFocusFrame", - "QFontComboBox", - "QFontDialog", - "QFormLayout", - "QFrame", - "QGesture", - "QGestureEvent", - "QGestureRecognizer", - "QGraphicsAnchor", - "QGraphicsAnchorLayout", - "QGraphicsBlurEffect", - "QGraphicsColorizeEffect", - "QGraphicsDropShadowEffect", - "QGraphicsEffect", - "QGraphicsEllipseItem", - "QGraphicsGridLayout", - "QGraphicsItem", - "QGraphicsItemGroup", - "QGraphicsLayout", - "QGraphicsLayoutItem", - "QGraphicsLineItem", - "QGraphicsLinearLayout", - "QGraphicsObject", - "QGraphicsOpacityEffect", - "QGraphicsPathItem", - "QGraphicsPixmapItem", - "QGraphicsPolygonItem", - "QGraphicsProxyWidget", - "QGraphicsRectItem", - "QGraphicsRotation", - "QGraphicsScale", - "QGraphicsScene", - "QGraphicsSceneContextMenuEvent", - "QGraphicsSceneDragDropEvent", - "QGraphicsSceneEvent", - "QGraphicsSceneHelpEvent", - "QGraphicsSceneHoverEvent", - "QGraphicsSceneMouseEvent", - "QGraphicsSceneMoveEvent", - "QGraphicsSceneResizeEvent", - "QGraphicsSceneWheelEvent", - "QGraphicsSimpleTextItem", - "QGraphicsTextItem", - "QGraphicsTransform", - "QGraphicsView", - "QGraphicsWidget", - "QGridLayout", - "QGroupBox", - "QHBoxLayout", - "QHeaderView", - "QInputDialog", - "QItemDelegate", - "QItemEditorCreatorBase", - "QItemEditorFactory", - "QKeyEventTransition", - "QLCDNumber", - "QLabel", - "QLayout", - "QLayoutItem", - "QLineEdit", - "QListView", - "QListWidget", - "QListWidgetItem", - "QMainWindow", - "QMdiArea", - "QMdiSubWindow", - "QMenu", - "QMenuBar", - "QMessageBox", - "QMouseEventTransition", - "QPanGesture", - "QPinchGesture", - "QPlainTextDocumentLayout", - "QPlainTextEdit", - "QProgressBar", - "QProgressDialog", - "QPushButton", - "QRadioButton", - "QRubberBand", - "QScrollArea", - "QScrollBar", - "QShortcut", - "QSizeGrip", - "QSizePolicy", - "QSlider", - "QSpacerItem", - "QSpinBox", - "QSplashScreen", - "QSplitter", - "QSplitterHandle", - "QStackedLayout", - "QStackedWidget", - "QStatusBar", - "QStyle", - "QStyleFactory", - "QStyleHintReturn", - "QStyleHintReturnMask", - "QStyleHintReturnVariant", - "QStyleOption", - "QStyleOptionButton", - "QStyleOptionComboBox", - "QStyleOptionComplex", - "QStyleOptionDockWidget", - "QStyleOptionFocusRect", - "QStyleOptionFrame", - "QStyleOptionGraphicsItem", - "QStyleOptionGroupBox", - "QStyleOptionHeader", - "QStyleOptionMenuItem", - "QStyleOptionProgressBar", - "QStyleOptionRubberBand", - "QStyleOptionSizeGrip", - "QStyleOptionSlider", - "QStyleOptionSpinBox", - "QStyleOptionTab", - "QStyleOptionTabBarBase", - "QStyleOptionTabWidgetFrame", - "QStyleOptionTitleBar", - "QStyleOptionToolBar", - "QStyleOptionToolBox", - "QStyleOptionToolButton", - "QStyleOptionViewItem", - "QStylePainter", - "QStyledItemDelegate", - "QSwipeGesture", - "QSystemTrayIcon", - "QTabBar", - "QTabWidget", - "QTableView", - "QTableWidget", - "QTableWidgetItem", - "QTableWidgetSelectionRange", - "QTapAndHoldGesture", - "QTapGesture", - "QTextBrowser", - "QTextEdit", - "QTimeEdit", - "QToolBar", - "QToolBox", - "QToolButton", - "QToolTip", - "QTreeView", - "QTreeWidget", - "QTreeWidgetItem", - "QTreeWidgetItemIterator", - "QUndoCommand", - "QUndoGroup", - "QUndoStack", - "QUndoView", - "QVBoxLayout", - "QWhatsThis", - "QWidget", - "QWidgetAction", - "QWidgetItem", - "QWizard", - "QWizardPage" - ], - "QtX11Extras": [ - "QX11Info" - ], - "QtXml": [ - "QDomAttr", - "QDomCDATASection", - "QDomCharacterData", - "QDomComment", - "QDomDocument", - "QDomDocumentFragment", - "QDomDocumentType", - "QDomElement", - "QDomEntity", - "QDomEntityReference", - "QDomImplementation", - "QDomNamedNodeMap", - "QDomNode", - "QDomNodeList", - "QDomNotation", - "QDomProcessingInstruction", - "QDomText", - "QXmlAttributes", - "QXmlContentHandler", - "QXmlDTDHandler", - "QXmlDeclHandler", - "QXmlDefaultHandler", - "QXmlEntityResolver", - "QXmlErrorHandler", - "QXmlInputSource", - "QXmlLexicalHandler", - "QXmlLocator", - "QXmlNamespaceSupport", - "QXmlParseException", - "QXmlReader", - "QXmlSimpleReader" - ], - "QtXmlPatterns": [ - "QAbstractMessageHandler", - "QAbstractUriResolver", - "QAbstractXmlNodeModel", - "QAbstractXmlReceiver", - "QSourceLocation", - "QXmlFormatter", - "QXmlItem", - "QXmlName", - "QXmlNamePool", - "QXmlNodeModelIndex", - "QXmlQuery", - "QXmlResultItems", - "QXmlSchema", - "QXmlSchemaValidator", - "QXmlSerializer" - ] -} - -""" Missing members - -This mapping describes members that have been deprecated -in one or more bindings and have been left out of the -_common_members mapping. - -The member can provide an extra details string to be -included in exceptions and warnings. -""" - -_missing_members = { - "QtGui": { - "QMatrix": "Deprecated in PyQt5", - }, -} - - -def _qInstallMessageHandler(handler): - """Install a message handler that works in all bindings - - Args: - handler: A function that takes 3 arguments, or None - """ - def messageOutputHandler(*args): - # In Qt4 bindings, message handlers are passed 2 arguments - # In Qt5 bindings, message handlers are passed 3 arguments - # The first argument is a QtMsgType - # The last argument is the message to be printed - # The Middle argument (if passed) is a QMessageLogContext - if len(args) == 3: - msgType, logContext, msg = args - elif len(args) == 2: - msgType, msg = args - logContext = None - else: - raise TypeError( - "handler expected 2 or 3 arguments, got {0}".format(len(args))) - - if isinstance(msg, bytes): - # In python 3, some bindings pass a bytestring, which cannot be - # used elsewhere. Decoding a python 2 or 3 bytestring object will - # consistently return a unicode object. - msg = msg.decode() - - handler(msgType, logContext, msg) - - passObject = messageOutputHandler if handler else handler - if Qt.IsPySide or Qt.IsPyQt4: - return Qt._QtCore.qInstallMsgHandler(passObject) - elif Qt.IsPySide2 or Qt.IsPyQt5: - return Qt._QtCore.qInstallMessageHandler(passObject) - - -def _getcpppointer(object): - if hasattr(Qt, "_shiboken2"): - return getattr(Qt, "_shiboken2").getCppPointer(object)[0] - elif hasattr(Qt, "_shiboken"): - return getattr(Qt, "_shiboken").getCppPointer(object)[0] - elif hasattr(Qt, "_sip"): - return getattr(Qt, "_sip").unwrapinstance(object) - raise AttributeError("'module' has no attribute 'getCppPointer'") - - -def _wrapinstance(ptr, base=None): - """Enable implicit cast of pointer to most suitable class - - This behaviour is available in sip per default. - - Based on http://nathanhorne.com/pyqtpyside-wrap-instance - - Usage: - This mechanism kicks in under these circumstances. - 1. Qt.py is using PySide 1 or 2. - 2. A `base` argument is not provided. - - See :func:`QtCompat.wrapInstance()` - - Arguments: - ptr (long): Pointer to QObject in memory - base (QObject, optional): Base class to wrap with. Defaults to QObject, - which should handle anything. - - """ - - assert isinstance(ptr, long), "Argument 'ptr' must be of type " - assert (base is None) or issubclass(base, Qt.QtCore.QObject), ( - "Argument 'base' must be of type ") - - if Qt.IsPyQt4 or Qt.IsPyQt5: - func = getattr(Qt, "_sip").wrapinstance - elif Qt.IsPySide2: - func = getattr(Qt, "_shiboken2").wrapInstance - elif Qt.IsPySide: - func = getattr(Qt, "_shiboken").wrapInstance - else: - raise AttributeError("'module' has no attribute 'wrapInstance'") - - if base is None: - q_object = func(long(ptr), Qt.QtCore.QObject) - meta_object = q_object.metaObject() - class_name = meta_object.className() - super_class_name = meta_object.superClass().className() - - if hasattr(Qt.QtWidgets, class_name): - base = getattr(Qt.QtWidgets, class_name) - - elif hasattr(Qt.QtWidgets, super_class_name): - base = getattr(Qt.QtWidgets, super_class_name) - - else: - base = Qt.QtCore.QObject - - return func(long(ptr), base) - - -def _isvalid(object): - """Check if the object is valid to use in Python runtime. - - Usage: - See :func:`QtCompat.isValid()` - - Arguments: - object (QObject): QObject to check the validity of. - - """ - - assert isinstance(object, Qt.QtCore.QObject) - - if hasattr(Qt, "_shiboken2"): - return getattr(Qt, "_shiboken2").isValid(object) - - elif hasattr(Qt, "_shiboken"): - return getattr(Qt, "_shiboken").isValid(object) - - elif hasattr(Qt, "_sip"): - return not getattr(Qt, "_sip").isdeleted(object) - - else: - raise AttributeError("'module' has no attribute isValid") - - -def _translate(context, sourceText, *args): - # In Qt4 bindings, translate can be passed 2 or 3 arguments - # In Qt5 bindings, translate can be passed 2 arguments - # The first argument is disambiguation[str] - # The last argument is n[int] - # The middle argument can be encoding[QtCore.QCoreApplication.Encoding] - if len(args) == 3: - disambiguation, encoding, n = args - elif len(args) == 2: - disambiguation, n = args - encoding = None - else: - raise TypeError( - "Expected 4 or 5 arguments, got {0}.".format(len(args) + 2)) - - if hasattr(Qt.QtCore, "QCoreApplication"): - app = getattr(Qt.QtCore, "QCoreApplication") - else: - raise NotImplementedError( - "Missing QCoreApplication implementation for {binding}".format( - binding=Qt.__binding__, - ) - ) - if Qt.__binding__ in ("PySide2", "PyQt5"): - sanitized_args = [context, sourceText, disambiguation, n] - else: - sanitized_args = [ - context, - sourceText, - disambiguation, - encoding or app.CodecForTr, - n - ] - return app.translate(*sanitized_args) - - -def _loadUi(uifile, baseinstance=None): - """Dynamically load a user interface from the given `uifile` - - This function calls `uic.loadUi` if using PyQt bindings, - else it implements a comparable binding for PySide. - - Documentation: - http://pyqt.sourceforge.net/Docs/PyQt5/designer.html#PyQt5.uic.loadUi - - Arguments: - uifile (str): Absolute path to Qt Designer file. - baseinstance (QWidget): Instantiated QWidget or subclass thereof - - Return: - baseinstance if `baseinstance` is not `None`. Otherwise - return the newly created instance of the user interface. - - """ - if hasattr(Qt, "_uic"): - return Qt._uic.loadUi(uifile, baseinstance) - - elif hasattr(Qt, "_QtUiTools"): - # Implement `PyQt5.uic.loadUi` for PySide(2) - - class _UiLoader(Qt._QtUiTools.QUiLoader): - """Create the user interface in a base instance. - - Unlike `Qt._QtUiTools.QUiLoader` itself this class does not - create a new instance of the top-level widget, but creates the user - interface in an existing instance of the top-level class if needed. - - This mimics the behaviour of `PyQt5.uic.loadUi`. - - """ - - def __init__(self, baseinstance): - super(_UiLoader, self).__init__(baseinstance) - self.baseinstance = baseinstance - self.custom_widgets = {} - - def _loadCustomWidgets(self, etree): - """ - Workaround to pyside-77 bug. - - From QUiLoader doc we should use registerCustomWidget method. - But this causes a segfault on some platforms. - - Instead we fetch from customwidgets DOM node the python class - objects. Then we can directly use them in createWidget method. - """ - - def headerToModule(header): - """ - Translate a header file to python module path - foo/bar.h => foo.bar - """ - # Remove header extension - module = os.path.splitext(header)[0] - - # Replace os separator by python module separator - return module.replace("/", ".").replace("\\", ".") - - custom_widgets = etree.find("customwidgets") - - if custom_widgets is None: - return - - for custom_widget in custom_widgets: - class_name = custom_widget.find("class").text - header = custom_widget.find("header").text - module = importlib.import_module(headerToModule(header)) - self.custom_widgets[class_name] = getattr(module, - class_name) - - def load(self, uifile, *args, **kwargs): - from xml.etree.ElementTree import ElementTree - - # For whatever reason, if this doesn't happen then - # reading an invalid or non-existing .ui file throws - # a RuntimeError. - etree = ElementTree() - etree.parse(uifile) - self._loadCustomWidgets(etree) - - widget = Qt._QtUiTools.QUiLoader.load( - self, uifile, *args, **kwargs) - - # Workaround for PySide 1.0.9, see issue #208 - widget.parentWidget() - - return widget - - def createWidget(self, class_name, parent=None, name=""): - """Called for each widget defined in ui file - - Overridden here to populate `baseinstance` instead. - - """ - - if parent is None and self.baseinstance: - # Supposed to create the top-level widget, - # return the base instance instead - return self.baseinstance - - # For some reason, Line is not in the list of available - # widgets, but works fine, so we have to special case it here. - if class_name in self.availableWidgets() + ["Line"]: - # Create a new widget for child widgets - widget = Qt._QtUiTools.QUiLoader.createWidget(self, - class_name, - parent, - name) - elif class_name in self.custom_widgets: - widget = self.custom_widgets[class_name](parent) - else: - raise Exception("Custom widget '%s' not supported" - % class_name) - - if self.baseinstance: - # Set an attribute for the new child widget on the base - # instance, just like PyQt5.uic.loadUi does. - setattr(self.baseinstance, name, widget) - - return widget - - widget = _UiLoader(baseinstance).load(uifile) - Qt.QtCore.QMetaObject.connectSlotsByName(widget) - - return widget - - else: - raise NotImplementedError("No implementation available for loadUi") - - -"""Misplaced members - -These members from the original submodule are misplaced relative PySide2 - -""" -_misplaced_members = { - "PySide2": { - "QtCore.QStringListModel": "QtCore.QStringListModel", - "QtGui.QStringListModel": "QtCore.QStringListModel", - "QtCore.Property": "QtCore.Property", - "QtCore.Signal": "QtCore.Signal", - "QtCore.Slot": "QtCore.Slot", - "QtCore.QAbstractProxyModel": "QtCore.QAbstractProxyModel", - "QtCore.QSortFilterProxyModel": "QtCore.QSortFilterProxyModel", - "QtCore.QItemSelection": "QtCore.QItemSelection", - "QtCore.QItemSelectionModel": "QtCore.QItemSelectionModel", - "QtCore.QItemSelectionRange": "QtCore.QItemSelectionRange", - "QtUiTools.QUiLoader": ["QtCompat.loadUi", _loadUi], - "shiboken2.wrapInstance": ["QtCompat.wrapInstance", _wrapinstance], - "shiboken2.getCppPointer": ["QtCompat.getCppPointer", _getcpppointer], - "shiboken2.isValid": ["QtCompat.isValid", _isvalid], - "QtWidgets.qApp": "QtWidgets.QApplication.instance()", - "QtCore.QCoreApplication.translate": [ - "QtCompat.translate", _translate - ], - "QtWidgets.QApplication.translate": [ - "QtCompat.translate", _translate - ], - "QtCore.qInstallMessageHandler": [ - "QtCompat.qInstallMessageHandler", _qInstallMessageHandler - ], - "QtWidgets.QStyleOptionViewItem": "QtCompat.QStyleOptionViewItemV4", - }, - "PyQt5": { - "QtCore.pyqtProperty": "QtCore.Property", - "QtCore.pyqtSignal": "QtCore.Signal", - "QtCore.pyqtSlot": "QtCore.Slot", - "QtCore.QAbstractProxyModel": "QtCore.QAbstractProxyModel", - "QtCore.QSortFilterProxyModel": "QtCore.QSortFilterProxyModel", - "QtCore.QStringListModel": "QtCore.QStringListModel", - "QtCore.QItemSelection": "QtCore.QItemSelection", - "QtCore.QItemSelectionModel": "QtCore.QItemSelectionModel", - "QtCore.QItemSelectionRange": "QtCore.QItemSelectionRange", - "uic.loadUi": ["QtCompat.loadUi", _loadUi], - "sip.wrapinstance": ["QtCompat.wrapInstance", _wrapinstance], - "sip.unwrapinstance": ["QtCompat.getCppPointer", _getcpppointer], - "sip.isdeleted": ["QtCompat.isValid", _isvalid], - "QtWidgets.qApp": "QtWidgets.QApplication.instance()", - "QtCore.QCoreApplication.translate": [ - "QtCompat.translate", _translate - ], - "QtWidgets.QApplication.translate": [ - "QtCompat.translate", _translate - ], - "QtCore.qInstallMessageHandler": [ - "QtCompat.qInstallMessageHandler", _qInstallMessageHandler - ], - "QtWidgets.QStyleOptionViewItem": "QtCompat.QStyleOptionViewItemV4", - }, - "PySide": { - "QtGui.QAbstractProxyModel": "QtCore.QAbstractProxyModel", - "QtGui.QSortFilterProxyModel": "QtCore.QSortFilterProxyModel", - "QtGui.QStringListModel": "QtCore.QStringListModel", - "QtGui.QItemSelection": "QtCore.QItemSelection", - "QtGui.QItemSelectionModel": "QtCore.QItemSelectionModel", - "QtCore.Property": "QtCore.Property", - "QtCore.Signal": "QtCore.Signal", - "QtCore.Slot": "QtCore.Slot", - "QtGui.QItemSelectionRange": "QtCore.QItemSelectionRange", - "QtGui.QAbstractPrintDialog": "QtPrintSupport.QAbstractPrintDialog", - "QtGui.QPageSetupDialog": "QtPrintSupport.QPageSetupDialog", - "QtGui.QPrintDialog": "QtPrintSupport.QPrintDialog", - "QtGui.QPrintEngine": "QtPrintSupport.QPrintEngine", - "QtGui.QPrintPreviewDialog": "QtPrintSupport.QPrintPreviewDialog", - "QtGui.QPrintPreviewWidget": "QtPrintSupport.QPrintPreviewWidget", - "QtGui.QPrinter": "QtPrintSupport.QPrinter", - "QtGui.QPrinterInfo": "QtPrintSupport.QPrinterInfo", - "QtUiTools.QUiLoader": ["QtCompat.loadUi", _loadUi], - "shiboken.wrapInstance": ["QtCompat.wrapInstance", _wrapinstance], - "shiboken.unwrapInstance": ["QtCompat.getCppPointer", _getcpppointer], - "shiboken.isValid": ["QtCompat.isValid", _isvalid], - "QtGui.qApp": "QtWidgets.QApplication.instance()", - "QtCore.QCoreApplication.translate": [ - "QtCompat.translate", _translate - ], - "QtGui.QApplication.translate": [ - "QtCompat.translate", _translate - ], - "QtCore.qInstallMsgHandler": [ - "QtCompat.qInstallMessageHandler", _qInstallMessageHandler - ], - "QtGui.QStyleOptionViewItemV4": "QtCompat.QStyleOptionViewItemV4", - }, - "PyQt4": { - "QtGui.QAbstractProxyModel": "QtCore.QAbstractProxyModel", - "QtGui.QSortFilterProxyModel": "QtCore.QSortFilterProxyModel", - "QtGui.QItemSelection": "QtCore.QItemSelection", - "QtGui.QStringListModel": "QtCore.QStringListModel", - "QtGui.QItemSelectionModel": "QtCore.QItemSelectionModel", - "QtCore.pyqtProperty": "QtCore.Property", - "QtCore.pyqtSignal": "QtCore.Signal", - "QtCore.pyqtSlot": "QtCore.Slot", - "QtGui.QItemSelectionRange": "QtCore.QItemSelectionRange", - "QtGui.QAbstractPrintDialog": "QtPrintSupport.QAbstractPrintDialog", - "QtGui.QPageSetupDialog": "QtPrintSupport.QPageSetupDialog", - "QtGui.QPrintDialog": "QtPrintSupport.QPrintDialog", - "QtGui.QPrintEngine": "QtPrintSupport.QPrintEngine", - "QtGui.QPrintPreviewDialog": "QtPrintSupport.QPrintPreviewDialog", - "QtGui.QPrintPreviewWidget": "QtPrintSupport.QPrintPreviewWidget", - "QtGui.QPrinter": "QtPrintSupport.QPrinter", - "QtGui.QPrinterInfo": "QtPrintSupport.QPrinterInfo", - # "QtCore.pyqtSignature": "QtCore.Slot", - "uic.loadUi": ["QtCompat.loadUi", _loadUi], - "sip.wrapinstance": ["QtCompat.wrapInstance", _wrapinstance], - "sip.unwrapinstance": ["QtCompat.getCppPointer", _getcpppointer], - "sip.isdeleted": ["QtCompat.isValid", _isvalid], - "QtCore.QString": "str", - "QtGui.qApp": "QtWidgets.QApplication.instance()", - "QtCore.QCoreApplication.translate": [ - "QtCompat.translate", _translate - ], - "QtGui.QApplication.translate": [ - "QtCompat.translate", _translate - ], - "QtCore.qInstallMsgHandler": [ - "QtCompat.qInstallMessageHandler", _qInstallMessageHandler - ], - "QtGui.QStyleOptionViewItemV4": "QtCompat.QStyleOptionViewItemV4", - } -} - -""" Compatibility Members - -This dictionary is used to build Qt.QtCompat objects that provide a consistent -interface for obsolete members, and differences in binding return values. - -{ - "binding": { - "classname": { - "targetname": "binding_namespace", - } - } -} -""" -_compatibility_members = { - "PySide2": { - "QWidget": { - "grab": "QtWidgets.QWidget.grab", - }, - "QHeaderView": { - "sectionsClickable": "QtWidgets.QHeaderView.sectionsClickable", - "setSectionsClickable": - "QtWidgets.QHeaderView.setSectionsClickable", - "sectionResizeMode": "QtWidgets.QHeaderView.sectionResizeMode", - "setSectionResizeMode": - "QtWidgets.QHeaderView.setSectionResizeMode", - "sectionsMovable": "QtWidgets.QHeaderView.sectionsMovable", - "setSectionsMovable": "QtWidgets.QHeaderView.setSectionsMovable", - }, - "QFileDialog": { - "getOpenFileName": "QtWidgets.QFileDialog.getOpenFileName", - "getOpenFileNames": "QtWidgets.QFileDialog.getOpenFileNames", - "getSaveFileName": "QtWidgets.QFileDialog.getSaveFileName", - }, - }, - "PyQt5": { - "QWidget": { - "grab": "QtWidgets.QWidget.grab", - }, - "QHeaderView": { - "sectionsClickable": "QtWidgets.QHeaderView.sectionsClickable", - "setSectionsClickable": - "QtWidgets.QHeaderView.setSectionsClickable", - "sectionResizeMode": "QtWidgets.QHeaderView.sectionResizeMode", - "setSectionResizeMode": - "QtWidgets.QHeaderView.setSectionResizeMode", - "sectionsMovable": "QtWidgets.QHeaderView.sectionsMovable", - "setSectionsMovable": "QtWidgets.QHeaderView.setSectionsMovable", - }, - "QFileDialog": { - "getOpenFileName": "QtWidgets.QFileDialog.getOpenFileName", - "getOpenFileNames": "QtWidgets.QFileDialog.getOpenFileNames", - "getSaveFileName": "QtWidgets.QFileDialog.getSaveFileName", - }, - }, - "PySide": { - "QWidget": { - "grab": "QtWidgets.QPixmap.grabWidget", - }, - "QHeaderView": { - "sectionsClickable": "QtWidgets.QHeaderView.isClickable", - "setSectionsClickable": "QtWidgets.QHeaderView.setClickable", - "sectionResizeMode": "QtWidgets.QHeaderView.resizeMode", - "setSectionResizeMode": "QtWidgets.QHeaderView.setResizeMode", - "sectionsMovable": "QtWidgets.QHeaderView.isMovable", - "setSectionsMovable": "QtWidgets.QHeaderView.setMovable", - }, - "QFileDialog": { - "getOpenFileName": "QtWidgets.QFileDialog.getOpenFileName", - "getOpenFileNames": "QtWidgets.QFileDialog.getOpenFileNames", - "getSaveFileName": "QtWidgets.QFileDialog.getSaveFileName", - }, - }, - "PyQt4": { - "QWidget": { - "grab": "QtWidgets.QPixmap.grabWidget", - }, - "QHeaderView": { - "sectionsClickable": "QtWidgets.QHeaderView.isClickable", - "setSectionsClickable": "QtWidgets.QHeaderView.setClickable", - "sectionResizeMode": "QtWidgets.QHeaderView.resizeMode", - "setSectionResizeMode": "QtWidgets.QHeaderView.setResizeMode", - "sectionsMovable": "QtWidgets.QHeaderView.isMovable", - "setSectionsMovable": "QtWidgets.QHeaderView.setMovable", - }, - "QFileDialog": { - "getOpenFileName": "QtWidgets.QFileDialog.getOpenFileName", - "getOpenFileNames": "QtWidgets.QFileDialog.getOpenFileNames", - "getSaveFileName": "QtWidgets.QFileDialog.getSaveFileName", - }, - }, -} - - -def _apply_site_config(): - try: - import QtSiteConfig - except ImportError: - # If no QtSiteConfig module found, no modifications - # to _common_members are needed. - pass - else: - # Provide the ability to modify the dicts used to build Qt.py - if hasattr(QtSiteConfig, 'update_members'): - QtSiteConfig.update_members(_common_members) - - if hasattr(QtSiteConfig, 'update_misplaced_members'): - QtSiteConfig.update_misplaced_members(members=_misplaced_members) - - if hasattr(QtSiteConfig, 'update_compatibility_members'): - QtSiteConfig.update_compatibility_members( - members=_compatibility_members) - - -def _new_module(name): - return types.ModuleType(__name__ + "." + name) - - -def _import_sub_module(module, name): - """import_sub_module will mimic the function of importlib.import_module""" - module = __import__(module.__name__ + "." + name) - for level in name.split("."): - module = getattr(module, level) - return module - - -def _setup(module, extras): - """Install common submodules""" - - Qt.__binding__ = module.__name__ - - for name in list(_common_members) + extras: - try: - submodule = _import_sub_module( - module, name) - except ImportError: - try: - # For extra modules like sip and shiboken that may not be - # children of the binding. - submodule = __import__(name) - except ImportError: - continue - - setattr(Qt, "_" + name, submodule) - - if name not in extras: - # Store reference to original binding, - # but don't store speciality modules - # such as uic or QtUiTools - setattr(Qt, name, _new_module(name)) - - -def _reassign_misplaced_members(binding): - """Apply misplaced members from `binding` to Qt.py - - Arguments: - binding (dict): Misplaced members - - """ - - for src, dst in _misplaced_members[binding].items(): - dst_value = None - - src_parts = src.split(".") - src_module = src_parts[0] - src_member = None - if len(src_parts) > 1: - src_member = src_parts[1:] - - if isinstance(dst, (list, tuple)): - dst, dst_value = dst - - dst_parts = dst.split(".") - dst_module = dst_parts[0] - dst_member = None - if len(dst_parts) > 1: - dst_member = dst_parts[1] - - # Get the member we want to store in the namesapce. - if not dst_value: - try: - _part = getattr(Qt, "_" + src_module) - while src_member: - member = src_member.pop(0) - _part = getattr(_part, member) - dst_value = _part - except AttributeError: - # If the member we want to store in the namespace does not - # exist, there is no need to continue. This can happen if a - # request was made to rename a member that didn't exist, for - # example if QtWidgets isn't available on the target platform. - _log("Misplaced member has no source: {0}".format(src)) - continue - - try: - src_object = getattr(Qt, dst_module) - except AttributeError: - if dst_module not in _common_members: - # Only create the Qt parent module if its listed in - # _common_members. Without this check, if you remove QtCore - # from _common_members, the default _misplaced_members will add - # Qt.QtCore so it can add Signal, Slot, etc. - msg = 'Not creating missing member module "{m}" for "{c}"' - _log(msg.format(m=dst_module, c=dst_member)) - continue - # If the dst is valid but the Qt parent module does not exist - # then go ahead and create a new module to contain the member. - setattr(Qt, dst_module, _new_module(dst_module)) - src_object = getattr(Qt, dst_module) - # Enable direct import of the new module - sys.modules[__name__ + "." + dst_module] = src_object - - if not dst_value: - dst_value = getattr(Qt, "_" + src_module) - if src_member: - dst_value = getattr(dst_value, src_member) - - setattr( - src_object, - dst_member or dst_module, - dst_value - ) - - -def _build_compatibility_members(binding, decorators=None): - """Apply `binding` to QtCompat - - Arguments: - binding (str): Top level binding in _compatibility_members. - decorators (dict, optional): Provides the ability to decorate the - original Qt methods when needed by a binding. This can be used - to change the returned value to a standard value. The key should - be the classname, the value is a dict where the keys are the - target method names, and the values are the decorator functions. - - """ - - decorators = decorators or dict() - - # Allow optional site-level customization of the compatibility members. - # This method does not need to be implemented in QtSiteConfig. - try: - import QtSiteConfig - except ImportError: - pass - else: - if hasattr(QtSiteConfig, 'update_compatibility_decorators'): - QtSiteConfig.update_compatibility_decorators(binding, decorators) - - _QtCompat = type("QtCompat", (object,), {}) - - for classname, bindings in _compatibility_members[binding].items(): - attrs = {} - for target, binding in bindings.items(): - namespaces = binding.split('.') - try: - src_object = getattr(Qt, "_" + namespaces[0]) - except AttributeError as e: - _log("QtCompat: AttributeError: %s" % e) - # Skip reassignment of non-existing members. - # This can happen if a request was made to - # rename a member that didn't exist, for example - # if QtWidgets isn't available on the target platform. - continue - - # Walk down any remaining namespace getting the object assuming - # that if the first namespace exists the rest will exist. - for namespace in namespaces[1:]: - src_object = getattr(src_object, namespace) - - # decorate the Qt method if a decorator was provided. - if target in decorators.get(classname, []): - # staticmethod must be called on the decorated method to - # prevent a TypeError being raised when the decorated method - # is called. - src_object = staticmethod( - decorators[classname][target](src_object)) - - attrs[target] = src_object - - # Create the QtCompat class and install it into the namespace - compat_class = type(classname, (_QtCompat,), attrs) - setattr(Qt.QtCompat, classname, compat_class) - - -def _pyside2(): - """Initialise PySide2 - - These functions serve to test the existence of a binding - along with set it up in such a way that it aligns with - the final step; adding members from the original binding - to Qt.py - - """ - - import PySide2 as module - extras = ["QtUiTools"] - try: - try: - # Before merge of PySide and shiboken - import shiboken2 - except ImportError: - # After merge of PySide and shiboken, May 2017 - from PySide2 import shiboken2 - extras.append("shiboken2") - except ImportError: - pass - - _setup(module, extras) - Qt.__binding_version__ = module.__version__ - - if hasattr(Qt, "_shiboken2"): - Qt.QtCompat.wrapInstance = _wrapinstance - Qt.QtCompat.getCppPointer = _getcpppointer - Qt.QtCompat.delete = shiboken2.delete - - if hasattr(Qt, "_QtUiTools"): - Qt.QtCompat.loadUi = _loadUi - - if hasattr(Qt, "_QtCore"): - Qt.__qt_version__ = Qt._QtCore.qVersion() - Qt.QtCompat.dataChanged = ( - lambda self, topleft, bottomright, roles=None: - self.dataChanged.emit(topleft, bottomright, roles or []) - ) - - if hasattr(Qt, "_QtWidgets"): - Qt.QtCompat.setSectionResizeMode = \ - Qt._QtWidgets.QHeaderView.setSectionResizeMode - - _reassign_misplaced_members("PySide2") - _build_compatibility_members("PySide2") - - -def _pyside(): - """Initialise PySide""" - - import PySide as module - extras = ["QtUiTools"] - try: - try: - # Before merge of PySide and shiboken - import shiboken - except ImportError: - # After merge of PySide and shiboken, May 2017 - from PySide import shiboken - extras.append("shiboken") - except ImportError: - pass - - _setup(module, extras) - Qt.__binding_version__ = module.__version__ - - if hasattr(Qt, "_shiboken"): - Qt.QtCompat.wrapInstance = _wrapinstance - Qt.QtCompat.getCppPointer = _getcpppointer - Qt.QtCompat.delete = shiboken.delete - - if hasattr(Qt, "_QtUiTools"): - Qt.QtCompat.loadUi = _loadUi - - if hasattr(Qt, "_QtGui"): - setattr(Qt, "QtWidgets", _new_module("QtWidgets")) - setattr(Qt, "_QtWidgets", Qt._QtGui) - if hasattr(Qt._QtGui, "QX11Info"): - setattr(Qt, "QtX11Extras", _new_module("QtX11Extras")) - Qt.QtX11Extras.QX11Info = Qt._QtGui.QX11Info - - Qt.QtCompat.setSectionResizeMode = Qt._QtGui.QHeaderView.setResizeMode - - if hasattr(Qt, "_QtCore"): - Qt.__qt_version__ = Qt._QtCore.qVersion() - Qt.QtCompat.dataChanged = ( - lambda self, topleft, bottomright, roles=None: - self.dataChanged.emit(topleft, bottomright) - ) - - _reassign_misplaced_members("PySide") - _build_compatibility_members("PySide") - - -def _pyqt5(): - """Initialise PyQt5""" - - import PyQt5 as module - extras = ["uic"] - - try: - import sip - extras += ["sip"] - except ImportError: - - # Relevant to PyQt5 5.11 and above - try: - from PyQt5 import sip - extras += ["sip"] - except ImportError: - sip = None - - _setup(module, extras) - if hasattr(Qt, "_sip"): - Qt.QtCompat.wrapInstance = _wrapinstance - Qt.QtCompat.getCppPointer = _getcpppointer - Qt.QtCompat.delete = sip.delete - - if hasattr(Qt, "_uic"): - Qt.QtCompat.loadUi = _loadUi - - if hasattr(Qt, "_QtCore"): - Qt.__binding_version__ = Qt._QtCore.PYQT_VERSION_STR - Qt.__qt_version__ = Qt._QtCore.QT_VERSION_STR - Qt.QtCompat.dataChanged = ( - lambda self, topleft, bottomright, roles=None: - self.dataChanged.emit(topleft, bottomright, roles or []) - ) - - if hasattr(Qt, "_QtWidgets"): - Qt.QtCompat.setSectionResizeMode = \ - Qt._QtWidgets.QHeaderView.setSectionResizeMode - - _reassign_misplaced_members("PyQt5") - _build_compatibility_members('PyQt5') - - -def _pyqt4(): - """Initialise PyQt4""" - - import sip - - # Validation of envivornment variable. Prevents an error if - # the variable is invalid since it's just a hint. - try: - hint = int(QT_SIP_API_HINT) - except TypeError: - hint = None # Variable was None, i.e. not set. - except ValueError: - raise ImportError("QT_SIP_API_HINT=%s must be a 1 or 2") - - for api in ("QString", - "QVariant", - "QDate", - "QDateTime", - "QTextStream", - "QTime", - "QUrl"): - try: - sip.setapi(api, hint or 2) - except AttributeError: - raise ImportError("PyQt4 < 4.6 isn't supported by Qt.py") - except ValueError: - actual = sip.getapi(api) - if not hint: - raise ImportError("API version already set to %d" % actual) - else: - # Having provided a hint indicates a soft constraint, one - # that doesn't throw an exception. - sys.stderr.write( - "Warning: API '%s' has already been set to %d.\n" - % (api, actual) - ) - - import PyQt4 as module - extras = ["uic"] - try: - import sip - extras.append(sip.__name__) - except ImportError: - sip = None - - _setup(module, extras) - if hasattr(Qt, "_sip"): - Qt.QtCompat.wrapInstance = _wrapinstance - Qt.QtCompat.getCppPointer = _getcpppointer - Qt.QtCompat.delete = sip.delete - - if hasattr(Qt, "_uic"): - Qt.QtCompat.loadUi = _loadUi - - if hasattr(Qt, "_QtGui"): - setattr(Qt, "QtWidgets", _new_module("QtWidgets")) - setattr(Qt, "_QtWidgets", Qt._QtGui) - if hasattr(Qt._QtGui, "QX11Info"): - setattr(Qt, "QtX11Extras", _new_module("QtX11Extras")) - Qt.QtX11Extras.QX11Info = Qt._QtGui.QX11Info - - Qt.QtCompat.setSectionResizeMode = \ - Qt._QtGui.QHeaderView.setResizeMode - - if hasattr(Qt, "_QtCore"): - Qt.__binding_version__ = Qt._QtCore.PYQT_VERSION_STR - Qt.__qt_version__ = Qt._QtCore.QT_VERSION_STR - Qt.QtCompat.dataChanged = ( - lambda self, topleft, bottomright, roles=None: - self.dataChanged.emit(topleft, bottomright) - ) - - _reassign_misplaced_members("PyQt4") - - # QFileDialog QtCompat decorator - def _standardizeQFileDialog(some_function): - """Decorator that makes PyQt4 return conform to other bindings""" - def wrapper(*args, **kwargs): - ret = (some_function(*args, **kwargs)) - - # PyQt4 only returns the selected filename, force it to a - # standard return of the selected filename, and a empty string - # for the selected filter - return ret, '' - - wrapper.__doc__ = some_function.__doc__ - wrapper.__name__ = some_function.__name__ - - return wrapper - - decorators = { - "QFileDialog": { - "getOpenFileName": _standardizeQFileDialog, - "getOpenFileNames": _standardizeQFileDialog, - "getSaveFileName": _standardizeQFileDialog, - } - } - _build_compatibility_members('PyQt4', decorators) - - -def _none(): - """Internal option (used in installer)""" - - Mock = type("Mock", (), {"__getattr__": lambda Qt, attr: None}) - - Qt.__binding__ = "None" - Qt.__qt_version__ = "0.0.0" - Qt.__binding_version__ = "0.0.0" - Qt.QtCompat.loadUi = lambda uifile, baseinstance=None: None - Qt.QtCompat.setSectionResizeMode = lambda *args, **kwargs: None - - for submodule in _common_members.keys(): - setattr(Qt, submodule, Mock()) - setattr(Qt, "_" + submodule, Mock()) - - -def _log(text): - if QT_VERBOSE: - sys.stdout.write(text + "\n") - - -def _convert(lines): - """Convert compiled .ui file from PySide2 to Qt.py - - Arguments: - lines (list): Each line of of .ui file - - Usage: - >> with open("myui.py") as f: - .. lines = _convert(f.readlines()) - - """ - - def parse(line): - line = line.replace("from PySide2 import", "from Qt import QtCompat,") - line = line.replace("QtWidgets.QApplication.translate", - "QtCompat.translate") - if "QtCore.SIGNAL" in line: - raise NotImplementedError("QtCore.SIGNAL is missing from PyQt5 " - "and so Qt.py does not support it: you " - "should avoid defining signals inside " - "your ui files.") - return line - - parsed = list() - for line in lines: - line = parse(line) - parsed.append(line) - - return parsed - - -def _cli(args): - """Qt.py command-line interface""" - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument("--convert", - help="Path to compiled Python module, e.g. my_ui.py") - parser.add_argument("--compile", - help="Accept raw .ui file and compile with native " - "PySide2 compiler.") - parser.add_argument("--stdout", - help="Write to stdout instead of file", - action="store_true") - parser.add_argument("--stdin", - help="Read from stdin instead of file", - action="store_true") - - args = parser.parse_args(args) - - if args.stdout: - raise NotImplementedError("--stdout") - - if args.stdin: - raise NotImplementedError("--stdin") - - if args.compile: - raise NotImplementedError("--compile") - - if args.convert: - sys.stdout.write("#\n" - "# WARNING: --convert is an ALPHA feature.\n#\n" - "# See https://github.com/mottosso/Qt.py/pull/132\n" - "# for details.\n" - "#\n") - - # - # ------> Read - # - with open(args.convert) as f: - lines = _convert(f.readlines()) - - backup = "%s_backup%s" % os.path.splitext(args.convert) - sys.stdout.write("Creating \"%s\"..\n" % backup) - shutil.copy(args.convert, backup) - - # - # <------ Write - # - with open(args.convert, "w") as f: - f.write("".join(lines)) - - sys.stdout.write("Successfully converted \"%s\"\n" % args.convert) - - -class MissingMember(object): - """ - A placeholder type for a missing Qt object not - included in Qt.py - - Args: - name (str): The name of the missing type - details (str): An optional custom error message - """ - ERR_TMPL = ("{} is not a common object across PySide2 " - "and the other Qt bindings. It is not included " - "as a common member in the Qt.py layer") - - def __init__(self, name, details=''): - self.__name = name - self.__err = self.ERR_TMPL.format(name) - - if details: - self.__err = "{}: {}".format(self.__err, details) - - def __repr__(self): - return "<{}: {}>".format(self.__class__.__name__, self.__name) - - def __getattr__(self, name): - raise NotImplementedError(self.__err) - - def __call__(self, *a, **kw): - raise NotImplementedError(self.__err) - - -def _install(): - # Default order (customise order and content via QT_PREFERRED_BINDING) - default_order = ("PySide2", "PyQt5", "PySide", "PyQt4") - preferred_order = list( - b for b in QT_PREFERRED_BINDING.split(os.pathsep) if b - ) - - order = preferred_order or default_order - - available = { - "PySide2": _pyside2, - "PyQt5": _pyqt5, - "PySide": _pyside, - "PyQt4": _pyqt4, - "None": _none - } - - _log("Order: '%s'" % "', '".join(order)) - - # Allow site-level customization of the available modules. - _apply_site_config() - - found_binding = False - for name in order: - _log("Trying %s" % name) - - try: - available[name]() - found_binding = True - break - - except ImportError as e: - _log("ImportError: %s" % e) - - except KeyError: - _log("ImportError: Preferred binding '%s' not found." % name) - - if not found_binding: - # If not binding were found, throw this error - raise ImportError("No Qt binding were found.") - - # Install individual members - for name, members in _common_members.items(): - try: - their_submodule = getattr(Qt, "_%s" % name) - except AttributeError: - continue - - our_submodule = getattr(Qt, name) - - # Enable import * - __all__.append(name) - - # Enable direct import of submodule, - # e.g. import Qt.QtCore - sys.modules[__name__ + "." + name] = our_submodule - - for member in members: - # Accept that a submodule may miss certain members. - try: - their_member = getattr(their_submodule, member) - except AttributeError: - _log("'%s.%s' was missing." % (name, member)) - continue - - setattr(our_submodule, member, their_member) - - # Install missing member placeholders - for name, members in _missing_members.items(): - our_submodule = getattr(Qt, name) - - for member in members: - - # If the submodule already has this member installed, - # either by the common members, or the site config, - # then skip installing this one over it. - if hasattr(our_submodule, member): - continue - - placeholder = MissingMember("{}.{}".format(name, member), - details=members[member]) - setattr(our_submodule, member, placeholder) - - # Enable direct import of QtCompat - sys.modules['Qt.QtCompat'] = Qt.QtCompat - - # Backwards compatibility - if hasattr(Qt.QtCompat, 'loadUi'): - Qt.QtCompat.load_ui = Qt.QtCompat.loadUi - - -_install() - -# Setup Binding Enum states -Qt.IsPySide2 = Qt.__binding__ == 'PySide2' -Qt.IsPyQt5 = Qt.__binding__ == 'PyQt5' -Qt.IsPySide = Qt.__binding__ == 'PySide' -Qt.IsPyQt4 = Qt.__binding__ == 'PyQt4' - -"""Augment QtCompat - -QtCompat contains wrappers and added functionality -to the original bindings, such as the CLI interface -and otherwise incompatible members between bindings, -such as `QHeaderView.setSectionResizeMode`. - -""" - -Qt.QtCompat._cli = _cli -Qt.QtCompat._convert = _convert - -# Enable command-line interface -if __name__ == "__main__": - _cli(sys.argv[1:]) - - -# The MIT License (MIT) -# -# Copyright (c) 2016-2017 Marcus Ottosson -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# -# In PySide(2), loadUi does not exist, so we implement it -# -# `_UiLoader` is adapted from the qtpy project, which was further influenced -# by qt-helpers which was released under a 3-clause BSD license which in turn -# is based on a solution at: -# -# - https://gist.github.com/cpbotha/1b42a20c8f3eb9bb7cb8 -# -# The License for this code is as follows: -# -# qt-helpers - a common front-end to various Qt modules -# -# Copyright (c) 2015, Chris Beaumont and Thomas Robitaille -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the -# distribution. -# * Neither the name of the Glue project nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Which itself was based on the solution at -# -# https://gist.github.com/cpbotha/1b42a20c8f3eb9bb7cb8 -# -# which was released under the MIT license: -# -# Copyright (c) 2011 Sebastian Wiesner -# Modifications by Charl Botha -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files -# (the "Software"),to deal in the Software without restriction, -# including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/openpype/vendor/python/common/scriptsmenu/vendor/__init__.py b/openpype/vendor/python/common/scriptsmenu/vendor/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 From e51453466c8069b224743689fb5b2ed2cfd01f88 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:54:00 +0100 Subject: [PATCH 17/42] global loader plugins are using qtpy --- openpype/plugins/load/copy_file.py | 2 +- openpype/plugins/load/copy_file_path.py | 2 +- openpype/plugins/load/delete_old_versions.py | 2 +- openpype/plugins/load/delivery.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/plugins/load/copy_file.py b/openpype/plugins/load/copy_file.py index 60db094cfbb..163f56a83a9 100644 --- a/openpype/plugins/load/copy_file.py +++ b/openpype/plugins/load/copy_file.py @@ -19,7 +19,7 @@ def load(self, context, name=None, namespace=None, data=None): @staticmethod def copy_file_to_clipboard(path): - from Qt import QtCore, QtWidgets + from qtpy import QtCore, QtWidgets clipboard = QtWidgets.QApplication.clipboard() assert clipboard, "Must have running QApplication instance" diff --git a/openpype/plugins/load/copy_file_path.py b/openpype/plugins/load/copy_file_path.py index 565d8d1ff18..569e5c8780f 100644 --- a/openpype/plugins/load/copy_file_path.py +++ b/openpype/plugins/load/copy_file_path.py @@ -19,7 +19,7 @@ def load(self, context, name=None, namespace=None, data=None): @staticmethod def copy_path_to_clipboard(path): - from Qt import QtWidgets + from qtpy import QtWidgets clipboard = QtWidgets.QApplication.clipboard() assert clipboard, "Must have running QApplication instance" diff --git a/openpype/plugins/load/delete_old_versions.py b/openpype/plugins/load/delete_old_versions.py index b7ac0152687..c7ad88a924b 100644 --- a/openpype/plugins/load/delete_old_versions.py +++ b/openpype/plugins/load/delete_old_versions.py @@ -5,7 +5,7 @@ import clique from pymongo import UpdateOne import qargparse -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype import style from openpype.client import get_versions, get_representations diff --git a/openpype/plugins/load/delivery.py b/openpype/plugins/load/delivery.py index 89c24f2402e..d1d5659118f 100644 --- a/openpype/plugins/load/delivery.py +++ b/openpype/plugins/load/delivery.py @@ -1,7 +1,7 @@ import copy from collections import defaultdict -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.client import get_representations from openpype.pipeline import load, Anatomy From 727b17b1b52ed91d49c1535475b1fd9276743c0c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 13:56:22 +0100 Subject: [PATCH 18/42] added qtpy 1.11.3 into python 2 vendor --- .../python/python_2/qtpy/Qt3DAnimation.py | 26 ++ .../vendor/python/python_2/qtpy/Qt3DCore.py | 26 ++ .../vendor/python/python_2/qtpy/Qt3DExtras.py | 26 ++ .../vendor/python/python_2/qtpy/Qt3DInput.py | 26 ++ .../vendor/python/python_2/qtpy/Qt3DLogic.py | 26 ++ .../vendor/python/python_2/qtpy/Qt3DRender.py | 26 ++ .../vendor/python/python_2/qtpy/QtCharts.py | 22 ++ .../vendor/python/python_2/qtpy/QtCore.py | 111 +++++++ .../python_2/qtpy/QtDataVisualization.py | 22 ++ .../vendor/python/python_2/qtpy/QtDesigner.py | 20 ++ openpype/vendor/python/python_2/qtpy/QtGui.py | 161 ++++++++++ .../vendor/python/python_2/qtpy/QtHelp.py | 24 ++ .../vendor/python/python_2/qtpy/QtLocation.py | 18 ++ .../python/python_2/qtpy/QtMultimedia.py | 17 ++ .../python_2/qtpy/QtMultimediaWidgets.py | 18 ++ .../vendor/python/python_2/qtpy/QtNetwork.py | 25 ++ .../vendor/python/python_2/qtpy/QtOpenGL.py | 24 ++ .../python/python_2/qtpy/QtPositioning.py | 18 ++ .../python/python_2/qtpy/QtPrintSupport.py | 28 ++ openpype/vendor/python/python_2/qtpy/QtQml.py | 18 ++ .../vendor/python/python_2/qtpy/QtQuick.py | 18 ++ .../python/python_2/qtpy/QtQuickWidgets.py | 18 ++ .../python/python_2/qtpy/QtSerialPort.py | 17 ++ openpype/vendor/python/python_2/qtpy/QtSql.py | 24 ++ openpype/vendor/python/python_2/qtpy/QtSvg.py | 24 ++ .../vendor/python/python_2/qtpy/QtTest.py | 30 ++ .../python/python_2/qtpy/QtWebChannel.py | 18 ++ .../python_2/qtpy/QtWebEngineWidgets.py | 49 +++ .../python/python_2/qtpy/QtWebSockets.py | 18 ++ .../vendor/python/python_2/qtpy/QtWidgets.py | 135 +++++++++ .../python/python_2/qtpy/QtWinExtras.py | 16 + .../python/python_2/qtpy/QtXmlPatterns.py | 22 ++ .../vendor/python/python_2/qtpy/__init__.py | 278 ++++++++++++++++++ .../python/python_2/qtpy/_patch/__init__.py | 0 .../python/python_2/qtpy/_patch/qcombobox.py | 101 +++++++ .../python_2/qtpy/_patch/qheaderview.py | 96 ++++++ .../vendor/python/python_2/qtpy/_version.py | 2 + .../vendor/python/python_2/qtpy/compat.py | 195 ++++++++++++ .../vendor/python/python_2/qtpy/py3compat.py | 262 +++++++++++++++++ .../python/python_2/qtpy/tests/__init__.py | 0 .../python/python_2/qtpy/tests/conftest.py | 71 +++++ .../python/python_2/qtpy/tests/runtests.py | 26 ++ .../python_2/qtpy/tests/test_macos_checks.py | 110 +++++++ .../python/python_2/qtpy/tests/test_main.py | 82 ++++++ .../qtpy/tests/test_patch_qcombobox.py | 107 +++++++ .../qtpy/tests/test_patch_qheaderview.py | 98 ++++++ .../qtpy/tests/test_qdesktopservice_split.py | 41 +++ .../python_2/qtpy/tests/test_qt3danimation.py | 25 ++ .../python_2/qtpy/tests/test_qt3dcore.py | 44 +++ .../python_2/qtpy/tests/test_qt3dextras.py | 47 +++ .../python_2/qtpy/tests/test_qt3dinput.py | 33 +++ .../python_2/qtpy/tests/test_qt3dlogic.py | 12 + .../python_2/qtpy/tests/test_qt3drender.py | 119 ++++++++ .../python_2/qtpy/tests/test_qtcharts.py | 11 + .../python/python_2/qtpy/tests/test_qtcore.py | 29 ++ .../qtpy/tests/test_qtdatavisualization.py | 86 ++++++ .../python_2/qtpy/tests/test_qtdesigner.py | 28 ++ .../python/python_2/qtpy/tests/test_qthelp.py | 22 ++ .../python_2/qtpy/tests/test_qtlocation.py | 48 +++ .../python_2/qtpy/tests/test_qtmultimedia.py | 18 ++ .../qtpy/tests/test_qtmultimediawidgets.py | 18 ++ .../python_2/qtpy/tests/test_qtnetwork.py | 43 +++ .../python_2/qtpy/tests/test_qtpositioning.py | 28 ++ .../qtpy/tests/test_qtprintsupport.py | 18 ++ .../python/python_2/qtpy/tests/test_qtqml.py | 34 +++ .../python_2/qtpy/tests/test_qtquick.py | 53 ++++ .../qtpy/tests/test_qtquickwidgets.py | 10 + .../python_2/qtpy/tests/test_qtserialport.py | 12 + .../python/python_2/qtpy/tests/test_qtsql.py | 24 ++ .../python/python_2/qtpy/tests/test_qtsvg.py | 13 + .../python/python_2/qtpy/tests/test_qttest.py | 9 + .../python_2/qtpy/tests/test_qtwebchannel.py | 13 + .../qtpy/tests/test_qtwebenginewidgets.py | 12 + .../python_2/qtpy/tests/test_qtwebsockets.py | 15 + .../python_2/qtpy/tests/test_qtwinextras.py | 29 ++ .../python_2/qtpy/tests/test_qtxmlpatterns.py | 25 ++ .../python/python_2/qtpy/tests/test_uic.py | 116 ++++++++ openpype/vendor/python/python_2/qtpy/uic.py | 277 +++++++++++++++++ 78 files changed, 3811 insertions(+) create mode 100644 openpype/vendor/python/python_2/qtpy/Qt3DAnimation.py create mode 100644 openpype/vendor/python/python_2/qtpy/Qt3DCore.py create mode 100644 openpype/vendor/python/python_2/qtpy/Qt3DExtras.py create mode 100644 openpype/vendor/python/python_2/qtpy/Qt3DInput.py create mode 100644 openpype/vendor/python/python_2/qtpy/Qt3DLogic.py create mode 100644 openpype/vendor/python/python_2/qtpy/Qt3DRender.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtCharts.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtCore.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtDataVisualization.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtDesigner.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtGui.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtHelp.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtLocation.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtMultimedia.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtMultimediaWidgets.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtNetwork.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtOpenGL.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtPositioning.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtPrintSupport.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtQml.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtQuick.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtQuickWidgets.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtSerialPort.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtSql.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtSvg.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtTest.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtWebChannel.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtWebEngineWidgets.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtWebSockets.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtWidgets.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtWinExtras.py create mode 100644 openpype/vendor/python/python_2/qtpy/QtXmlPatterns.py create mode 100644 openpype/vendor/python/python_2/qtpy/__init__.py create mode 100644 openpype/vendor/python/python_2/qtpy/_patch/__init__.py create mode 100644 openpype/vendor/python/python_2/qtpy/_patch/qcombobox.py create mode 100644 openpype/vendor/python/python_2/qtpy/_patch/qheaderview.py create mode 100644 openpype/vendor/python/python_2/qtpy/_version.py create mode 100644 openpype/vendor/python/python_2/qtpy/compat.py create mode 100644 openpype/vendor/python/python_2/qtpy/py3compat.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/__init__.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/conftest.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/runtests.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_macos_checks.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_main.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_patch_qcombobox.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_patch_qheaderview.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qdesktopservice_split.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qt3danimation.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qt3dcore.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qt3dextras.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qt3dinput.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qt3dlogic.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qt3drender.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtcharts.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtcore.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtdatavisualization.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtdesigner.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qthelp.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtlocation.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtmultimedia.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtmultimediawidgets.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtnetwork.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtpositioning.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtprintsupport.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtqml.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtquick.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtquickwidgets.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtserialport.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtsql.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtsvg.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qttest.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtwebchannel.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtwebenginewidgets.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtwebsockets.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtwinextras.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_qtxmlpatterns.py create mode 100644 openpype/vendor/python/python_2/qtpy/tests/test_uic.py create mode 100644 openpype/vendor/python/python_2/qtpy/uic.py diff --git a/openpype/vendor/python/python_2/qtpy/Qt3DAnimation.py b/openpype/vendor/python/python_2/qtpy/Qt3DAnimation.py new file mode 100644 index 00000000000..c6625b2d209 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/Qt3DAnimation.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides Qt3DAnimation classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError, PYSIDE_VERSION +from .py3compat import PY2 + +if PYQT5: + from PyQt5.Qt3DAnimation import * +elif PYSIDE2: + if not PY2 or (PY2 and PYSIDE_VERSION < '5.12.4'): + # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-1026 + import PySide2.Qt3DAnimation as __temp + import inspect + for __name in inspect.getmembers(__temp.Qt3DAnimation): + globals()[__name[0]] = __name[1] + else: + raise PythonQtError('A bug in Shiboken prevents this') +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/Qt3DCore.py b/openpype/vendor/python/python_2/qtpy/Qt3DCore.py new file mode 100644 index 00000000000..523e1deda78 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/Qt3DCore.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides Qt3DCore classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError, PYSIDE_VERSION +from .py3compat import PY2 + +if PYQT5: + from PyQt5.Qt3DCore import * +elif PYSIDE2: + if not PY2 or (PY2 and PYSIDE_VERSION < '5.12.4'): + # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-1026 + import PySide2.Qt3DCore as __temp + import inspect + for __name in inspect.getmembers(__temp.Qt3DCore): + globals()[__name[0]] = __name[1] + else: + raise PythonQtError('A bug in Shiboken prevents this') +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/Qt3DExtras.py b/openpype/vendor/python/python_2/qtpy/Qt3DExtras.py new file mode 100644 index 00000000000..4f3a9c13eee --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/Qt3DExtras.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides Qt3DExtras classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError, PYSIDE_VERSION +from .py3compat import PY2 + +if PYQT5: + from PyQt5.Qt3DExtras import * +elif PYSIDE2: + if not PY2 or (PY2 and PYSIDE_VERSION < '5.12.4'): + # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-1026 + import PySide2.Qt3DExtras as __temp + import inspect + for __name in inspect.getmembers(__temp.Qt3DExtras): + globals()[__name[0]] = __name[1] + else: + raise PythonQtError('A bug in Shiboken prevents this') +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/Qt3DInput.py b/openpype/vendor/python/python_2/qtpy/Qt3DInput.py new file mode 100644 index 00000000000..87b9a96a46a --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/Qt3DInput.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides Qt3DInput classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError, PYSIDE_VERSION +from .py3compat import PY2 + +if PYQT5: + from PyQt5.Qt3DInput import * +elif PYSIDE2: + if not PY2 or (PY2 and PYSIDE_VERSION < '5.12.4'): + # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-1026 + import PySide2.Qt3DInput as __temp + import inspect + for __name in inspect.getmembers(__temp.Qt3DInput): + globals()[__name[0]] = __name[1] + else: + raise PythonQtError('A bug in Shiboken prevents this') +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/Qt3DLogic.py b/openpype/vendor/python/python_2/qtpy/Qt3DLogic.py new file mode 100644 index 00000000000..d17f13671e2 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/Qt3DLogic.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides Qt3DLogic classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError, PYSIDE_VERSION +from .py3compat import PY2 + +if PYQT5: + from PyQt5.Qt3DLogic import * +elif PYSIDE2: + if not PY2 or (PY2 and PYSIDE_VERSION < '5.12.4'): + # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-1026 + import PySide2.Qt3DLogic as __temp + import inspect + for __name in inspect.getmembers(__temp.Qt3DLogic): + globals()[__name[0]] = __name[1] + else: + raise PythonQtError('A bug in Shiboken prevents this') +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/Qt3DRender.py b/openpype/vendor/python/python_2/qtpy/Qt3DRender.py new file mode 100644 index 00000000000..f30331ae170 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/Qt3DRender.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides Qt3DRender classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError, PYSIDE_VERSION +from .py3compat import PY2 + +if PYQT5: + from PyQt5.Qt3DRender import * +elif PYSIDE2: + if not PY2 or (PY2 and PYSIDE_VERSION < '5.12.4'): + # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-1026 + import PySide2.Qt3DRender as __temp + import inspect + for __name in inspect.getmembers(__temp.Qt3DRender): + globals()[__name[0]] = __name[1] + else: + raise PythonQtError('A bug in Shiboken prevents this') +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtCharts.py b/openpype/vendor/python/python_2/qtpy/QtCharts.py new file mode 100644 index 00000000000..74671230f8d --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtCharts.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2019- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtChart classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError + +if PYQT5: + try: + from PyQt5 import QtChart as QtCharts + except ImportError: + raise PythonQtError('The QtChart module was not found. ' + 'It needs to be installed separately for PyQt5.') +elif PYSIDE2: + from PySide2.QtCharts import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtCore.py b/openpype/vendor/python/python_2/qtpy/QtCore.py new file mode 100644 index 00000000000..d4bbd0d3eac --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtCore.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2014-2015 Colin Duquesnoy +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) + +""" +Provides QtCore classes and functions. +""" + +from . import PYQT5, PYSIDE2, PYQT4, PYSIDE, PythonQtError + + +if PYQT5: + from PyQt5.QtCore import * + from PyQt5.QtCore import pyqtSignal as Signal + from PyQt5.QtCore import pyqtBoundSignal as SignalInstance + from PyQt5.QtCore import pyqtSlot as Slot + from PyQt5.QtCore import pyqtProperty as Property + from PyQt5.QtCore import QT_VERSION_STR as __version__ + + # For issue #153 + from PyQt5.QtCore import QDateTime + QDateTime.toPython = QDateTime.toPyDateTime + + # Those are imported from `import *` + del pyqtSignal, pyqtBoundSignal, pyqtSlot, pyqtProperty, QT_VERSION_STR +elif PYSIDE2: + from PySide2.QtCore import * + + try: # may be limited to PySide-5.11a1 only + from PySide2.QtGui import QStringListModel + except: + pass + + import PySide2.QtCore + __version__ = PySide2.QtCore.__version__ +elif PYQT4: + from PyQt4.QtCore import * + # Those are things we inherited from Spyder that fix crazy crashes under + # some specific situations. (See #34) + from PyQt4.QtCore import QCoreApplication + from PyQt4.QtCore import Qt + from PyQt4.QtCore import pyqtSignal as Signal + from PyQt4.QtCore import pyqtBoundSignal as SignalInstance + from PyQt4.QtCore import pyqtSlot as Slot + from PyQt4.QtCore import pyqtProperty as Property + from PyQt4.QtGui import (QItemSelection, QItemSelectionModel, + QItemSelectionRange, QSortFilterProxyModel, + QStringListModel) + from PyQt4.QtCore import QT_VERSION_STR as __version__ + from PyQt4.QtCore import qInstallMsgHandler as qInstallMessageHandler + + # QDesktopServices has has been split into (QDesktopServices and + # QStandardPaths) in Qt5 + # This creates a dummy class that emulates QStandardPaths + from PyQt4.QtGui import QDesktopServices as _QDesktopServices + + class QStandardPaths(): + StandardLocation = _QDesktopServices.StandardLocation + displayName = _QDesktopServices.displayName + DesktopLocation = _QDesktopServices.DesktopLocation + DocumentsLocation = _QDesktopServices.DocumentsLocation + FontsLocation = _QDesktopServices.FontsLocation + ApplicationsLocation = _QDesktopServices.ApplicationsLocation + MusicLocation = _QDesktopServices.MusicLocation + MoviesLocation = _QDesktopServices.MoviesLocation + PicturesLocation = _QDesktopServices.PicturesLocation + TempLocation = _QDesktopServices.TempLocation + HomeLocation = _QDesktopServices.HomeLocation + DataLocation = _QDesktopServices.DataLocation + CacheLocation = _QDesktopServices.CacheLocation + writableLocation = _QDesktopServices.storageLocation + + # Those are imported from `import *` + del pyqtSignal, pyqtBoundSignal, pyqtSlot, pyqtProperty, QT_VERSION_STR, qInstallMsgHandler +elif PYSIDE: + from PySide.QtCore import * + from PySide.QtGui import (QItemSelection, QItemSelectionModel, + QItemSelectionRange, QSortFilterProxyModel, + QStringListModel) + from PySide.QtCore import qInstallMsgHandler as qInstallMessageHandler + del qInstallMsgHandler + + # QDesktopServices has has been split into (QDesktopServices and + # QStandardPaths) in Qt5 + # This creates a dummy class that emulates QStandardPaths + from PySide.QtGui import QDesktopServices as _QDesktopServices + + class QStandardPaths(): + StandardLocation = _QDesktopServices.StandardLocation + displayName = _QDesktopServices.displayName + DesktopLocation = _QDesktopServices.DesktopLocation + DocumentsLocation = _QDesktopServices.DocumentsLocation + FontsLocation = _QDesktopServices.FontsLocation + ApplicationsLocation = _QDesktopServices.ApplicationsLocation + MusicLocation = _QDesktopServices.MusicLocation + MoviesLocation = _QDesktopServices.MoviesLocation + PicturesLocation = _QDesktopServices.PicturesLocation + TempLocation = _QDesktopServices.TempLocation + HomeLocation = _QDesktopServices.HomeLocation + DataLocation = _QDesktopServices.DataLocation + CacheLocation = _QDesktopServices.CacheLocation + writableLocation = _QDesktopServices.storageLocation + + import PySide.QtCore + __version__ = PySide.QtCore.__version__ +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtDataVisualization.py b/openpype/vendor/python/python_2/qtpy/QtDataVisualization.py new file mode 100644 index 00000000000..cfb2b3b6b90 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtDataVisualization.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtDataVisualization classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError + +if PYQT5: + from PyQt5.QtDataVisualization import * +elif PYSIDE2: + # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-1026 + import PySide2.QtDataVisualization as __temp + import inspect + for __name in inspect.getmembers(__temp.QtDataVisualization): + globals()[__name[0]] = __name[1] +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtDesigner.py b/openpype/vendor/python/python_2/qtpy/QtDesigner.py new file mode 100644 index 00000000000..4aaafc815a6 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtDesigner.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2014-2015 Colin Duquesnoy +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) + +""" +Provides QtDesigner classes and functions. +""" + +from . import PYQT5, PYQT4, PythonQtError + + +if PYQT5: + from PyQt5.QtDesigner import * +elif PYQT4: + from PyQt4.QtDesigner import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtGui.py b/openpype/vendor/python/python_2/qtpy/QtGui.py new file mode 100644 index 00000000000..be8f5688653 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtGui.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2014-2015 Colin Duquesnoy +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) + +""" +Provides QtGui classes and functions. +.. warning:: Only PyQt4/PySide QtGui classes compatible with PyQt5.QtGui are + exposed here. Therefore, you need to treat/use this package as if it were + the ``PyQt5.QtGui`` module. +""" +import warnings + +from . import PYQT5, PYQT4, PYSIDE, PYSIDE2, PythonQtError + + +if PYQT5: + from PyQt5.QtGui import * +elif PYSIDE2: + from PySide2.QtGui import * +elif PYQT4: + try: + # Older versions of PyQt4 do not provide these + from PyQt4.QtGui import (QGlyphRun, QMatrix2x2, QMatrix2x3, + QMatrix2x4, QMatrix3x2, QMatrix3x3, + QMatrix3x4, QMatrix4x2, QMatrix4x3, + QMatrix4x4, QTouchEvent, QQuaternion, + QRadialGradient, QRawFont, QStaticText, + QVector2D, QVector3D, QVector4D, + qFuzzyCompare) + except ImportError: + pass + try: + from PyQt4.Qt import QKeySequence, QTextCursor + except ImportError: + # In PyQt4-sip 4.19.13 QKeySequence and QTextCursor are in PyQt4.QtGui + from PyQt4.QtGui import QKeySequence, QTextCursor + from PyQt4.QtGui import (QAbstractTextDocumentLayout, QActionEvent, QBitmap, + QBrush, QClipboard, QCloseEvent, QColor, + QConicalGradient, QContextMenuEvent, QCursor, + QDoubleValidator, QDrag, + QDragEnterEvent, QDragLeaveEvent, QDragMoveEvent, + QDropEvent, QFileOpenEvent, QFocusEvent, QFont, + QFontDatabase, QFontInfo, QFontMetrics, + QFontMetricsF, QGradient, QHelpEvent, + QHideEvent, QHoverEvent, QIcon, QIconDragEvent, + QIconEngine, QImage, QImageIOHandler, QImageReader, + QImageWriter, QInputEvent, QInputMethodEvent, + QKeyEvent, QLinearGradient, + QMouseEvent, QMoveEvent, QMovie, + QPaintDevice, QPaintEngine, QPaintEngineState, + QPaintEvent, QPainter, QPainterPath, + QPainterPathStroker, QPalette, QPen, QPicture, + QPictureIO, QPixmap, QPixmapCache, QPolygon, + QPolygonF, QRegExpValidator, QRegion, QResizeEvent, + QSessionManager, QShortcutEvent, QShowEvent, + QStandardItem, QStandardItemModel, + QStatusTipEvent, QSyntaxHighlighter, QTabletEvent, + QTextBlock, QTextBlockFormat, QTextBlockGroup, + QTextBlockUserData, QTextCharFormat, + QTextDocument, QTextDocumentFragment, + QTextDocumentWriter, QTextFormat, QTextFragment, + QTextFrame, QTextFrameFormat, QTextImageFormat, + QTextInlineObject, QTextItem, QTextLayout, + QTextLength, QTextLine, QTextList, QTextListFormat, + QTextObject, QTextObjectInterface, QTextOption, + QTextTable, QTextTableCell, QTextTableCellFormat, + QTextTableFormat, QTransform, + QValidator, QWhatsThisClickedEvent, QWheelEvent, + QWindowStateChangeEvent, qAlpha, qBlue, + qGray, qGreen, qIsGray, qRed, qRgb, + qRgba, QIntValidator) + + # QDesktopServices has has been split into (QDesktopServices and + # QStandardPaths) in Qt5 + # It only exposes QDesktopServices that are still in pyqt5 + from PyQt4.QtGui import QDesktopServices as _QDesktopServices + + class QDesktopServices(): + openUrl = _QDesktopServices.openUrl + setUrlHandler = _QDesktopServices.setUrlHandler + unsetUrlHandler = _QDesktopServices.unsetUrlHandler + + def __getattr__(self, name): + attr = getattr(_QDesktopServices, name) + + new_name = name + if name == 'storageLocation': + new_name = 'writableLocation' + warnings.warn(("Warning QDesktopServices.{} is deprecated in Qt5" + "we recommend you use QDesktopServices.{} instead").format(name, new_name), + DeprecationWarning) + return attr + QDesktopServices = QDesktopServices() + +elif PYSIDE: + from PySide.QtGui import (QAbstractTextDocumentLayout, QActionEvent, QBitmap, + QBrush, QClipboard, QCloseEvent, QColor, + QConicalGradient, QContextMenuEvent, QCursor, + QDoubleValidator, QDrag, + QDragEnterEvent, QDragLeaveEvent, QDragMoveEvent, + QDropEvent, QFileOpenEvent, QFocusEvent, QFont, + QFontDatabase, QFontInfo, QFontMetrics, + QFontMetricsF, QGradient, QHelpEvent, + QHideEvent, QHoverEvent, QIcon, QIconDragEvent, + QIconEngine, QImage, QImageIOHandler, QImageReader, + QImageWriter, QInputEvent, QInputMethodEvent, + QKeyEvent, QKeySequence, QLinearGradient, + QMatrix2x2, QMatrix2x3, QMatrix2x4, QMatrix3x2, + QMatrix3x3, QMatrix3x4, QMatrix4x2, QMatrix4x3, + QMatrix4x4, QMouseEvent, QMoveEvent, QMovie, + QPaintDevice, QPaintEngine, QPaintEngineState, + QPaintEvent, QPainter, QPainterPath, + QPainterPathStroker, QPalette, QPen, QPicture, + QPictureIO, QPixmap, QPixmapCache, QPolygon, + QPolygonF, QQuaternion, QRadialGradient, + QRegExpValidator, QRegion, QResizeEvent, + QSessionManager, QShortcutEvent, QShowEvent, + QStandardItem, QStandardItemModel, + QStatusTipEvent, QSyntaxHighlighter, QTabletEvent, + QTextBlock, QTextBlockFormat, QTextBlockGroup, + QTextBlockUserData, QTextCharFormat, QTextCursor, + QTextDocument, QTextDocumentFragment, + QTextFormat, QTextFragment, + QTextFrame, QTextFrameFormat, QTextImageFormat, + QTextInlineObject, QTextItem, QTextLayout, + QTextLength, QTextLine, QTextList, QTextListFormat, + QTextObject, QTextObjectInterface, QTextOption, + QTextTable, QTextTableCell, QTextTableCellFormat, + QTextTableFormat, QTouchEvent, QTransform, + QValidator, QVector2D, QVector3D, QVector4D, + QWhatsThisClickedEvent, QWheelEvent, + QWindowStateChangeEvent, qAlpha, qBlue, + qGray, qGreen, qIsGray, qRed, qRgb, qRgba, + QIntValidator) + # QDesktopServices has has been split into (QDesktopServices and + # QStandardPaths) in Qt5 + # It only exposes QDesktopServices that are still in pyqt5 + from PySide.QtGui import QDesktopServices as _QDesktopServices + + class QDesktopServices(): + openUrl = _QDesktopServices.openUrl + setUrlHandler = _QDesktopServices.setUrlHandler + unsetUrlHandler = _QDesktopServices.unsetUrlHandler + + def __getattr__(self, name): + attr = getattr(_QDesktopServices, name) + + new_name = name + if name == 'storageLocation': + new_name = 'writableLocation' + warnings.warn(("Warning QDesktopServices.{} is deprecated in Qt5" + "we recommend you use QDesktopServices.{} instead").format(name, new_name), + DeprecationWarning) + return attr + QDesktopServices = QDesktopServices() +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtHelp.py b/openpype/vendor/python/python_2/qtpy/QtHelp.py new file mode 100644 index 00000000000..ca9d93ddee9 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtHelp.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) + +"""QtHelp Wrapper.""" + +import warnings + +from . import PYQT5 +from . import PYQT4 +from . import PYSIDE +from . import PYSIDE2 + +if PYQT5: + from PyQt5.QtHelp import * +elif PYSIDE2: + from PySide2.QtHelp import * +elif PYQT4: + from PyQt4.QtHelp import * +elif PYSIDE: + from PySide.QtHelp import * diff --git a/openpype/vendor/python/python_2/qtpy/QtLocation.py b/openpype/vendor/python/python_2/qtpy/QtLocation.py new file mode 100644 index 00000000000..9dfe874ae57 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtLocation.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtLocation classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError + +if PYQT5: + from PyQt5.QtLocation import * +elif PYSIDE2: + from PySide2.QtLocation import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtMultimedia.py b/openpype/vendor/python/python_2/qtpy/QtMultimedia.py new file mode 100644 index 00000000000..9015ece9c16 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtMultimedia.py @@ -0,0 +1,17 @@ +import warnings + +from . import PYQT5 +from . import PYQT4 +from . import PYSIDE +from . import PYSIDE2 + +if PYQT5: + from PyQt5.QtMultimedia import * +elif PYSIDE2: + from PySide2.QtMultimedia import * +elif PYQT4: + from PyQt4.QtMultimedia import * + from PyQt4.QtGui import QSound +elif PYSIDE: + from PySide.QtMultimedia import * + from PySide.QtGui import QSound diff --git a/openpype/vendor/python/python_2/qtpy/QtMultimediaWidgets.py b/openpype/vendor/python/python_2/qtpy/QtMultimediaWidgets.py new file mode 100644 index 00000000000..697845d9c82 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtMultimediaWidgets.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtMultimediaWidgets classes and functions.""" + +# Local imports +from . import PYSIDE2, PYQT5, PythonQtError + +if PYQT5: + from PyQt5.QtMultimediaWidgets import * +elif PYSIDE2: + from PySide2.QtMultimediaWidgets import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtNetwork.py b/openpype/vendor/python/python_2/qtpy/QtNetwork.py new file mode 100644 index 00000000000..49faded7963 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtNetwork.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2014-2015 Colin Duquesnoy +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) + +""" +Provides QtNetwork classes and functions. +""" + +from . import PYQT5, PYSIDE2, PYQT4, PYSIDE, PythonQtError + + +if PYQT5: + from PyQt5.QtNetwork import * +elif PYSIDE2: + from PySide2.QtNetwork import * +elif PYQT4: + from PyQt4.QtNetwork import * +elif PYSIDE: + from PySide.QtNetwork import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtOpenGL.py b/openpype/vendor/python/python_2/qtpy/QtOpenGL.py new file mode 100644 index 00000000000..69ef82280d1 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtOpenGL.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtOpenGL classes and functions.""" + +# Local imports +from . import PYQT4, PYQT5, PYSIDE, PYSIDE2, PythonQtError + +if PYQT5: + from PyQt5.QtOpenGL import * +elif PYSIDE2: + from PySide2.QtOpenGL import * +elif PYQT4: + from PyQt4.QtOpenGL import * +elif PYSIDE: + from PySide.QtOpenGL import * +else: + raise PythonQtError('No Qt bindings could be found') + +del PYQT4, PYQT5, PYSIDE, PYSIDE2 diff --git a/openpype/vendor/python/python_2/qtpy/QtPositioning.py b/openpype/vendor/python/python_2/qtpy/QtPositioning.py new file mode 100644 index 00000000000..2b46d356897 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtPositioning.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright 2020 Antonio Valentino +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtPositioning classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError + +if PYQT5: + from PyQt5.QtPositioning import * +elif PYSIDE2: + from PySide2.QtPositioning import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtPrintSupport.py b/openpype/vendor/python/python_2/qtpy/QtPrintSupport.py new file mode 100644 index 00000000000..b821d4118cf --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtPrintSupport.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) + +""" +Provides QtPrintSupport classes and functions. +""" + +from . import PYQT5, PYQT4,PYSIDE2, PYSIDE, PythonQtError + + +if PYQT5: + from PyQt5.QtPrintSupport import * +elif PYSIDE2: + from PySide2.QtPrintSupport import * +elif PYQT4: + from PyQt4.QtGui import (QAbstractPrintDialog, QPageSetupDialog, + QPrintDialog, QPrintEngine, QPrintPreviewDialog, + QPrintPreviewWidget, QPrinter, QPrinterInfo) +elif PYSIDE: + from PySide.QtGui import (QAbstractPrintDialog, QPageSetupDialog, + QPrintDialog, QPrintEngine, QPrintPreviewDialog, + QPrintPreviewWidget, QPrinter, QPrinterInfo) +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtQml.py b/openpype/vendor/python/python_2/qtpy/QtQml.py new file mode 100644 index 00000000000..117f977f2b1 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtQml.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtQml classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError + +if PYQT5: + from PyQt5.QtQml import * +elif PYSIDE2: + from PySide2.QtQml import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtQuick.py b/openpype/vendor/python/python_2/qtpy/QtQuick.py new file mode 100644 index 00000000000..8291066724d --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtQuick.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtQuick classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError + +if PYQT5: + from PyQt5.QtQuick import * +elif PYSIDE2: + from PySide2.QtQuick import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtQuickWidgets.py b/openpype/vendor/python/python_2/qtpy/QtQuickWidgets.py new file mode 100644 index 00000000000..545d52b6811 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtQuickWidgets.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtQuickWidgets classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PythonQtError + +if PYQT5: + from PyQt5.QtQuickWidgets import * +elif PYSIDE2: + from PySide2.QtQuickWidgets import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtSerialPort.py b/openpype/vendor/python/python_2/qtpy/QtSerialPort.py new file mode 100644 index 00000000000..26fcae180e1 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtSerialPort.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2020 Marcin Stano +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtSerialPort classes and functions.""" + +# Local imports +from . import PYQT5, PythonQtError + +if PYQT5: + from PyQt5.QtSerialPort import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtSql.py b/openpype/vendor/python/python_2/qtpy/QtSql.py new file mode 100644 index 00000000000..98520bef513 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtSql.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtSql classes and functions.""" + +# Local imports +from . import PYQT5, PYSIDE2, PYQT4, PYSIDE, PythonQtError + +if PYQT5: + from PyQt5.QtSql import * +elif PYSIDE2: + from PySide2.QtSql import * +elif PYQT4: + from PyQt4.QtSql import * +elif PYSIDE: + from PySide.QtSql import * +else: + raise PythonQtError('No Qt bindings could be found') + +del PYQT4, PYQT5, PYSIDE, PYSIDE2 diff --git a/openpype/vendor/python/python_2/qtpy/QtSvg.py b/openpype/vendor/python/python_2/qtpy/QtSvg.py new file mode 100644 index 00000000000..edc075eac83 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtSvg.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtSvg classes and functions.""" + +# Local imports +from . import PYQT4, PYSIDE2, PYQT5, PYSIDE, PythonQtError + +if PYQT5: + from PyQt5.QtSvg import * +elif PYSIDE2: + from PySide2.QtSvg import * +elif PYQT4: + from PyQt4.QtSvg import * +elif PYSIDE: + from PySide.QtSvg import * +else: + raise PythonQtError('No Qt bindings could be found') + +del PYQT4, PYQT5, PYSIDE, PYSIDE2 diff --git a/openpype/vendor/python/python_2/qtpy/QtTest.py b/openpype/vendor/python/python_2/qtpy/QtTest.py new file mode 100644 index 00000000000..cca5e192288 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtTest.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2014-2015 Colin Duquesnoy +# Copyright © 2009- The Spyder Developmet Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) + +""" +Provides QtTest and functions +""" + +from . import PYQT5,PYSIDE2, PYQT4, PYSIDE, PythonQtError + + +if PYQT5: + from PyQt5.QtTest import QTest +elif PYSIDE2: + from PySide2.QtTest import QTest +elif PYQT4: + from PyQt4.QtTest import QTest as OldQTest + + class QTest(OldQTest): + @staticmethod + def qWaitForWindowActive(QWidget): + OldQTest.qWaitForWindowShown(QWidget) +elif PYSIDE: + from PySide.QtTest import QTest +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtWebChannel.py b/openpype/vendor/python/python_2/qtpy/QtWebChannel.py new file mode 100644 index 00000000000..2862a0569c8 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtWebChannel.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtWebChannel classes and functions.""" + +# Local imports +from . import PYSIDE2, PYQT5, PythonQtError + +if PYQT5: + from PyQt5.QtWebChannel import * +elif PYSIDE2: + from PySide2.QtWebChannel import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtWebEngineWidgets.py b/openpype/vendor/python/python_2/qtpy/QtWebEngineWidgets.py new file mode 100644 index 00000000000..33a66575c50 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtWebEngineWidgets.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2014-2015 Colin Duquesnoy +# Copyright © 2009- The Spyder development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) + +""" +Provides QtWebEngineWidgets classes and functions. +""" + +from . import PYQT5,PYSIDE2, PYQT4, PYSIDE, PythonQtError + + +# To test if we are using WebEngine or WebKit +WEBENGINE = True + + +if PYQT5: + try: + from PyQt5.QtWebEngineWidgets import QWebEnginePage + from PyQt5.QtWebEngineWidgets import QWebEngineView + from PyQt5.QtWebEngineWidgets import QWebEngineSettings + # Based on the work at https://github.com/spyder-ide/qtpy/pull/203 + from PyQt5.QtWebEngineWidgets import QWebEngineProfile + except ImportError: + from PyQt5.QtWebKitWidgets import QWebPage as QWebEnginePage + from PyQt5.QtWebKitWidgets import QWebView as QWebEngineView + from PyQt5.QtWebKit import QWebSettings as QWebEngineSettings + WEBENGINE = False +elif PYSIDE2: + from PySide2.QtWebEngineWidgets import QWebEnginePage + from PySide2.QtWebEngineWidgets import QWebEngineView + from PySide2.QtWebEngineWidgets import QWebEngineSettings + # Based on the work at https://github.com/spyder-ide/qtpy/pull/203 + from PySide2.QtWebEngineWidgets import QWebEngineProfile +elif PYQT4: + from PyQt4.QtWebKit import QWebPage as QWebEnginePage + from PyQt4.QtWebKit import QWebView as QWebEngineView + from PyQt4.QtWebKit import QWebSettings as QWebEngineSettings + WEBENGINE = False +elif PYSIDE: + from PySide.QtWebKit import QWebPage as QWebEnginePage + from PySide.QtWebKit import QWebView as QWebEngineView + from PySide.QtWebKit import QWebSettings as QWebEngineSettings + WEBENGINE = False +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtWebSockets.py b/openpype/vendor/python/python_2/qtpy/QtWebSockets.py new file mode 100644 index 00000000000..4b6a8204c92 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtWebSockets.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtWebSockets classes and functions.""" + +# Local imports +from . import PYSIDE2, PYQT5, PythonQtError + +if PYQT5: + from PyQt5.QtWebSockets import * +elif PYSIDE2: + from PySide2.QtWebSockets import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtWidgets.py b/openpype/vendor/python/python_2/qtpy/QtWidgets.py new file mode 100644 index 00000000000..66ef3abad85 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtWidgets.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2014-2015 Colin Duquesnoy +# Copyright © 2009- The Spyder Developmet Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) + +""" +Provides widget classes and functions. +.. warning:: Only PyQt4/PySide QtGui classes compatible with PyQt5.QtWidgets + are exposed here. Therefore, you need to treat/use this package as if it + were the ``PyQt5.QtWidgets`` module. +""" + +from . import PYQT5, PYSIDE2, PYQT4, PYSIDE, PythonQtError +from ._patch.qcombobox import patch_qcombobox +from ._patch.qheaderview import introduce_renamed_methods_qheaderview + + +if PYQT5: + from PyQt5.QtWidgets import * +elif PYSIDE2: + from PySide2.QtWidgets import * +elif PYQT4: + from PyQt4.QtGui import * + QStyleOptionViewItem = QStyleOptionViewItemV4 + del QStyleOptionViewItemV4 + QStyleOptionFrame = QStyleOptionFrameV3 + del QStyleOptionFrameV3 + + # These objects belong to QtGui + try: + # Older versions of PyQt4 do not provide these + del (QGlyphRun, + QMatrix2x2, QMatrix2x3, QMatrix2x4, QMatrix3x2, QMatrix3x3, + QMatrix3x4, QMatrix4x2, QMatrix4x3, QMatrix4x4, + QQuaternion, QRadialGradient, QRawFont, QRegExpValidator, + QStaticText, QTouchEvent, QVector2D, QVector3D, QVector4D, + qFuzzyCompare) + except NameError: + pass + del (QAbstractTextDocumentLayout, QActionEvent, QBitmap, QBrush, QClipboard, + QCloseEvent, QColor, QConicalGradient, QContextMenuEvent, QCursor, + QDesktopServices, QDoubleValidator, QDrag, QDragEnterEvent, + QDragLeaveEvent, QDragMoveEvent, QDropEvent, QFileOpenEvent, + QFocusEvent, QFont, QFontDatabase, QFontInfo, QFontMetrics, + QFontMetricsF, QGradient, QHelpEvent, QHideEvent, + QHoverEvent, QIcon, QIconDragEvent, QIconEngine, QImage, + QImageIOHandler, QImageReader, QImageWriter, QInputEvent, + QInputMethodEvent, QKeyEvent, QKeySequence, QLinearGradient, + QMouseEvent, QMoveEvent, QMovie, QPaintDevice, QPaintEngine, + QPaintEngineState, QPaintEvent, QPainter, QPainterPath, + QPainterPathStroker, QPalette, QPen, QPicture, QPictureIO, QPixmap, + QPixmapCache, QPolygon, QPolygonF, + QRegion, QResizeEvent, QSessionManager, QShortcutEvent, QShowEvent, + QStandardItem, QStandardItemModel, QStatusTipEvent, + QSyntaxHighlighter, QTabletEvent, QTextBlock, QTextBlockFormat, + QTextBlockGroup, QTextBlockUserData, QTextCharFormat, QTextCursor, + QTextDocument, QTextDocumentFragment, QTextDocumentWriter, + QTextFormat, QTextFragment, QTextFrame, QTextFrameFormat, + QTextImageFormat, QTextInlineObject, QTextItem, QTextLayout, + QTextLength, QTextLine, QTextList, QTextListFormat, QTextObject, + QTextObjectInterface, QTextOption, QTextTable, QTextTableCell, + QTextTableCellFormat, QTextTableFormat, QTransform, + QValidator, QWhatsThisClickedEvent, + QWheelEvent, QWindowStateChangeEvent, qAlpha, qBlue, + qGray, qGreen, qIsGray, qRed, qRgb, qRgba, QIntValidator, + QStringListModel) + + # These objects belong to QtPrintSupport + del (QAbstractPrintDialog, QPageSetupDialog, QPrintDialog, QPrintEngine, + QPrintPreviewDialog, QPrintPreviewWidget, QPrinter, QPrinterInfo) + + # These objects belong to QtCore + del (QItemSelection, QItemSelectionModel, QItemSelectionRange, + QSortFilterProxyModel) + + # Patch QComboBox to allow Python objects to be passed to userData + patch_qcombobox(QComboBox) + + # QHeaderView: renamed methods + introduce_renamed_methods_qheaderview(QHeaderView) + +elif PYSIDE: + from PySide.QtGui import * + QStyleOptionViewItem = QStyleOptionViewItemV4 + del QStyleOptionViewItemV4 + + # These objects belong to QtGui + del (QAbstractTextDocumentLayout, QActionEvent, QBitmap, QBrush, QClipboard, + QCloseEvent, QColor, QConicalGradient, QContextMenuEvent, QCursor, + QDesktopServices, QDoubleValidator, QDrag, QDragEnterEvent, + QDragLeaveEvent, QDragMoveEvent, QDropEvent, QFileOpenEvent, + QFocusEvent, QFont, QFontDatabase, QFontInfo, QFontMetrics, + QFontMetricsF, QGradient, QHelpEvent, QHideEvent, + QHoverEvent, QIcon, QIconDragEvent, QIconEngine, QImage, + QImageIOHandler, QImageReader, QImageWriter, QInputEvent, + QInputMethodEvent, QKeyEvent, QKeySequence, QLinearGradient, + QMatrix2x2, QMatrix2x3, QMatrix2x4, QMatrix3x2, QMatrix3x3, + QMatrix3x4, QMatrix4x2, QMatrix4x3, QMatrix4x4, QMouseEvent, + QMoveEvent, QMovie, QPaintDevice, QPaintEngine, QPaintEngineState, + QPaintEvent, QPainter, QPainterPath, QPainterPathStroker, QPalette, + QPen, QPicture, QPictureIO, QPixmap, QPixmapCache, QPolygon, + QPolygonF, QQuaternion, QRadialGradient, QRegExpValidator, + QRegion, QResizeEvent, QSessionManager, QShortcutEvent, QShowEvent, + QStandardItem, QStandardItemModel, QStatusTipEvent, + QSyntaxHighlighter, QTabletEvent, QTextBlock, QTextBlockFormat, + QTextBlockGroup, QTextBlockUserData, QTextCharFormat, QTextCursor, + QTextDocument, QTextDocumentFragment, + QTextFormat, QTextFragment, QTextFrame, QTextFrameFormat, + QTextImageFormat, QTextInlineObject, QTextItem, QTextLayout, + QTextLength, QTextLine, QTextList, QTextListFormat, QTextObject, + QTextObjectInterface, QTextOption, QTextTable, QTextTableCell, + QTextTableCellFormat, QTextTableFormat, QTouchEvent, QTransform, + QValidator, QVector2D, QVector3D, QVector4D, QWhatsThisClickedEvent, + QWheelEvent, QWindowStateChangeEvent, qAlpha, qBlue, qGray, qGreen, + qIsGray, qRed, qRgb, qRgba, QIntValidator, QStringListModel) + + # These objects belong to QtPrintSupport + del (QAbstractPrintDialog, QPageSetupDialog, QPrintDialog, QPrintEngine, + QPrintPreviewDialog, QPrintPreviewWidget, QPrinter, QPrinterInfo) + + # These objects belong to QtCore + del (QItemSelection, QItemSelectionModel, QItemSelectionRange, + QSortFilterProxyModel) + + # Patch QComboBox to allow Python objects to be passed to userData + patch_qcombobox(QComboBox) + + # QHeaderView: renamed methods + introduce_renamed_methods_qheaderview(QHeaderView) + +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtWinExtras.py b/openpype/vendor/python/python_2/qtpy/QtWinExtras.py new file mode 100644 index 00000000000..c033ff98859 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtWinExtras.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) + +from . import PYQT5, PYSIDE2, PythonQtError + + +if PYQT5: + from PyQt5.QtWinExtras import * +elif PYSIDE2: + from PySide2.QtWinExtras import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/QtXmlPatterns.py b/openpype/vendor/python/python_2/qtpy/QtXmlPatterns.py new file mode 100644 index 00000000000..b41e13df7f2 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/QtXmlPatterns.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +# ----------------------------------------------------------------------------- +"""Provides QtXmlPatterns classes and functions.""" + +# Local imports +from . import PYQT4, PYSIDE2, PYQT5, PYSIDE, PythonQtError + +if PYQT5: + from PyQt5.QtXmlPatterns import * +elif PYSIDE2: + from PySide2.QtXmlPatterns import * +elif PYQT4: + from PyQt4.QtXmlPatterns import * +elif PYSIDE: + from PySide.QtXmlPatterns import * +else: + raise PythonQtError('No Qt bindings could be found') diff --git a/openpype/vendor/python/python_2/qtpy/__init__.py b/openpype/vendor/python/python_2/qtpy/__init__.py new file mode 100644 index 00000000000..6d978ae3735 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/__init__.py @@ -0,0 +1,278 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2009- The Spyder Development Team +# Copyright © 2014-2015 Colin Duquesnoy +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) + +""" +**QtPy** is a shim over the various Python Qt bindings. It is used to write +Qt binding independent libraries or applications. + +If one of the APIs has already been imported, then it will be used. + +Otherwise, the shim will automatically select the first available API (PyQt5, +PySide2, PyQt4 and finally PySide); in that case, you can force the use of one +specific bindings (e.g. if your application is using one specific bindings and +you need to use library that use QtPy) by setting up the ``QT_API`` environment +variable. + +PyQt5 +===== + +For PyQt5, you don't have to set anything as it will be used automatically:: + + >>> from qtpy import QtGui, QtWidgets, QtCore + >>> print(QtWidgets.QWidget) + + +PySide2 +====== + +Set the QT_API environment variable to 'pyside2' before importing other +packages:: + + >>> import os + >>> os.environ['QT_API'] = 'pyside2' + >>> from qtpy import QtGui, QtWidgets, QtCore + >>> print(QtWidgets.QWidget) + +PyQt4 +===== + +Set the ``QT_API`` environment variable to 'pyqt' before importing any python +package:: + + >>> import os + >>> os.environ['QT_API'] = 'pyqt' + >>> from qtpy import QtGui, QtWidgets, QtCore + >>> print(QtWidgets.QWidget) + +PySide +====== + +Set the QT_API environment variable to 'pyside' before importing other +packages:: + + >>> import os + >>> os.environ['QT_API'] = 'pyside' + >>> from qtpy import QtGui, QtWidgets, QtCore + >>> print(QtWidgets.QWidget) + +""" + +from distutils.version import LooseVersion +import os +import platform +import sys +import warnings + +# Version of QtPy +from ._version import __version__ +from .py3compat import PY2 + + +class PythonQtError(RuntimeError): + """Error raise if no bindings could be selected.""" + pass + + +class PythonQtWarning(Warning): + """Warning if some features are not implemented in a binding.""" + pass + + +# Qt API environment variable name +QT_API = 'QT_API' + +# Names of the expected PyQt5 api +PYQT5_API = ['pyqt5'] + +# Names of the expected PyQt4 api +PYQT4_API = [ + 'pyqt', # name used in IPython.qt + 'pyqt4' # pyqode.qt original name +] + +# Names of the expected PySide api +PYSIDE_API = ['pyside'] + +# Names of the expected PySide2 api +PYSIDE2_API = ['pyside2'] + +# Names of the legacy APIs that we should warn users about +LEGACY_APIS = PYQT4_API + PYSIDE_API + +# Minimum fully supported versions of Qt and the bindings +PYQT_VERSION_MIN = '5.9.0' +PYSIDE_VERSION_MIN = '5.12.0' +QT_VERSION_MIN = '5.9.0' + +# Detecting if a binding was specified by the user +binding_specified = QT_API in os.environ + +# Setting a default value for QT_API +os.environ.setdefault(QT_API, 'pyqt5') + +API = os.environ[QT_API].lower() +initial_api = API +assert API in (PYQT5_API + PYQT4_API + PYSIDE_API + PYSIDE2_API) + +is_old_pyqt = is_pyqt46 = False +PYQT5 = True +PYQT4 = PYSIDE = PYSIDE2 = False + +# When `FORCE_QT_API` is set, we disregard +# any previously imported python bindings. +if not os.environ.get('FORCE_QT_API'): + if 'PyQt5' in sys.modules: + API = initial_api if initial_api in PYQT5_API else 'pyqt5' + elif 'PySide2' in sys.modules: + API = initial_api if initial_api in PYSIDE2_API else 'pyside2' + elif 'PyQt4' in sys.modules: + API = initial_api if initial_api in PYQT4_API else 'pyqt4' + elif 'PySide' in sys.modules: + API = initial_api if initial_api in PYSIDE_API else 'pyside' + + +if API in PYQT5_API: + try: + from PyQt5.QtCore import PYQT_VERSION_STR as PYQT_VERSION # analysis:ignore + from PyQt5.QtCore import QT_VERSION_STR as QT_VERSION # analysis:ignore + PYSIDE_VERSION = None + + if sys.platform == 'darwin': + macos_version = LooseVersion(platform.mac_ver()[0]) + if macos_version < LooseVersion('10.10'): + if LooseVersion(QT_VERSION) >= LooseVersion('5.9'): + raise PythonQtError("Qt 5.9 or higher only works in " + "macOS 10.10 or higher. Your " + "program will fail in this " + "system.") + elif macos_version < LooseVersion('10.11'): + if LooseVersion(QT_VERSION) >= LooseVersion('5.11'): + raise PythonQtError("Qt 5.11 or higher only works in " + "macOS 10.11 or higher. Your " + "program will fail in this " + "system.") + + del macos_version + except ImportError: + API = os.environ['QT_API'] = 'pyside2' + +if API in PYSIDE2_API: + try: + from PySide2 import __version__ as PYSIDE_VERSION # analysis:ignore + from PySide2.QtCore import __version__ as QT_VERSION # analysis:ignore + + PYQT_VERSION = None + PYQT5 = False + PYSIDE2 = True + + if sys.platform == 'darwin': + macos_version = LooseVersion(platform.mac_ver()[0]) + if macos_version < LooseVersion('10.11'): + if LooseVersion(QT_VERSION) >= LooseVersion('5.11'): + raise PythonQtError("Qt 5.11 or higher only works in " + "macOS 10.11 or higher. Your " + "program will fail in this " + "system.") + + del macos_version + except ImportError: + API = os.environ['QT_API'] = 'pyqt' + +if API in PYQT4_API: + try: + import sip + try: + sip.setapi('QString', 2) + sip.setapi('QVariant', 2) + sip.setapi('QDate', 2) + sip.setapi('QDateTime', 2) + sip.setapi('QTextStream', 2) + sip.setapi('QTime', 2) + sip.setapi('QUrl', 2) + except (AttributeError, ValueError): + # PyQt < v4.6 + pass + try: + from PyQt4.Qt import PYQT_VERSION_STR as PYQT_VERSION # analysis:ignore + from PyQt4.Qt import QT_VERSION_STR as QT_VERSION # analysis:ignore + except ImportError: + # In PyQt4-sip 4.19.13 PYQT_VERSION_STR and QT_VERSION_STR are in PyQt4.QtCore + from PyQt4.QtCore import PYQT_VERSION_STR as PYQT_VERSION # analysis:ignore + from PyQt4.QtCore import QT_VERSION_STR as QT_VERSION # analysis:ignore + PYSIDE_VERSION = None + PYQT5 = False + PYQT4 = True + except ImportError: + API = os.environ['QT_API'] = 'pyside' + else: + is_old_pyqt = PYQT_VERSION.startswith(('4.4', '4.5', '4.6', '4.7')) + is_pyqt46 = PYQT_VERSION.startswith('4.6') + +if API in PYSIDE_API: + try: + from PySide import __version__ as PYSIDE_VERSION # analysis:ignore + from PySide.QtCore import __version__ as QT_VERSION # analysis:ignore + PYQT_VERSION = None + PYQT5 = PYSIDE2 = False + PYSIDE = True + except ImportError: + raise PythonQtError('No Qt bindings could be found') + +# If a correct API name is passed to QT_API and it could not be found, +# switches to another and informs through the warning +if API != initial_api and binding_specified: + warnings.warn('Selected binding "{}" could not be found, ' + 'using "{}"'.format(initial_api, API), RuntimeWarning) + +API_NAME = {'pyqt5': 'PyQt5', 'pyqt': 'PyQt4', 'pyqt4': 'PyQt4', + 'pyside': 'PySide', 'pyside2':'PySide2'}[API] + +if PYQT4: + import sip + try: + API_NAME += (" (API v{0})".format(sip.getapi('QString'))) + except AttributeError: + pass + +try: + # QtDataVisualization backward compatibility (QtDataVisualization vs. QtDatavisualization) + # Only available for Qt5 bindings > 5.9 on Windows + from . import QtDataVisualization as QtDatavisualization +except (ImportError, PythonQtError): + pass + + +def _warn_old_minor_version(name, old_version, min_version): + warning_message = ( + "{name} version {old_version} is unsupported upstream and " + "deprecated by QtPy. To ensure your application is still supported " + "in QtPy 2.0, please make sure it doesn't depend upon {name} versions " + "older than {min_version}.".format( + name=name, old_version=old_version, min_version=min_version)) + warnings.warn(warning_message, DeprecationWarning) + + +# Warn if using a legacy, soon to be unsupported Qt API/binding +if API in LEGACY_APIS or initial_api in LEGACY_APIS: + warnings.warn( + "A deprecated Qt4-based binding (PyQt4/PySide) was installed, " + "imported or set via the 'QT_API' environment variable. " + "To ensure your application is still supported in QtPy 2.0, " + "please make sure it doesn't depend upon, import or " + "set the 'QT_API' env var to 'pyqt', 'pyqt4' or 'pyside'.", + DeprecationWarning, + ) +else: + if LooseVersion(QT_VERSION) < LooseVersion(QT_VERSION_MIN): + _warn_old_minor_version('Qt', QT_VERSION, QT_VERSION_MIN) + if PYQT_VERSION and (LooseVersion(PYQT_VERSION) + < LooseVersion(PYQT_VERSION_MIN)): + _warn_old_minor_version('PyQt', PYQT_VERSION, PYQT_VERSION_MIN) + elif PYSIDE_VERSION and (LooseVersion(PYSIDE_VERSION) + < LooseVersion(PYSIDE_VERSION_MIN)): + _warn_old_minor_version('PySide', PYSIDE_VERSION, PYSIDE_VERSION_MIN) diff --git a/openpype/vendor/python/python_2/qtpy/_patch/__init__.py b/openpype/vendor/python/python_2/qtpy/_patch/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/openpype/vendor/python/python_2/qtpy/_patch/qcombobox.py b/openpype/vendor/python/python_2/qtpy/_patch/qcombobox.py new file mode 100644 index 00000000000..d3e98bed16f --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/_patch/qcombobox.py @@ -0,0 +1,101 @@ +# The code below, as well as the associated test were adapted from +# qt-helpers, which was released under a 3-Clause BSD license: +# +# Copyright (c) 2015, Chris Beaumont and Thomas Robitaille +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# * Neither the name of the Glue project nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +def patch_qcombobox(QComboBox): + """ + In PySide, using Python objects as userData in QComboBox causes + Segmentation faults under certain conditions. Even in cases where it + doesn't, findData does not work correctly. Likewise, findData also does not + work correctly with Python objects when using PyQt4. On the other hand, + PyQt5 deals with this case correctly. We therefore patch QComboBox when + using PyQt4 and PySide to avoid issues. + """ + + from ..QtGui import QIcon + from ..QtCore import Qt, QObject + + class userDataWrapper(): + """ + This class is used to wrap any userData object. If we don't do this, + then certain types of objects can cause segmentation faults or issues + depending on whether/how __getitem__ is defined. + """ + def __init__(self, data): + self.data = data + + _addItem = QComboBox.addItem + + def addItem(self, *args, **kwargs): + if len(args) == 3 or (not isinstance(args[0], QIcon) + and len(args) == 2): + args, kwargs['userData'] = args[:-1], args[-1] + if 'userData' in kwargs: + kwargs['userData'] = userDataWrapper(kwargs['userData']) + _addItem(self, *args, **kwargs) + + _insertItem = QComboBox.insertItem + + def insertItem(self, *args, **kwargs): + if len(args) == 4 or (not isinstance(args[1], QIcon) + and len(args) == 3): + args, kwargs['userData'] = args[:-1], args[-1] + if 'userData' in kwargs: + kwargs['userData'] = userDataWrapper(kwargs['userData']) + _insertItem(self, *args, **kwargs) + + _setItemData = QComboBox.setItemData + + def setItemData(self, index, value, role=Qt.UserRole): + value = userDataWrapper(value) + _setItemData(self, index, value, role=role) + + _itemData = QComboBox.itemData + + def itemData(self, index, role=Qt.UserRole): + userData = _itemData(self, index, role=role) + if isinstance(userData, userDataWrapper): + userData = userData.data + return userData + + def findData(self, value): + for i in range(self.count()): + if self.itemData(i) == value: + return i + return -1 + + QComboBox.addItem = addItem + QComboBox.insertItem = insertItem + QComboBox.setItemData = setItemData + QComboBox.itemData = itemData + QComboBox.findData = findData \ No newline at end of file diff --git a/openpype/vendor/python/python_2/qtpy/_patch/qheaderview.py b/openpype/vendor/python/python_2/qtpy/_patch/qheaderview.py new file mode 100644 index 00000000000..b6baddbb22b --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/_patch/qheaderview.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# +# Copyright © The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see LICENSE.txt for details) +import warnings + +def introduce_renamed_methods_qheaderview(QHeaderView): + + _isClickable = QHeaderView.isClickable + def sectionsClickable(self): + """ + QHeaderView.sectionsClickable() -> bool + """ + return _isClickable(self) + QHeaderView.sectionsClickable = sectionsClickable + def isClickable(self): + warnings.warn('isClickable is only available in Qt4. Use ' + 'sectionsClickable instead.', stacklevel=2) + return _isClickable(self) + QHeaderView.isClickable = isClickable + + + _isMovable = QHeaderView.isMovable + def sectionsMovable(self): + """ + QHeaderView.sectionsMovable() -> bool + """ + return _isMovable(self) + QHeaderView.sectionsMovable = sectionsMovable + def isMovable(self): + warnings.warn('isMovable is only available in Qt4. Use ' + 'sectionsMovable instead.', stacklevel=2) + return _isMovable(self) + QHeaderView.isMovable = isMovable + + + _resizeMode = QHeaderView.resizeMode + def sectionResizeMode(self, logicalIndex): + """ + QHeaderView.sectionResizeMode(int) -> QHeaderView.ResizeMode + """ + return _resizeMode(self, logicalIndex) + QHeaderView.sectionResizeMode = sectionResizeMode + def resizeMode(self, logicalIndex): + warnings.warn('resizeMode is only available in Qt4. Use ' + 'sectionResizeMode instead.', stacklevel=2) + return _resizeMode(self, logicalIndex) + QHeaderView.resizeMode = resizeMode + + _setClickable = QHeaderView.setClickable + def setSectionsClickable(self, clickable): + """ + QHeaderView.setSectionsClickable(bool) + """ + return _setClickable(self, clickable) + QHeaderView.setSectionsClickable = setSectionsClickable + def setClickable(self, clickable): + warnings.warn('setClickable is only available in Qt4. Use ' + 'setSectionsClickable instead.', stacklevel=2) + return _setClickable(self, clickable) + QHeaderView.setClickable = setClickable + + + _setMovable = QHeaderView.setMovable + def setSectionsMovable(self, movable): + """ + QHeaderView.setSectionsMovable(bool) + """ + return _setMovable(self, movable) + QHeaderView.setSectionsMovable = setSectionsMovable + def setMovable(self, movable): + warnings.warn('setMovable is only available in Qt4. Use ' + 'setSectionsMovable instead.', stacklevel=2) + return _setMovable(self, movable) + QHeaderView.setMovable = setMovable + + + _setResizeMode = QHeaderView.setResizeMode + def setSectionResizeMode(self, *args): + """ + QHeaderView.setSectionResizeMode(QHeaderView.ResizeMode) + QHeaderView.setSectionResizeMode(int, QHeaderView.ResizeMode) + """ + _setResizeMode(self, *args) + QHeaderView.setSectionResizeMode = setSectionResizeMode + def setResizeMode(self, *args): + warnings.warn('setResizeMode is only available in Qt4. Use ' + 'setSectionResizeMode instead.', stacklevel=2) + _setResizeMode(self, *args) + QHeaderView.setResizeMode = setResizeMode + + + + diff --git a/openpype/vendor/python/python_2/qtpy/_version.py b/openpype/vendor/python/python_2/qtpy/_version.py new file mode 100644 index 00000000000..310a76d68c4 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/_version.py @@ -0,0 +1,2 @@ +version_info = (1, 11, 3) +__version__ = '.'.join(map(str, version_info)) diff --git a/openpype/vendor/python/python_2/qtpy/compat.py b/openpype/vendor/python/python_2/qtpy/compat.py new file mode 100644 index 00000000000..949d8854d19 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/compat.py @@ -0,0 +1,195 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2009- The Spyder Development Team +# Licensed under the terms of the MIT License + +""" +Compatibility functions +""" + +from __future__ import print_function +import sys + +from . import PYQT4 +from .QtWidgets import QFileDialog +from .py3compat import Callable, is_text_string, to_text_string, TEXT_TYPES + + +# ============================================================================= +# QVariant conversion utilities +# ============================================================================= +PYQT_API_1 = False +if PYQT4: + import sip + try: + PYQT_API_1 = sip.getapi('QVariant') == 1 # PyQt API #1 + except AttributeError: + # PyQt =v4.4 (API #1 and #2) and PySide >=v1.0""" + # Calling QFileDialog static method + if sys.platform == "win32": + # On Windows platforms: redirect standard outputs + _temp1, _temp2 = sys.stdout, sys.stderr + sys.stdout, sys.stderr = None, None + try: + result = QFileDialog.getExistingDirectory(parent, caption, basedir, + options) + finally: + if sys.platform == "win32": + # On Windows platforms: restore standard outputs + sys.stdout, sys.stderr = _temp1, _temp2 + if not is_text_string(result): + # PyQt API #1 + result = to_text_string(result) + return result + + +def _qfiledialog_wrapper(attr, parent=None, caption='', basedir='', + filters='', selectedfilter='', options=None): + if options is None: + options = QFileDialog.Options(0) + try: + # PyQt =v4.6 + QString = None # analysis:ignore + tuple_returned = True + try: + # PyQt >=v4.6 + func = getattr(QFileDialog, attr+'AndFilter') + except AttributeError: + # PySide or PyQt =v4.6 + output, selectedfilter = result + else: + # PyQt =v4.4 (API #1 and #2) and PySide >=v1.0""" + return _qfiledialog_wrapper('getOpenFileName', parent=parent, + caption=caption, basedir=basedir, + filters=filters, selectedfilter=selectedfilter, + options=options) + + +def getopenfilenames(parent=None, caption='', basedir='', filters='', + selectedfilter='', options=None): + """Wrapper around QtGui.QFileDialog.getOpenFileNames static method + Returns a tuple (filenames, selectedfilter) -- when dialog box is canceled, + returns a tuple (empty list, empty string) + Compatible with PyQt >=v4.4 (API #1 and #2) and PySide >=v1.0""" + return _qfiledialog_wrapper('getOpenFileNames', parent=parent, + caption=caption, basedir=basedir, + filters=filters, selectedfilter=selectedfilter, + options=options) + + +def getsavefilename(parent=None, caption='', basedir='', filters='', + selectedfilter='', options=None): + """Wrapper around QtGui.QFileDialog.getSaveFileName static method + Returns a tuple (filename, selectedfilter) -- when dialog box is canceled, + returns a tuple of empty strings + Compatible with PyQt >=v4.4 (API #1 and #2) and PySide >=v1.0""" + return _qfiledialog_wrapper('getSaveFileName', parent=parent, + caption=caption, basedir=basedir, + filters=filters, selectedfilter=selectedfilter, + options=options) diff --git a/openpype/vendor/python/python_2/qtpy/py3compat.py b/openpype/vendor/python/python_2/qtpy/py3compat.py new file mode 100644 index 00000000000..e92871a02b8 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/py3compat.py @@ -0,0 +1,262 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2012-2013 Pierre Raybaut +# Licensed under the terms of the MIT License +# (see spyderlib/__init__.py for details) + +""" +spyderlib.py3compat +------------------- + +Transitional module providing compatibility functions intended to help +migrating from Python 2 to Python 3. + +This module should be fully compatible with: + * Python >=v2.6 + * Python 3 +""" + +from __future__ import print_function + +import sys +import os + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY33 = PY3 and sys.version_info[1] >= 3 + + +# ============================================================================= +# Data types +# ============================================================================= +if PY2: + # Python 2 + TEXT_TYPES = (str, unicode) + INT_TYPES = (int, long) +else: + # Python 3 + TEXT_TYPES = (str,) + INT_TYPES = (int,) +NUMERIC_TYPES = tuple(list(INT_TYPES) + [float, complex]) + + +# ============================================================================= +# Renamed/Reorganized modules +# ============================================================================= +if PY2: + # Python 2 + import __builtin__ as builtins + from collections import Callable, MutableMapping + import ConfigParser as configparser + try: + import _winreg as winreg + except ImportError: + pass + from sys import maxint as maxsize + try: + import CStringIO as io + except ImportError: + import StringIO as io + try: + import cPickle as pickle + except ImportError: + import pickle + from UserDict import DictMixin as MutableMapping + import thread as _thread + import repr as reprlib +else: + # Python 3 + import builtins + import configparser + try: + import winreg + except ImportError: + pass + from sys import maxsize + import io + import pickle + if PY33: + from collections.abc import Callable, MutableMapping + else: + from collections import Callable, MutableMapping + import _thread + import reprlib + + +# ============================================================================= +# Strings +# ============================================================================= +if PY2: + # Python 2 + import codecs + + def u(obj): + """Make unicode object""" + return codecs.unicode_escape_decode(obj)[0] +else: + # Python 3 + def u(obj): + """Return string as it is""" + return obj + + +def is_text_string(obj): + """Return True if `obj` is a text string, False if it is anything else, + like binary data (Python 3) or QString (Python 2, PyQt API #1)""" + if PY2: + # Python 2 + return isinstance(obj, basestring) + else: + # Python 3 + return isinstance(obj, str) + + +def is_binary_string(obj): + """Return True if `obj` is a binary string, False if it is anything else""" + if PY2: + # Python 2 + return isinstance(obj, str) + else: + # Python 3 + return isinstance(obj, bytes) + + +def is_string(obj): + """Return True if `obj` is a text or binary Python string object, + False if it is anything else, like a QString (Python 2, PyQt API #1)""" + return is_text_string(obj) or is_binary_string(obj) + + +def is_unicode(obj): + """Return True if `obj` is unicode""" + if PY2: + # Python 2 + return isinstance(obj, unicode) + else: + # Python 3 + return isinstance(obj, str) + + +def to_text_string(obj, encoding=None): + """Convert `obj` to (unicode) text string""" + if PY2: + # Python 2 + if encoding is None: + return unicode(obj) + else: + return unicode(obj, encoding) + else: + # Python 3 + if encoding is None: + return str(obj) + elif isinstance(obj, str): + # In case this function is not used properly, this could happen + return obj + else: + return str(obj, encoding) + + +def to_binary_string(obj, encoding=None): + """Convert `obj` to binary string (bytes in Python 3, str in Python 2)""" + if PY2: + # Python 2 + if encoding is None: + return str(obj) + else: + return obj.encode(encoding) + else: + # Python 3 + return bytes(obj, 'utf-8' if encoding is None else encoding) + + +# ============================================================================= +# Function attributes +# ============================================================================= +def get_func_code(func): + """Return function code object""" + if PY2: + # Python 2 + return func.func_code + else: + # Python 3 + return func.__code__ + + +def get_func_name(func): + """Return function name""" + if PY2: + # Python 2 + return func.func_name + else: + # Python 3 + return func.__name__ + + +def get_func_defaults(func): + """Return function default argument values""" + if PY2: + # Python 2 + return func.func_defaults + else: + # Python 3 + return func.__defaults__ + + +# ============================================================================= +# Special method attributes +# ============================================================================= +def get_meth_func(obj): + """Return method function object""" + if PY2: + # Python 2 + return obj.im_func + else: + # Python 3 + return obj.__func__ + + +def get_meth_class_inst(obj): + """Return method class instance""" + if PY2: + # Python 2 + return obj.im_self + else: + # Python 3 + return obj.__self__ + + +def get_meth_class(obj): + """Return method class""" + if PY2: + # Python 2 + return obj.im_class + else: + # Python 3 + return obj.__self__.__class__ + + +# ============================================================================= +# Misc. +# ============================================================================= +if PY2: + # Python 2 + input = raw_input + getcwd = os.getcwdu + cmp = cmp + import string + str_lower = string.lower + from itertools import izip_longest as zip_longest +else: + # Python 3 + input = input + getcwd = os.getcwd + + def cmp(a, b): + return (a > b) - (a < b) + str_lower = str.lower + from itertools import zip_longest + + +def qbytearray_to_str(qba): + """Convert QByteArray object to str in a way compatible with Python 2/3""" + return str(bytes(qba.toHex().data()).decode()) diff --git a/openpype/vendor/python/python_2/qtpy/tests/__init__.py b/openpype/vendor/python/python_2/qtpy/tests/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/openpype/vendor/python/python_2/qtpy/tests/conftest.py b/openpype/vendor/python/python_2/qtpy/tests/conftest.py new file mode 100644 index 00000000000..c631886fb59 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/conftest.py @@ -0,0 +1,71 @@ +import os + + +def pytest_configure(config): + """ + This function gets run by py.test at the very start + """ + + if 'USE_QT_API' in os.environ: + os.environ['QT_API'] = os.environ['USE_QT_API'].lower() + + # We need to import qtpy here to make sure that the API versions get set + # straight away. + import qtpy + + +def pytest_report_header(config): + """ + This function is used by py.test to insert a customized header into the + test report. + """ + + versions = os.linesep + versions += 'PyQt4: ' + + try: + from PyQt4 import Qt + versions += "PyQt: {0} - Qt: {1}".format(Qt.PYQT_VERSION_STR, Qt.QT_VERSION_STR) + except ImportError: + versions += 'not installed' + except AttributeError: + versions += 'unknown version' + + versions += os.linesep + versions += 'PyQt5: ' + + try: + from PyQt5 import Qt + versions += "PyQt: {0} - Qt: {1}".format(Qt.PYQT_VERSION_STR, Qt.QT_VERSION_STR) + except ImportError: + versions += 'not installed' + except AttributeError: + versions += 'unknown version' + + versions += os.linesep + versions += 'PySide: ' + + try: + import PySide + from PySide import QtCore + versions += "PySide: {0} - Qt: {1}".format(PySide.__version__, QtCore.__version__) + except ImportError: + versions += 'not installed' + except AttributeError: + versions += 'unknown version' + + versions += os.linesep + versions += 'PySide2: ' + + try: + import PySide2 + from PySide2 import QtCore + versions += "PySide: {0} - Qt: {1}".format(PySide2.__version__, QtCore.__version__) + except ImportError: + versions += 'not installed' + except AttributeError: + versions += 'unknown version' + + versions += os.linesep + + return versions diff --git a/openpype/vendor/python/python_2/qtpy/tests/runtests.py b/openpype/vendor/python/python_2/qtpy/tests/runtests.py new file mode 100644 index 00000000000..b54fbb45b24 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/runtests.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# ---------------------------------------------------------------------------- +# Copyright © 2015- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# ---------------------------------------------------------------------------- + +"""File for running tests programmatically.""" + +# Standard library imports +import sys + +# Third party imports +import qtpy # to ensure that Qt4 uses API v2 +import pytest + + +def main(): + """Run pytest tests.""" + errno = pytest.main(['-x', 'qtpy', '-v', '-rw', '--durations=10', + '--cov=qtpy', '--cov-report=term-missing']) + sys.exit(errno) + +if __name__ == '__main__': + main() diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_macos_checks.py b/openpype/vendor/python/python_2/qtpy/tests/test_macos_checks.py new file mode 100644 index 00000000000..01aa8091c09 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_macos_checks.py @@ -0,0 +1,110 @@ +from __future__ import absolute_import + +import mock +import platform +import sys + +import pytest +from qtpy import PYQT5, PYSIDE2 + + +@pytest.mark.skipif(not PYQT5, reason="Targeted to PyQt5") +@mock.patch.object(platform, 'mac_ver') +def test_qt59_exception(mac_ver, monkeypatch): + # Remove qtpy to reimport it again + try: + del sys.modules["qtpy"] + except KeyError: + pass + + # Patch stdlib to emulate a macOS system + monkeypatch.setattr("sys.platform", 'darwin') + mac_ver.return_value = ('10.9.2',) + + # Patch Qt version + monkeypatch.setattr("PyQt5.QtCore.QT_VERSION_STR", '5.9.1') + + # This should raise an Exception + with pytest.raises(Exception) as e: + import qtpy + + assert '10.10' in str(e.value) + assert '5.9' in str(e.value) + + +@pytest.mark.skipif(not PYQT5, reason="Targeted to PyQt5") +@mock.patch.object(platform, 'mac_ver') +def test_qt59_no_exception(mac_ver, monkeypatch): + # Remove qtpy to reimport it again + try: + del sys.modules["qtpy"] + except KeyError: + pass + + # Patch stdlib to emulate a macOS system + monkeypatch.setattr("sys.platform", 'darwin') + mac_ver.return_value = ('10.10.1',) + + # Patch Qt version + monkeypatch.setattr("PyQt5.QtCore.QT_VERSION_STR", '5.9.5') + + # This should not raise an Exception + try: + import qtpy + except Exception: + pytest.fail("Error!") + + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), + reason="Targeted to PyQt5 or PySide2") +@mock.patch.object(platform, 'mac_ver') +def test_qt511_exception(mac_ver, monkeypatch): + # Remove qtpy to reimport it again + try: + del sys.modules["qtpy"] + except KeyError: + pass + + # Patch stdlib to emulate a macOS system + monkeypatch.setattr("sys.platform", 'darwin') + mac_ver.return_value = ('10.10.3',) + + # Patch Qt version + if PYQT5: + monkeypatch.setattr("PyQt5.QtCore.QT_VERSION_STR", '5.11.1') + else: + monkeypatch.setattr("PySide2.QtCore.__version__", '5.11.1') + + # This should raise an Exception + with pytest.raises(Exception) as e: + import qtpy + + assert '10.11' in str(e.value) + assert '5.11' in str(e.value) + + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), + reason="Targeted to PyQt5 or PySide2") +@mock.patch.object(platform, 'mac_ver') +def test_qt511_no_exception(mac_ver, monkeypatch): + # Remove qtpy to reimport it again + try: + del sys.modules["qtpy"] + except KeyError: + pass + + # Patch stdlib to emulate a macOS system + monkeypatch.setattr("sys.platform", 'darwin') + mac_ver.return_value = ('10.13.2',) + + # Patch Qt version + if PYQT5: + monkeypatch.setattr("PyQt5.QtCore.QT_VERSION_STR", '5.11.1') + else: + monkeypatch.setattr("PySide2.QtCore.__version__", '5.11.1') + + # This should not raise an Exception + try: + import qtpy + except Exception: + pytest.fail("Error!") diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_main.py b/openpype/vendor/python/python_2/qtpy/tests/test_main.py new file mode 100644 index 00000000000..2449249cc94 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_main.py @@ -0,0 +1,82 @@ +import os + +from qtpy import QtCore, QtGui, QtWidgets, QtWebEngineWidgets + + +def assert_pyside(): + """ + Make sure that we are using PySide + """ + import PySide + assert QtCore.QEvent is PySide.QtCore.QEvent + assert QtGui.QPainter is PySide.QtGui.QPainter + assert QtWidgets.QWidget is PySide.QtGui.QWidget + assert QtWebEngineWidgets.QWebEnginePage is PySide.QtWebKit.QWebPage + +def assert_pyside2(): + """ + Make sure that we are using PySide + """ + import PySide2 + assert QtCore.QEvent is PySide2.QtCore.QEvent + assert QtGui.QPainter is PySide2.QtGui.QPainter + assert QtWidgets.QWidget is PySide2.QtWidgets.QWidget + assert QtWebEngineWidgets.QWebEnginePage is PySide2.QtWebEngineWidgets.QWebEnginePage + +def assert_pyqt4(): + """ + Make sure that we are using PyQt4 + """ + import PyQt4 + assert QtCore.QEvent is PyQt4.QtCore.QEvent + assert QtGui.QPainter is PyQt4.QtGui.QPainter + assert QtWidgets.QWidget is PyQt4.QtGui.QWidget + assert QtWebEngineWidgets.QWebEnginePage is PyQt4.QtWebKit.QWebPage + + +def assert_pyqt5(): + """ + Make sure that we are using PyQt5 + """ + import PyQt5 + assert QtCore.QEvent is PyQt5.QtCore.QEvent + assert QtGui.QPainter is PyQt5.QtGui.QPainter + assert QtWidgets.QWidget is PyQt5.QtWidgets.QWidget + if QtWebEngineWidgets.WEBENGINE: + assert QtWebEngineWidgets.QWebEnginePage is PyQt5.QtWebEngineWidgets.QWebEnginePage + else: + assert QtWebEngineWidgets.QWebEnginePage is PyQt5.QtWebKitWidgets.QWebPage + + +def test_qt_api(): + """ + If QT_API is specified, we check that the correct Qt wrapper was used + """ + + QT_API = os.environ.get('QT_API', '').lower() + + if QT_API == 'pyside': + assert_pyside() + elif QT_API in ('pyqt', 'pyqt4'): + assert_pyqt4() + elif QT_API == 'pyqt5': + assert_pyqt5() + elif QT_API == 'pyside2': + assert_pyside2() + else: + # If the tests are run locally, USE_QT_API and QT_API may not be + # defined, but we still want to make sure qtpy is behaving sensibly. + # We should then be loading, in order of decreasing preference, PyQt5, + # PyQt4, and PySide. + try: + import PyQt5 + except ImportError: + try: + import PyQt4 + except ImportError: + import PySide + assert_pyside() + else: + assert_pyqt4() + else: + assert_pyqt5() diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_patch_qcombobox.py b/openpype/vendor/python/python_2/qtpy/tests/test_patch_qcombobox.py new file mode 100644 index 00000000000..1e1f04a38af --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_patch_qcombobox.py @@ -0,0 +1,107 @@ +from __future__ import absolute_import + +import os +import sys + +import pytest +from qtpy import PYQT5, PYSIDE2, QtGui, QtWidgets + + +PY3 = sys.version[0] == "3" + + +def get_qapp(icon_path=None): + qapp = QtWidgets.QApplication.instance() + if qapp is None: + qapp = QtWidgets.QApplication(['']) + return qapp + + +class Data(object): + """ + Test class to store in userData. The __getitem__ is needed in order to + reproduce the segmentation fault. + """ + def __getitem__(self, item): + raise ValueError("Failing") + + +@pytest.mark.skipif(PY3 or (PYSIDE2 and os.environ.get('CI', None) is not None), + reason="It segfaults in Python 3 and in our CIs with PySide2") +def test_patched_qcombobox(): + """ + In PySide, using Python objects as userData in QComboBox causes + Segmentation faults under certain conditions. Even in cases where it + doesn't, findData does not work correctly. Likewise, findData also + does not work correctly with Python objects when using PyQt4. On the + other hand, PyQt5 deals with this case correctly. We therefore patch + QComboBox when using PyQt4 and PySide to avoid issues. + """ + + app = get_qapp() + + data1 = Data() + data2 = Data() + data3 = Data() + data4 = Data() + data5 = Data() + data6 = Data() + + icon1 = QtGui.QIcon() + icon2 = QtGui.QIcon() + + widget = QtWidgets.QComboBox() + widget.addItem('a', data1) + widget.insertItem(0, 'b', data2) + widget.addItem('c', data1) + widget.setItemData(2, data3) + widget.addItem(icon1, 'd', data4) + widget.insertItem(3, icon2, 'e', data5) + widget.addItem(icon1, 'f') + widget.insertItem(5, icon2, 'g') + + widget.show() + + assert widget.findData(data1) == 1 + assert widget.findData(data2) == 0 + assert widget.findData(data3) == 2 + assert widget.findData(data4) == 4 + assert widget.findData(data5) == 3 + assert widget.findData(data6) == -1 + + assert widget.itemData(0) == data2 + assert widget.itemData(1) == data1 + assert widget.itemData(2) == data3 + assert widget.itemData(3) == data5 + assert widget.itemData(4) == data4 + assert widget.itemData(5) is None + assert widget.itemData(6) is None + + assert widget.itemText(0) == 'b' + assert widget.itemText(1) == 'a' + assert widget.itemText(2) == 'c' + assert widget.itemText(3) == 'e' + assert widget.itemText(4) == 'd' + assert widget.itemText(5) == 'g' + assert widget.itemText(6) == 'f' + + +@pytest.mark.skipif(((PYSIDE2 or PYQT5) + and os.environ.get('CI', None) is not None), + reason="It segfaults in our CIs with PYSIDE2 or PYQT5") +def test_model_item(): + """ + This is a regression test for an issue that caused the call to item(0) + below to trigger segmentation faults in PySide. The issue is + non-deterministic when running the call once, so we include a loop to make + sure that we trigger the fault. + """ + app = get_qapp() + combo = QtWidgets.QComboBox() + label_data = [('a', None)] + for iter in range(10000): + combo.clear() + for i, (label, data) in enumerate(label_data): + combo.addItem(label, userData=data) + model = combo.model() + model.item(0) diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_patch_qheaderview.py b/openpype/vendor/python/python_2/qtpy/tests/test_patch_qheaderview.py new file mode 100644 index 00000000000..17037f34a37 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_patch_qheaderview.py @@ -0,0 +1,98 @@ +from __future__ import absolute_import + +import sys + +import pytest +from qtpy import PYSIDE, PYSIDE2, PYQT4 +from qtpy.QtWidgets import QApplication +from qtpy.QtWidgets import QHeaderView +from qtpy.QtCore import Qt +from qtpy.QtCore import QAbstractListModel + + +PY3 = sys.version[0] == "3" + + +def get_qapp(icon_path=None): + qapp = QApplication.instance() + if qapp is None: + qapp = QApplication(['']) + return qapp + + +@pytest.mark.skipif(PY3 or PYSIDE2, reason="It fails on Python 3 and PySide2") +def test_patched_qheaderview(): + """ + This will test whether QHeaderView has the new methods introduced in Qt5. + It will then create an instance of QHeaderView and test that no exceptions + are raised and that some basic behaviour works. + """ + assert QHeaderView.sectionsClickable is not None + assert QHeaderView.sectionsMovable is not None + assert QHeaderView.sectionResizeMode is not None + assert QHeaderView.setSectionsClickable is not None + assert QHeaderView.setSectionsMovable is not None + assert QHeaderView.setSectionResizeMode is not None + + # setup a model and add it to a headerview + qapp = get_qapp() + headerview = QHeaderView(Qt.Horizontal) + class Model(QAbstractListModel): + pass + model = Model() + headerview.setModel(model) + assert headerview.count() == 1 + + # test it + assert isinstance(headerview.sectionsClickable(), bool) + assert isinstance(headerview.sectionsMovable(), bool) + if PYSIDE: + assert isinstance(headerview.sectionResizeMode(0), + QHeaderView.ResizeMode) + else: + assert isinstance(headerview.sectionResizeMode(0), int) + + headerview.setSectionsClickable(True) + assert headerview.sectionsClickable() == True + headerview.setSectionsClickable(False) + assert headerview.sectionsClickable() == False + + headerview.setSectionsMovable(True) + assert headerview.sectionsMovable() == True + headerview.setSectionsMovable(False) + assert headerview.sectionsMovable() == False + + headerview.setSectionResizeMode(QHeaderView.Interactive) + assert headerview.sectionResizeMode(0) == QHeaderView.Interactive + headerview.setSectionResizeMode(QHeaderView.Fixed) + assert headerview.sectionResizeMode(0) == QHeaderView.Fixed + headerview.setSectionResizeMode(QHeaderView.Stretch) + assert headerview.sectionResizeMode(0) == QHeaderView.Stretch + headerview.setSectionResizeMode(QHeaderView.ResizeToContents) + assert headerview.sectionResizeMode(0) == QHeaderView.ResizeToContents + + headerview.setSectionResizeMode(0, QHeaderView.Interactive) + assert headerview.sectionResizeMode(0) == QHeaderView.Interactive + headerview.setSectionResizeMode(0, QHeaderView.Fixed) + assert headerview.sectionResizeMode(0) == QHeaderView.Fixed + headerview.setSectionResizeMode(0, QHeaderView.Stretch) + assert headerview.sectionResizeMode(0) == QHeaderView.Stretch + headerview.setSectionResizeMode(0, QHeaderView.ResizeToContents) + assert headerview.sectionResizeMode(0) == QHeaderView.ResizeToContents + + # test that the old methods in Qt4 raise exceptions + if PYQT4 or PYSIDE: + with pytest.warns(UserWarning): + headerview.isClickable() + with pytest.warns(UserWarning): + headerview.isMovable() + with pytest.warns(UserWarning): + headerview.resizeMode(0) + with pytest.warns(UserWarning): + headerview.setClickable(True) + with pytest.warns(UserWarning): + headerview.setMovable(True) + with pytest.warns(UserWarning): + headerview.setResizeMode(0, QHeaderView.Interactive) + + diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qdesktopservice_split.py b/openpype/vendor/python/python_2/qtpy/tests/test_qdesktopservice_split.py new file mode 100644 index 00000000000..472f2df1d00 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qdesktopservice_split.py @@ -0,0 +1,41 @@ +"""Test QDesktopServices split in Qt5.""" + +from __future__ import absolute_import + +import pytest +import warnings +from qtpy import PYQT4, PYSIDE + + +def test_qstandarpath(): + """Test the qtpy.QStandardPaths namespace""" + from qtpy.QtCore import QStandardPaths + + assert QStandardPaths.StandardLocation is not None + + # Attributes from QDesktopServices shouldn't be in QStandardPaths + with pytest.raises(AttributeError) as excinfo: + QStandardPaths.setUrlHandler + + +def test_qdesktopservice(): + """Test the qtpy.QDesktopServices namespace""" + from qtpy.QtGui import QDesktopServices + + assert QDesktopServices.setUrlHandler is not None + + +@pytest.mark.skipif(not (PYQT4 or PYSIDE), reason="Warning is only raised in old bindings") +def test_qdesktopservice_qt4_pyside(): + from qtpy.QtGui import QDesktopServices + # Attributes from QStandardPaths should raise a warning when imported + # from QDesktopServices + with warnings.catch_warnings(record=True) as w: + # Cause all warnings to always be triggered. + warnings.simplefilter("always") + # Try to import QtHelp. + QDesktopServices.StandardLocation + + assert len(w) == 1 + assert issubclass(w[-1].category, DeprecationWarning) + assert "deprecated" in str(w[-1].message) diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qt3danimation.py b/openpype/vendor/python/python_2/qtpy/tests/test_qt3danimation.py new file mode 100644 index 00000000000..650be19e184 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qt3danimation.py @@ -0,0 +1,25 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qt3danimation(): + """Test the qtpy.Qt3DAnimation namespace""" + Qt3DAnimation = pytest.importorskip("qtpy.Qt3DAnimation") + + assert Qt3DAnimation.QAnimationController is not None + assert Qt3DAnimation.QAdditiveClipBlend is not None + assert Qt3DAnimation.QAbstractClipBlendNode is not None + assert Qt3DAnimation.QAbstractAnimation is not None + assert Qt3DAnimation.QKeyframeAnimation is not None + assert Qt3DAnimation.QAbstractAnimationClip is not None + assert Qt3DAnimation.QAbstractClipAnimator is not None + assert Qt3DAnimation.QClipAnimator is not None + assert Qt3DAnimation.QAnimationGroup is not None + assert Qt3DAnimation.QLerpClipBlend is not None + assert Qt3DAnimation.QMorphingAnimation is not None + assert Qt3DAnimation.QAnimationAspect is not None + assert Qt3DAnimation.QVertexBlendAnimation is not None + assert Qt3DAnimation.QBlendedClipAnimator is not None + assert Qt3DAnimation.QMorphTarget is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qt3dcore.py b/openpype/vendor/python/python_2/qtpy/tests/test_qt3dcore.py new file mode 100644 index 00000000000..821fbd4525b --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qt3dcore.py @@ -0,0 +1,44 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qt3dcore(): + """Test the qtpy.Qt3DCore namespace""" + Qt3DCore = pytest.importorskip("qtpy.Qt3DCore") + + assert Qt3DCore.QPropertyValueAddedChange is not None + assert Qt3DCore.QSkeletonLoader is not None + assert Qt3DCore.QPropertyNodeRemovedChange is not None + assert Qt3DCore.QPropertyUpdatedChange is not None + assert Qt3DCore.QAspectEngine is not None + assert Qt3DCore.QPropertyValueAddedChangeBase is not None + assert Qt3DCore.QStaticPropertyValueRemovedChangeBase is not None + assert Qt3DCore.QPropertyNodeAddedChange is not None + assert Qt3DCore.QDynamicPropertyUpdatedChange is not None + assert Qt3DCore.QStaticPropertyUpdatedChangeBase is not None + assert Qt3DCore.ChangeFlags is not None + assert Qt3DCore.QAbstractAspect is not None + assert Qt3DCore.QBackendNode is not None + assert Qt3DCore.QTransform is not None + assert Qt3DCore.QPropertyUpdatedChangeBase is not None + assert Qt3DCore.QNodeId is not None + assert Qt3DCore.QJoint is not None + assert Qt3DCore.QSceneChange is not None + assert Qt3DCore.QNodeIdTypePair is not None + assert Qt3DCore.QAbstractSkeleton is not None + assert Qt3DCore.QComponentRemovedChange is not None + assert Qt3DCore.QComponent is not None + assert Qt3DCore.QEntity is not None + assert Qt3DCore.QNodeCommand is not None + assert Qt3DCore.QNode is not None + assert Qt3DCore.QPropertyValueRemovedChange is not None + assert Qt3DCore.QPropertyValueRemovedChangeBase is not None + assert Qt3DCore.QComponentAddedChange is not None + assert Qt3DCore.QNodeCreatedChangeBase is not None + assert Qt3DCore.QNodeDestroyedChange is not None + assert Qt3DCore.QArmature is not None + assert Qt3DCore.QStaticPropertyValueAddedChangeBase is not None + assert Qt3DCore.ChangeFlag is not None + assert Qt3DCore.QSkeleton is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qt3dextras.py b/openpype/vendor/python/python_2/qtpy/tests/test_qt3dextras.py new file mode 100644 index 00000000000..f63c7d57993 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qt3dextras.py @@ -0,0 +1,47 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qt3dextras(): + """Test the qtpy.Qt3DExtras namespace""" + Qt3DExtras = pytest.importorskip("qtpy.Qt3DExtras") + + assert Qt3DExtras.QTextureMaterial is not None + assert Qt3DExtras.QPhongAlphaMaterial is not None + assert Qt3DExtras.QOrbitCameraController is not None + assert Qt3DExtras.QAbstractSpriteSheet is not None + assert Qt3DExtras.QNormalDiffuseMapMaterial is not None + assert Qt3DExtras.QDiffuseSpecularMaterial is not None + assert Qt3DExtras.QSphereGeometry is not None + assert Qt3DExtras.QCuboidGeometry is not None + assert Qt3DExtras.QForwardRenderer is not None + assert Qt3DExtras.QPhongMaterial is not None + assert Qt3DExtras.QSpriteGrid is not None + assert Qt3DExtras.QDiffuseMapMaterial is not None + assert Qt3DExtras.QConeGeometry is not None + assert Qt3DExtras.QSpriteSheetItem is not None + assert Qt3DExtras.QPlaneGeometry is not None + assert Qt3DExtras.QSphereMesh is not None + assert Qt3DExtras.QNormalDiffuseSpecularMapMaterial is not None + assert Qt3DExtras.QCuboidMesh is not None + assert Qt3DExtras.QGoochMaterial is not None + assert Qt3DExtras.QText2DEntity is not None + assert Qt3DExtras.QTorusMesh is not None + assert Qt3DExtras.Qt3DWindow is not None + assert Qt3DExtras.QPerVertexColorMaterial is not None + assert Qt3DExtras.QExtrudedTextGeometry is not None + assert Qt3DExtras.QSkyboxEntity is not None + assert Qt3DExtras.QAbstractCameraController is not None + assert Qt3DExtras.QExtrudedTextMesh is not None + assert Qt3DExtras.QCylinderGeometry is not None + assert Qt3DExtras.QTorusGeometry is not None + assert Qt3DExtras.QMorphPhongMaterial is not None + assert Qt3DExtras.QPlaneMesh is not None + assert Qt3DExtras.QDiffuseSpecularMapMaterial is not None + assert Qt3DExtras.QSpriteSheet is not None + assert Qt3DExtras.QConeMesh is not None + assert Qt3DExtras.QFirstPersonCameraController is not None + assert Qt3DExtras.QMetalRoughMaterial is not None + assert Qt3DExtras.QCylinderMesh is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qt3dinput.py b/openpype/vendor/python/python_2/qtpy/tests/test_qt3dinput.py new file mode 100644 index 00000000000..48d73d03065 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qt3dinput.py @@ -0,0 +1,33 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qt3dinput(): + """Test the qtpy.Qt3DInput namespace""" + Qt3DInput = pytest.importorskip("qtpy.Qt3DInput") + + assert Qt3DInput.QAxisAccumulator is not None + assert Qt3DInput.QInputSettings is not None + assert Qt3DInput.QAnalogAxisInput is not None + assert Qt3DInput.QAbstractAxisInput is not None + assert Qt3DInput.QMouseHandler is not None + assert Qt3DInput.QButtonAxisInput is not None + assert Qt3DInput.QInputSequence is not None + assert Qt3DInput.QWheelEvent is not None + assert Qt3DInput.QActionInput is not None + assert Qt3DInput.QKeyboardDevice is not None + assert Qt3DInput.QMouseDevice is not None + assert Qt3DInput.QAxis is not None + assert Qt3DInput.QInputChord is not None + assert Qt3DInput.QMouseEvent is not None + assert Qt3DInput.QKeyboardHandler is not None + assert Qt3DInput.QKeyEvent is not None + assert Qt3DInput.QAbstractActionInput is not None + assert Qt3DInput.QInputAspect is not None + assert Qt3DInput.QLogicalDevice is not None + assert Qt3DInput.QAction is not None + assert Qt3DInput.QAbstractPhysicalDevice is not None + assert Qt3DInput.QAxisSetting is not None + diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qt3dlogic.py b/openpype/vendor/python/python_2/qtpy/tests/test_qt3dlogic.py new file mode 100644 index 00000000000..34f7de67e47 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qt3dlogic.py @@ -0,0 +1,12 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qt3dlogic(): + """Test the qtpy.Qt3DLogic namespace""" + Qt3DLogic = pytest.importorskip("qtpy.Qt3DLogic") + + assert Qt3DLogic.QLogicAspect is not None + assert Qt3DLogic.QFrameAction is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qt3drender.py b/openpype/vendor/python/python_2/qtpy/tests/test_qt3drender.py new file mode 100644 index 00000000000..f4647682606 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qt3drender.py @@ -0,0 +1,119 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qt3drender(): + """Test the qtpy.Qt3DRender namespace""" + Qt3DRender = pytest.importorskip("qtpy.Qt3DRender") + + assert Qt3DRender.QPointSize is not None + assert Qt3DRender.QFrustumCulling is not None + assert Qt3DRender.QPickPointEvent is not None + assert Qt3DRender.QRenderPassFilter is not None + assert Qt3DRender.QMesh is not None + assert Qt3DRender.QRayCaster is not None + assert Qt3DRender.QStencilMask is not None + assert Qt3DRender.QPickLineEvent is not None + assert Qt3DRender.QPickTriangleEvent is not None + assert Qt3DRender.QRenderState is not None + assert Qt3DRender.QTextureWrapMode is not None + assert Qt3DRender.QRenderPass is not None + assert Qt3DRender.QGeometryRenderer is not None + assert Qt3DRender.QAttribute is not None + assert Qt3DRender.QStencilOperation is not None + assert Qt3DRender.QScissorTest is not None + assert Qt3DRender.QTextureCubeMapArray is not None + assert Qt3DRender.QRenderTarget is not None + assert Qt3DRender.QStencilTest is not None + assert Qt3DRender.QTextureData is not None + assert Qt3DRender.QBuffer is not None + assert Qt3DRender.QLineWidth is not None + assert Qt3DRender.QLayer is not None + assert Qt3DRender.QTextureRectangle is not None + assert Qt3DRender.QRenderTargetSelector is not None + assert Qt3DRender.QPickingSettings is not None + assert Qt3DRender.QCullFace is not None + assert Qt3DRender.QAbstractFunctor is not None + assert Qt3DRender.PropertyReaderInterface is not None + assert Qt3DRender.QMaterial is not None + assert Qt3DRender.QAlphaCoverage is not None + assert Qt3DRender.QClearBuffers is not None + assert Qt3DRender.QAlphaTest is not None + assert Qt3DRender.QStencilOperationArguments is not None + assert Qt3DRender.QTexture2DMultisample is not None + assert Qt3DRender.QLevelOfDetailSwitch is not None + assert Qt3DRender.QRenderStateSet is not None + assert Qt3DRender.QViewport is not None + assert Qt3DRender.QObjectPicker is not None + assert Qt3DRender.QPolygonOffset is not None + assert Qt3DRender.QRenderSettings is not None + assert Qt3DRender.QFrontFace is not None + assert Qt3DRender.QTexture3D is not None + assert Qt3DRender.QTextureBuffer is not None + assert Qt3DRender.QTechniqueFilter is not None + assert Qt3DRender.QLayerFilter is not None + assert Qt3DRender.QFilterKey is not None + assert Qt3DRender.QRenderSurfaceSelector is not None + assert Qt3DRender.QEnvironmentLight is not None + assert Qt3DRender.QMemoryBarrier is not None + assert Qt3DRender.QNoDepthMask is not None + assert Qt3DRender.QBlitFramebuffer is not None + assert Qt3DRender.QGraphicsApiFilter is not None + assert Qt3DRender.QAbstractTexture is not None + assert Qt3DRender.QRenderCaptureReply is not None + assert Qt3DRender.QAbstractLight is not None + assert Qt3DRender.QAbstractRayCaster is not None + assert Qt3DRender.QDirectionalLight is not None + assert Qt3DRender.QDispatchCompute is not None + assert Qt3DRender.QBufferDataGenerator is not None + assert Qt3DRender.QPointLight is not None + assert Qt3DRender.QStencilTestArguments is not None + assert Qt3DRender.QTexture1D is not None + assert Qt3DRender.QCameraSelector is not None + assert Qt3DRender.QProximityFilter is not None + assert Qt3DRender.QTexture1DArray is not None + assert Qt3DRender.QBlendEquation is not None + assert Qt3DRender.QTextureImageDataGenerator is not None + assert Qt3DRender.QSpotLight is not None + assert Qt3DRender.QEffect is not None + assert Qt3DRender.QSeamlessCubemap is not None + assert Qt3DRender.QTexture2DMultisampleArray is not None + assert Qt3DRender.QComputeCommand is not None + assert Qt3DRender.QFrameGraphNode is not None + assert Qt3DRender.QSortPolicy is not None + assert Qt3DRender.QTextureImageData is not None + assert Qt3DRender.QCamera is not None + assert Qt3DRender.QGeometry is not None + assert Qt3DRender.QScreenRayCaster is not None + assert Qt3DRender.QClipPlane is not None + assert Qt3DRender.QMultiSampleAntiAliasing is not None + assert Qt3DRender.QRayCasterHit is not None + assert Qt3DRender.QAbstractTextureImage is not None + assert Qt3DRender.QNoDraw is not None + assert Qt3DRender.QPickEvent is not None + assert Qt3DRender.QRenderCapture is not None + assert Qt3DRender.QDepthTest is not None + assert Qt3DRender.QParameter is not None + assert Qt3DRender.QLevelOfDetail is not None + assert Qt3DRender.QGeometryFactory is not None + assert Qt3DRender.QTexture2D is not None + assert Qt3DRender.QRenderAspect is not None + assert Qt3DRender.QPaintedTextureImage is not None + assert Qt3DRender.QDithering is not None + assert Qt3DRender.QTextureGenerator is not None + assert Qt3DRender.QBlendEquationArguments is not None + assert Qt3DRender.QLevelOfDetailBoundingSphere is not None + assert Qt3DRender.QColorMask is not None + assert Qt3DRender.QSceneLoader is not None + assert Qt3DRender.QTextureLoader is not None + assert Qt3DRender.QShaderProgram is not None + assert Qt3DRender.QTextureCubeMap is not None + assert Qt3DRender.QTexture2DArray is not None + assert Qt3DRender.QTextureImage is not None + assert Qt3DRender.QCameraLens is not None + assert Qt3DRender.QRenderTargetOutput is not None + assert Qt3DRender.QShaderProgramBuilder is not None + assert Qt3DRender.QTechnique is not None + assert Qt3DRender.QShaderData is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtcharts.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtcharts.py new file mode 100644 index 00000000000..4c72dbc30db --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtcharts.py @@ -0,0 +1,11 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYSIDE2 + + +@pytest.mark.skipif(not PYSIDE2, reason="Only available by default in PySide2") +def test_qtcharts(): + """Test the qtpy.QtCharts namespace""" + from qtpy import QtCharts + assert QtCharts.QtCharts.QChart is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtcore.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtcore.py new file mode 100644 index 00000000000..81c1e6c495f --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtcore.py @@ -0,0 +1,29 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2, QtCore + +"""Test QtCore.""" + + +def test_qtmsghandler(): + """Test qtpy.QtMsgHandler""" + assert QtCore.qInstallMessageHandler is not None + + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), + reason="Targeted to PyQt5 or PySide2") +def test_DateTime_toPython(): + """Test QDateTime.toPython""" + assert QtCore.QDateTime.toPython is not None + + +@pytest.mark.skipif(PYSIDE2, + reason="Doesn't seem to be present on PySide2") +def test_QtCore_SignalInstance(): + class ClassWithSignal(QtCore.QObject): + signal = QtCore.Signal() + + instance = ClassWithSignal() + + assert isinstance(instance.signal, QtCore.SignalInstance) diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtdatavisualization.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtdatavisualization.py new file mode 100644 index 00000000000..8e287da622f --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtdatavisualization.py @@ -0,0 +1,86 @@ +from __future__ import absolute_import + +import sys + +import pytest +from qtpy import PYQT5, PYSIDE2 +from qtpy.py3compat import PY3 + +@pytest.mark.skipif( + sys.platform != "win32" or not (PYQT5 or PYSIDE2) or PY3, + reason="Only available in Qt5 bindings and Python 2 on Windows") +def test_qtdatavisualization(): + """Test the qtpy.QtDataVisualization namespace""" + # QtDataVisualization + assert qtpy.QtDataVisualization.QScatter3DSeries is not None + assert qtpy.QtDataVisualization.QSurfaceDataItem is not None + assert qtpy.QtDataVisualization.QSurface3DSeries is not None + assert qtpy.QtDataVisualization.QAbstract3DInputHandler is not None + assert qtpy.QtDataVisualization.QHeightMapSurfaceDataProxy is not None + assert qtpy.QtDataVisualization.QAbstractDataProxy is not None + assert qtpy.QtDataVisualization.Q3DCamera is not None + assert qtpy.QtDataVisualization.QAbstract3DGraph is not None + assert qtpy.QtDataVisualization.QCustom3DVolume is not None + assert qtpy.QtDataVisualization.Q3DInputHandler is not None + assert qtpy.QtDataVisualization.QBarDataProxy is not None + assert qtpy.QtDataVisualization.QSurfaceDataProxy is not None + assert qtpy.QtDataVisualization.QScatterDataItem is not None + assert qtpy.QtDataVisualization.Q3DLight is not None + assert qtpy.QtDataVisualization.QScatterDataProxy is not None + assert qtpy.QtDataVisualization.QValue3DAxis is not None + assert qtpy.QtDataVisualization.Q3DBars is not None + assert qtpy.QtDataVisualization.QBarDataItem is not None + assert qtpy.QtDataVisualization.QItemModelBarDataProxy is not None + assert qtpy.QtDataVisualization.Q3DTheme is not None + assert qtpy.QtDataVisualization.QCustom3DItem is not None + assert qtpy.QtDataVisualization.QItemModelScatterDataProxy is not None + assert qtpy.QtDataVisualization.QValue3DAxisFormatter is not None + assert qtpy.QtDataVisualization.QItemModelSurfaceDataProxy is not None + assert qtpy.QtDataVisualization.Q3DScatter is not None + assert qtpy.QtDataVisualization.QTouch3DInputHandler is not None + assert qtpy.QtDataVisualization.QBar3DSeries is not None + assert qtpy.QtDataVisualization.QAbstract3DAxis is not None + assert qtpy.QtDataVisualization.Q3DScene is not None + assert qtpy.QtDataVisualization.QCategory3DAxis is not None + assert qtpy.QtDataVisualization.QAbstract3DSeries is not None + assert qtpy.QtDataVisualization.Q3DObject is not None + assert qtpy.QtDataVisualization.QCustom3DLabel is not None + assert qtpy.QtDataVisualization.Q3DSurface is not None + assert qtpy.QtDataVisualization.QLogValue3DAxisFormatter is not None + + # QtDatavisualization + assert qtpy.QtDatavisualization.QScatter3DSeries is not None + assert qtpy.QtDatavisualization.QSurfaceDataItem is not None + assert qtpy.QtDatavisualization.QSurface3DSeries is not None + assert qtpy.QtDatavisualization.QAbstract3DInputHandler is not None + assert qtpy.QtDatavisualization.QHeightMapSurfaceDataProxy is not None + assert qtpy.QtDatavisualization.QAbstractDataProxy is not None + assert qtpy.QtDatavisualization.Q3DCamera is not None + assert qtpy.QtDatavisualization.QAbstract3DGraph is not None + assert qtpy.QtDatavisualization.QCustom3DVolume is not None + assert qtpy.QtDatavisualization.Q3DInputHandler is not None + assert qtpy.QtDatavisualization.QBarDataProxy is not None + assert qtpy.QtDatavisualization.QSurfaceDataProxy is not None + assert qtpy.QtDatavisualization.QScatterDataItem is not None + assert qtpy.QtDatavisualization.Q3DLight is not None + assert qtpy.QtDatavisualization.QScatterDataProxy is not None + assert qtpy.QtDatavisualization.QValue3DAxis is not None + assert qtpy.QtDatavisualization.Q3DBars is not None + assert qtpy.QtDatavisualization.QBarDataItem is not None + assert qtpy.QtDatavisualization.QItemModelBarDataProxy is not None + assert qtpy.QtDatavisualization.Q3DTheme is not None + assert qtpy.QtDatavisualization.QCustom3DItem is not None + assert qtpy.QtDatavisualization.QItemModelScatterDataProxy is not None + assert qtpy.QtDatavisualization.QValue3DAxisFormatter is not None + assert qtpy.QtDatavisualization.QItemModelSurfaceDataProxy is not None + assert qtpy.QtDatavisualization.Q3DScatter is not None + assert qtpy.QtDatavisualization.QTouch3DInputHandler is not None + assert qtpy.QtDatavisualization.QBar3DSeries is not None + assert qtpy.QtDatavisualization.QAbstract3DAxis is not None + assert qtpy.QtDatavisualization.Q3DScene is not None + assert qtpy.QtDatavisualization.QCategory3DAxis is not None + assert qtpy.QtDatavisualization.QAbstract3DSeries is not None + assert qtpy.QtDatavisualization.Q3DObject is not None + assert qtpy.QtDatavisualization.QCustom3DLabel is not None + assert qtpy.QtDatavisualization.Q3DSurface is not None + assert qtpy.QtDatavisualization.QLogValue3DAxisFormatter is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtdesigner.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtdesigner.py new file mode 100644 index 00000000000..0327c6f7e3c --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtdesigner.py @@ -0,0 +1,28 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYSIDE2, PYSIDE + +@pytest.mark.skipif(PYSIDE2 or PYSIDE, reason="QtDesigner is not avalaible in PySide/PySide2") +def test_qtdesigner(): + from qtpy import QtDesigner + """Test the qtpy.QtDesigner namespace""" + assert QtDesigner.QAbstractExtensionFactory is not None + assert QtDesigner.QAbstractExtensionManager is not None + assert QtDesigner.QDesignerActionEditorInterface is not None + assert QtDesigner.QDesignerContainerExtension is not None + assert QtDesigner.QDesignerCustomWidgetCollectionInterface is not None + assert QtDesigner.QDesignerCustomWidgetInterface is not None + assert QtDesigner.QDesignerFormEditorInterface is not None + assert QtDesigner.QDesignerFormWindowCursorInterface is not None + assert QtDesigner.QDesignerFormWindowInterface is not None + assert QtDesigner.QDesignerFormWindowManagerInterface is not None + assert QtDesigner.QDesignerMemberSheetExtension is not None + assert QtDesigner.QDesignerObjectInspectorInterface is not None + assert QtDesigner.QDesignerPropertyEditorInterface is not None + assert QtDesigner.QDesignerPropertySheetExtension is not None + assert QtDesigner.QDesignerTaskMenuExtension is not None + assert QtDesigner.QDesignerWidgetBoxInterface is not None + assert QtDesigner.QExtensionFactory is not None + assert QtDesigner.QExtensionManager is not None + assert QtDesigner.QFormBuilder is not None \ No newline at end of file diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qthelp.py b/openpype/vendor/python/python_2/qtpy/tests/test_qthelp.py new file mode 100644 index 00000000000..2b70ca755c7 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qthelp.py @@ -0,0 +1,22 @@ +"""Test for QtHelp namespace.""" + +from __future__ import absolute_import + +import pytest + + +def test_qthelp(): + """Test the qtpy.QtHelp namespace.""" + from qtpy import QtHelp + + assert QtHelp.QHelpContentItem is not None + assert QtHelp.QHelpContentModel is not None + assert QtHelp.QHelpContentWidget is not None + assert QtHelp.QHelpEngine is not None + assert QtHelp.QHelpEngineCore is not None + assert QtHelp.QHelpIndexModel is not None + assert QtHelp.QHelpIndexWidget is not None + assert QtHelp.QHelpSearchEngine is not None + assert QtHelp.QHelpSearchQuery is not None + assert QtHelp.QHelpSearchQueryWidget is not None + assert QtHelp.QHelpSearchResultWidget is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtlocation.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtlocation.py new file mode 100644 index 00000000000..78bf93374fc --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtlocation.py @@ -0,0 +1,48 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qtlocation(): + """Test the qtpy.QtLocation namespace""" + from qtpy import QtLocation + assert QtLocation.QGeoCodeReply is not None + assert QtLocation.QGeoCodingManager is not None + assert QtLocation.QGeoCodingManagerEngine is not None + assert QtLocation.QGeoManeuver is not None + assert QtLocation.QGeoRoute is not None + assert QtLocation.QGeoRouteReply is not None + assert QtLocation.QGeoRouteRequest is not None + assert QtLocation.QGeoRouteSegment is not None + assert QtLocation.QGeoRoutingManager is not None + assert QtLocation.QGeoRoutingManagerEngine is not None + assert QtLocation.QGeoServiceProvider is not None + #assert QtLocation.QGeoServiceProviderFactory is not None + assert QtLocation.QPlace is not None + assert QtLocation.QPlaceAttribute is not None + assert QtLocation.QPlaceCategory is not None + assert QtLocation.QPlaceContactDetail is not None + assert QtLocation.QPlaceContent is not None + assert QtLocation.QPlaceContentReply is not None + assert QtLocation.QPlaceContentRequest is not None + assert QtLocation.QPlaceDetailsReply is not None + assert QtLocation.QPlaceEditorial is not None + assert QtLocation.QPlaceIcon is not None + assert QtLocation.QPlaceIdReply is not None + assert QtLocation.QPlaceImage is not None + assert QtLocation.QPlaceManager is not None + assert QtLocation.QPlaceManagerEngine is not None + assert QtLocation.QPlaceMatchReply is not None + assert QtLocation.QPlaceMatchRequest is not None + assert QtLocation.QPlaceProposedSearchResult is not None + assert QtLocation.QPlaceRatings is not None + assert QtLocation.QPlaceReply is not None + assert QtLocation.QPlaceResult is not None + assert QtLocation.QPlaceReview is not None + assert QtLocation.QPlaceSearchReply is not None + assert QtLocation.QPlaceSearchRequest is not None + assert QtLocation.QPlaceSearchResult is not None + assert QtLocation.QPlaceSearchSuggestionReply is not None + assert QtLocation.QPlaceSupplier is not None + assert QtLocation.QPlaceUser is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtmultimedia.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtmultimedia.py new file mode 100644 index 00000000000..1fc7ec97b8c --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtmultimedia.py @@ -0,0 +1,18 @@ +from __future__ import absolute_import +import os +import sys + +import pytest + + +@pytest.mark.skipif(sys.version_info[0] == 3, + reason="Conda packages don't seem to include QtMultimedia") +def test_qtmultimedia(): + """Test the qtpy.QtMultimedia namespace""" + from qtpy import QtMultimedia + + assert QtMultimedia.QAbstractVideoBuffer is not None + assert QtMultimedia.QAudio is not None + assert QtMultimedia.QAudioDeviceInfo is not None + assert QtMultimedia.QAudioInput is not None + assert QtMultimedia.QSound is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtmultimediawidgets.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtmultimediawidgets.py new file mode 100644 index 00000000000..bd659e5183d --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtmultimediawidgets.py @@ -0,0 +1,18 @@ +from __future__ import absolute_import +import os +import sys + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +@pytest.mark.skipif(sys.version_info[0] == 3, + reason="Conda packages don't seem to include QtMultimedia") +def test_qtmultimediawidgets(): + """Test the qtpy.QtMultimediaWidgets namespace""" + from qtpy import QtMultimediaWidgets + + assert QtMultimediaWidgets.QCameraViewfinder is not None + assert QtMultimediaWidgets.QGraphicsVideoItem is not None + assert QtMultimediaWidgets.QVideoWidget is not None + #assert QtMultimediaWidgets.QVideoWidgetControl is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtnetwork.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtnetwork.py new file mode 100644 index 00000000000..7f645910a5f --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtnetwork.py @@ -0,0 +1,43 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYSIDE, PYSIDE2, QtNetwork + + +def test_qtnetwork(): + """Test the qtpy.QtNetwork namespace""" + assert QtNetwork.QAbstractNetworkCache is not None + assert QtNetwork.QNetworkCacheMetaData is not None + if not PYSIDE and not PYSIDE2: + assert QtNetwork.QHttpMultiPart is not None + assert QtNetwork.QHttpPart is not None + assert QtNetwork.QNetworkAccessManager is not None + assert QtNetwork.QNetworkCookie is not None + assert QtNetwork.QNetworkCookieJar is not None + assert QtNetwork.QNetworkDiskCache is not None + assert QtNetwork.QNetworkReply is not None + assert QtNetwork.QNetworkRequest is not None + assert QtNetwork.QNetworkConfigurationManager is not None + assert QtNetwork.QNetworkConfiguration is not None + assert QtNetwork.QNetworkSession is not None + assert QtNetwork.QAuthenticator is not None + assert QtNetwork.QHostAddress is not None + assert QtNetwork.QHostInfo is not None + assert QtNetwork.QNetworkAddressEntry is not None + assert QtNetwork.QNetworkInterface is not None + assert QtNetwork.QNetworkProxy is not None + assert QtNetwork.QNetworkProxyFactory is not None + assert QtNetwork.QNetworkProxyQuery is not None + assert QtNetwork.QAbstractSocket is not None + assert QtNetwork.QLocalServer is not None + assert QtNetwork.QLocalSocket is not None + assert QtNetwork.QTcpServer is not None + assert QtNetwork.QTcpSocket is not None + assert QtNetwork.QUdpSocket is not None + if not PYSIDE: + assert QtNetwork.QSslCertificate is not None + assert QtNetwork.QSslCipher is not None + assert QtNetwork.QSslConfiguration is not None + assert QtNetwork.QSslError is not None + assert QtNetwork.QSslKey is not None + assert QtNetwork.QSslSocket is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtpositioning.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtpositioning.py new file mode 100644 index 00000000000..f6b5bffa9c6 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtpositioning.py @@ -0,0 +1,28 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qtpositioning(): + """Test the qtpy.QtPositioning namespace""" + from qtpy import QtPositioning + assert QtPositioning.QGeoAddress is not None + assert QtPositioning.QGeoAreaMonitorInfo is not None + assert QtPositioning.QGeoAreaMonitorSource is not None + assert QtPositioning.QGeoCircle is not None + assert QtPositioning.QGeoCoordinate is not None + assert QtPositioning.QGeoLocation is not None + assert QtPositioning.QGeoPath is not None + # CI for Python 2.7 and 3.6 uses Qt 5.9 + # assert QtPositioning.QGeoPolygon is not None # New in Qt 5.10 + assert QtPositioning.QGeoPositionInfo is not None + assert QtPositioning.QGeoPositionInfoSource is not None + # QGeoPositionInfoSourceFactory is not available in PyQt + # assert QtPositioning.QGeoPositionInfoSourceFactory is not None # New in Qt 5.2 + # assert QtPositioning.QGeoPositionInfoSourceFactoryV2 is not None # New in Qt 5.14 + assert QtPositioning.QGeoRectangle is not None + assert QtPositioning.QGeoSatelliteInfo is not None + assert QtPositioning.QGeoSatelliteInfoSource is not None + assert QtPositioning.QGeoShape is not None + assert QtPositioning.QNmeaPositionInfoSource is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtprintsupport.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtprintsupport.py new file mode 100644 index 00000000000..2e8f786136d --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtprintsupport.py @@ -0,0 +1,18 @@ +from __future__ import absolute_import + +import pytest +from qtpy import QtPrintSupport + + +def test_qtprintsupport(): + """Test the qtpy.QtPrintSupport namespace""" + assert QtPrintSupport.QAbstractPrintDialog is not None + assert QtPrintSupport.QPageSetupDialog is not None + assert QtPrintSupport.QPrintDialog is not None + assert QtPrintSupport.QPrintPreviewDialog is not None + assert QtPrintSupport.QPrintEngine is not None + assert QtPrintSupport.QPrinter is not None + assert QtPrintSupport.QPrinterInfo is not None + assert QtPrintSupport.QPrintPreviewWidget is not None + + diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtqml.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtqml.py new file mode 100644 index 00000000000..a6d7ca951f2 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtqml.py @@ -0,0 +1,34 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qtqml(): + """Test the qtpy.QtQml namespace""" + from qtpy import QtQml + assert QtQml.QJSEngine is not None + assert QtQml.QJSValue is not None + assert QtQml.QJSValueIterator is not None + assert QtQml.QQmlAbstractUrlInterceptor is not None + assert QtQml.QQmlApplicationEngine is not None + assert QtQml.QQmlComponent is not None + assert QtQml.QQmlContext is not None + assert QtQml.QQmlEngine is not None + assert QtQml.QQmlImageProviderBase is not None + assert QtQml.QQmlError is not None + assert QtQml.QQmlExpression is not None + assert QtQml.QQmlExtensionPlugin is not None + assert QtQml.QQmlFileSelector is not None + assert QtQml.QQmlIncubationController is not None + assert QtQml.QQmlIncubator is not None + if not PYSIDE2: + # https://wiki.qt.io/Qt_for_Python_Missing_Bindings#QtQml + assert QtQml.QQmlListProperty is not None + assert QtQml.QQmlListReference is not None + assert QtQml.QQmlNetworkAccessManagerFactory is not None + assert QtQml.QQmlParserStatus is not None + assert QtQml.QQmlProperty is not None + assert QtQml.QQmlPropertyValueSource is not None + assert QtQml.QQmlScriptString is not None + assert QtQml.QQmlPropertyMap is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtquick.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtquick.py new file mode 100644 index 00000000000..257fd7405e8 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtquick.py @@ -0,0 +1,53 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qtquick(): + """Test the qtpy.QtQuick namespace""" + from qtpy import QtQuick + assert QtQuick.QQuickAsyncImageProvider is not None + if not PYSIDE2: + assert QtQuick.QQuickCloseEvent is not None + assert QtQuick.QQuickFramebufferObject is not None + assert QtQuick.QQuickImageProvider is not None + assert QtQuick.QQuickImageResponse is not None + assert QtQuick.QQuickItem is not None + assert QtQuick.QQuickItemGrabResult is not None + assert QtQuick.QQuickPaintedItem is not None + assert QtQuick.QQuickRenderControl is not None + assert QtQuick.QQuickTextDocument is not None + assert QtQuick.QQuickTextureFactory is not None + assert QtQuick.QQuickView is not None + assert QtQuick.QQuickWindow is not None + assert QtQuick.QSGAbstractRenderer is not None + assert QtQuick.QSGBasicGeometryNode is not None + assert QtQuick.QSGClipNode is not None + assert QtQuick.QSGDynamicTexture is not None + assert QtQuick.QSGEngine is not None + if not PYSIDE2: + assert QtQuick.QSGFlatColorMaterial is not None + assert QtQuick.QSGGeometry is not None + assert QtQuick.QSGGeometryNode is not None + #assert QtQuick.QSGImageNode is not None + if not PYSIDE2: + assert QtQuick.QSGMaterial is not None + assert QtQuick.QSGMaterialShader is not None + assert QtQuick.QSGMaterialType is not None + assert QtQuick.QSGNode is not None + assert QtQuick.QSGOpacityNode is not None + if not PYSIDE2: + assert QtQuick.QSGOpaqueTextureMaterial is not None + #assert QtQuick.QSGRectangleNode is not None + #assert QtQuick.QSGRenderNode is not None + #assert QtQuick.QSGRendererInterface is not None + assert QtQuick.QSGSimpleRectNode is not None + assert QtQuick.QSGSimpleTextureNode is not None + assert QtQuick.QSGTexture is not None + if not PYSIDE2: + assert QtQuick.QSGTextureMaterial is not None + assert QtQuick.QSGTextureProvider is not None + assert QtQuick.QSGTransformNode is not None + if not PYSIDE2: + assert QtQuick.QSGVertexColorMaterial is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtquickwidgets.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtquickwidgets.py new file mode 100644 index 00000000000..0b41a8bd8ea --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtquickwidgets.py @@ -0,0 +1,10 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qtquickwidgets(): + """Test the qtpy.QtQuickWidgets namespace""" + from qtpy import QtQuickWidgets + assert QtQuickWidgets.QQuickWidget is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtserialport.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtserialport.py new file mode 100644 index 00000000000..26daaf76bbe --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtserialport.py @@ -0,0 +1,12 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5 + +@pytest.mark.skipif(not PYQT5, reason="Only available in Qt5 bindings, but still not in PySide2") +def test_qtserialport(): + """Test the qtpy.QtSerialPort namespace""" + from qtpy import QtSerialPort + + assert QtSerialPort.QSerialPort is not None + assert QtSerialPort.QSerialPortInfo is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtsql.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtsql.py new file mode 100644 index 00000000000..1e7404ffdcf --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtsql.py @@ -0,0 +1,24 @@ +from __future__ import absolute_import + +import pytest +from qtpy import QtSql + +def test_qtsql(): + """Test the qtpy.QtSql namespace""" + assert QtSql.QSqlDatabase is not None + assert QtSql.QSqlDriverCreatorBase is not None + assert QtSql.QSqlDriver is not None + assert QtSql.QSqlError is not None + assert QtSql.QSqlField is not None + assert QtSql.QSqlIndex is not None + assert QtSql.QSqlQuery is not None + assert QtSql.QSqlRecord is not None + assert QtSql.QSqlResult is not None + assert QtSql.QSqlQueryModel is not None + assert QtSql.QSqlRelationalDelegate is not None + assert QtSql.QSqlRelation is not None + assert QtSql.QSqlRelationalTableModel is not None + assert QtSql.QSqlTableModel is not None + + # Following modules are not (yet) part of any wrapper: + # QSqlDriverCreator, QSqlDriverPlugin diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtsvg.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtsvg.py new file mode 100644 index 00000000000..74d8522e725 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtsvg.py @@ -0,0 +1,13 @@ +from __future__ import absolute_import + +import pytest + + +def test_qtsvg(): + """Test the qtpy.QtSvg namespace""" + from qtpy import QtSvg + + assert QtSvg.QGraphicsSvgItem is not None + assert QtSvg.QSvgGenerator is not None + assert QtSvg.QSvgRenderer is not None + assert QtSvg.QSvgWidget is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qttest.py b/openpype/vendor/python/python_2/qtpy/tests/test_qttest.py new file mode 100644 index 00000000000..5d2ab9e156d --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qttest.py @@ -0,0 +1,9 @@ +from __future__ import absolute_import + +import pytest +from qtpy import QtTest + + +def test_qttest(): + """Test the qtpy.QtTest namespace""" + assert QtTest.QTest is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtwebchannel.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtwebchannel.py new file mode 100644 index 00000000000..2beb70c0afc --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtwebchannel.py @@ -0,0 +1,13 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qtwebchannel(): + """Test the qtpy.QtWebChannel namespace""" + from qtpy import QtWebChannel + + assert QtWebChannel.QWebChannel is not None + assert QtWebChannel.QWebChannelAbstractTransport is not None + diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtwebenginewidgets.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtwebenginewidgets.py new file mode 100644 index 00000000000..77c8e1f5fb1 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtwebenginewidgets.py @@ -0,0 +1,12 @@ +from __future__ import absolute_import + +import pytest +from qtpy import QtWebEngineWidgets + + +def test_qtwebenginewidgets(): + """Test the qtpy.QtWebSockets namespace""" + + assert QtWebEngineWidgets.QWebEnginePage is not None + assert QtWebEngineWidgets.QWebEngineView is not None + assert QtWebEngineWidgets.QWebEngineSettings is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtwebsockets.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtwebsockets.py new file mode 100644 index 00000000000..5bdcc32565a --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtwebsockets.py @@ -0,0 +1,15 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYQT5, PYSIDE2 + +@pytest.mark.skipif(not (PYQT5 or PYSIDE2), reason="Only available in Qt5 bindings") +def test_qtwebsockets(): + """Test the qtpy.QtWebSockets namespace""" + from qtpy import QtWebSockets + + assert QtWebSockets.QMaskGenerator is not None + assert QtWebSockets.QWebSocket is not None + assert QtWebSockets.QWebSocketCorsAuthenticator is not None + assert QtWebSockets.QWebSocketProtocol is not None + assert QtWebSockets.QWebSocketServer is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtwinextras.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtwinextras.py new file mode 100644 index 00000000000..f41f9ff6998 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtwinextras.py @@ -0,0 +1,29 @@ +from __future__ import absolute_import + +import os +import sys + +import pytest +from qtpy import PYSIDE2 + +@pytest.mark.skipif( + sys.platform != "win32" or os.environ['USE_CONDA'] == 'Yes', + reason="Only available in Qt5 bindings > 5.9 (only available with pip in the current CI setup) and Windows platform") +def test_qtwinextras(): + """Test the qtpy.QtWinExtras namespace""" + from qtpy import QtWinExtras + assert QtWinExtras.QWinJumpList is not None + assert QtWinExtras.QWinJumpListCategory is not None + assert QtWinExtras.QWinJumpListItem is not None + assert QtWinExtras.QWinTaskbarButton is not None + assert QtWinExtras.QWinTaskbarProgress is not None + assert QtWinExtras.QWinThumbnailToolBar is not None + assert QtWinExtras.QWinThumbnailToolButton is not None + if not PYSIDE2: # See https://bugreports.qt.io/browse/PYSIDE-1047 + assert QtWinExtras.QtWin is not None + + if PYSIDE2: + assert QtWinExtras.QWinColorizationChangeEvent is not None + assert QtWinExtras.QWinCompositionChangeEvent is not None + assert QtWinExtras.QWinEvent is not None + diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_qtxmlpatterns.py b/openpype/vendor/python/python_2/qtpy/tests/test_qtxmlpatterns.py new file mode 100644 index 00000000000..4c6d4cb9aad --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_qtxmlpatterns.py @@ -0,0 +1,25 @@ +from __future__ import absolute_import + +import pytest +from qtpy import PYSIDE2, PYSIDE + +def test_qtxmlpatterns(): + """Test the qtpy.QtXmlPatterns namespace""" + from qtpy import QtXmlPatterns + assert QtXmlPatterns.QAbstractMessageHandler is not None + assert QtXmlPatterns.QAbstractUriResolver is not None + assert QtXmlPatterns.QAbstractXmlNodeModel is not None + assert QtXmlPatterns.QAbstractXmlReceiver is not None + if not PYSIDE2 and not PYSIDE: + assert QtXmlPatterns.QSimpleXmlNodeModel is not None + assert QtXmlPatterns.QSourceLocation is not None + assert QtXmlPatterns.QXmlFormatter is not None + assert QtXmlPatterns.QXmlItem is not None + assert QtXmlPatterns.QXmlName is not None + assert QtXmlPatterns.QXmlNamePool is not None + assert QtXmlPatterns.QXmlNodeModelIndex is not None + assert QtXmlPatterns.QXmlQuery is not None + assert QtXmlPatterns.QXmlResultItems is not None + assert QtXmlPatterns.QXmlSchema is not None + assert QtXmlPatterns.QXmlSchemaValidator is not None + assert QtXmlPatterns.QXmlSerializer is not None diff --git a/openpype/vendor/python/python_2/qtpy/tests/test_uic.py b/openpype/vendor/python/python_2/qtpy/tests/test_uic.py new file mode 100644 index 00000000000..d7d3b599ec0 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/tests/test_uic.py @@ -0,0 +1,116 @@ +import os +import sys +import contextlib + +import pytest +from qtpy import PYQT5, PYSIDE2, PYSIDE, QtWidgets +from qtpy.QtWidgets import QComboBox + +if PYSIDE2 or PYSIDE: + pytest.importorskip("pyside2uic", reason="pyside2uic not installed") + +from qtpy import uic +from qtpy.uic import loadUi, loadUiType + + +QCOMBOBOX_SUBCLASS = """ +from qtpy.QtWidgets import QComboBox +class _QComboBoxSubclass(QComboBox): + pass +""" + +@contextlib.contextmanager +def enabled_qcombobox_subclass(tmpdir): + """ + Context manager that sets up a temporary module with a QComboBox subclass + and then removes it once we are done. + """ + + with open(tmpdir.join('qcombobox_subclass.py').strpath, 'w') as f: + f.write(QCOMBOBOX_SUBCLASS) + + sys.path.insert(0, tmpdir.strpath) + + yield + + sys.path.pop(0) + + +def get_qapp(icon_path=None): + """ + Helper function to return a QApplication instance + """ + qapp = QtWidgets.QApplication.instance() + if qapp is None: + qapp = QtWidgets.QApplication(['']) + return qapp + + +@pytest.mark.skipif(((PYSIDE2 or PYQT5) + and os.environ.get('CI', None) is not None), + reason="It segfaults in our CIs with PYSIDE2 or PYQT5") +def test_load_ui(): + """ + Make sure that the patched loadUi function behaves as expected with a + simple .ui file. + """ + app = get_qapp() + ui = loadUi(os.path.join(os.path.dirname(__file__), 'test.ui')) + assert isinstance(ui.pushButton, QtWidgets.QPushButton) + assert isinstance(ui.comboBox, QComboBox) + + +@pytest.mark.skipif(((PYSIDE2 or PYQT5) + and os.environ.get('CI', None) is not None), + reason="It segfaults in our CIs with PYSIDE2 or PYQT5") +def test_load_ui_type(): + """ + Make sure that the patched loadUiType function behaves as expected with a + simple .ui file. + """ + app = get_qapp() + ui_type, ui_base_type = loadUiType( + os.path.join(os.path.dirname(__file__), 'test.ui')) + assert ui_type.__name__ == 'Ui_Form' + + class Widget(ui_base_type, ui_type): + def __init__(self): + super(Widget, self).__init__() + self.setupUi(self) + + ui = Widget() + assert isinstance(ui, QtWidgets.QWidget) + assert isinstance(ui.pushButton, QtWidgets.QPushButton) + assert isinstance(ui.comboBox, QComboBox) + + +@pytest.mark.skipif(((PYSIDE2 or PYQT5) + and os.environ.get('CI', None) is not None), + reason="It segfaults in our CIs with PYSIDE2 or PYQT5") +def test_load_ui_custom_auto(tmpdir): + """ + Test that we can load a .ui file with custom widgets without having to + explicitly specify a dictionary of custom widgets, even in the case of + PySide. + """ + + app = get_qapp() + + with enabled_qcombobox_subclass(tmpdir): + from qcombobox_subclass import _QComboBoxSubclass + ui = loadUi(os.path.join(os.path.dirname(__file__), 'test_custom.ui')) + + assert isinstance(ui.pushButton, QtWidgets.QPushButton) + assert isinstance(ui.comboBox, _QComboBoxSubclass) + + +def test_load_full_uic(): + """Test that we load the full uic objects for PyQt5 and PyQt4.""" + QT_API = os.environ.get('QT_API', '').lower() + if QT_API.startswith('pyside'): + assert hasattr(uic, 'loadUi') + assert hasattr(uic, 'loadUiType') + else: + objects = ['compileUi', 'compileUiDir', 'loadUi', 'loadUiType', + 'widgetPluginPath'] + assert all([hasattr(uic, o) for o in objects]) diff --git a/openpype/vendor/python/python_2/qtpy/uic.py b/openpype/vendor/python/python_2/qtpy/uic.py new file mode 100644 index 00000000000..d26a25a15d4 --- /dev/null +++ b/openpype/vendor/python/python_2/qtpy/uic.py @@ -0,0 +1,277 @@ +import os + +from . import PYSIDE, PYSIDE2, PYQT4, PYQT5 +from .QtWidgets import QComboBox + + +if PYQT5: + + from PyQt5.uic import * + +elif PYQT4: + + from PyQt4.uic import * + +else: + + __all__ = ['loadUi', 'loadUiType'] + + # In PySide, loadUi does not exist, so we define it using QUiLoader, and + # then make sure we expose that function. This is adapted from qt-helpers + # which was released under a 3-clause BSD license: + # qt-helpers - a common front-end to various Qt modules + # + # Copyright (c) 2015, Chris Beaumont and Thomas Robitaille + # + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are + # met: + # + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the + # distribution. + # * Neither the name of the Glue project nor the names of its contributors + # may be used to endorse or promote products derived from this software + # without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # + # Which itself was based on the solution at + # + # https://gist.github.com/cpbotha/1b42a20c8f3eb9bb7cb8 + # + # which was released under the MIT license: + # + # Copyright (c) 2011 Sebastian Wiesner + # Modifications by Charl Botha + # + # Permission is hereby granted, free of charge, to any person obtaining a + # copy of this software and associated documentation files (the "Software"), + # to deal in the Software without restriction, including without limitation + # the rights to use, copy, modify, merge, publish, distribute, sublicense, + # and/or sell copies of the Software, and to permit persons to whom the + # Software is furnished to do so, subject to the following conditions: + # + # The above copyright notice and this permission notice shall be included in + # all copies or substantial portions of the Software. + # + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + # DEALINGS IN THE SOFTWARE. + + if PYSIDE: + from PySide.QtCore import QMetaObject + from PySide.QtUiTools import QUiLoader + try: + from pysideuic import compileUi + except ImportError: + pass + elif PYSIDE2: + from PySide2.QtCore import QMetaObject + from PySide2.QtUiTools import QUiLoader + try: + from pyside2uic import compileUi + except ImportError: + pass + + class UiLoader(QUiLoader): + """ + Subclass of :class:`~PySide.QtUiTools.QUiLoader` to create the user + interface in a base instance. + + Unlike :class:`~PySide.QtUiTools.QUiLoader` itself this class does not + create a new instance of the top-level widget, but creates the user + interface in an existing instance of the top-level class if needed. + + This mimics the behaviour of :func:`PyQt4.uic.loadUi`. + """ + + def __init__(self, baseinstance, customWidgets=None): + """ + Create a loader for the given ``baseinstance``. + + The user interface is created in ``baseinstance``, which must be an + instance of the top-level class in the user interface to load, or a + subclass thereof. + + ``customWidgets`` is a dictionary mapping from class name to class + object for custom widgets. Usually, this should be done by calling + registerCustomWidget on the QUiLoader, but with PySide 1.1.2 on + Ubuntu 12.04 x86_64 this causes a segfault. + + ``parent`` is the parent object of this loader. + """ + + QUiLoader.__init__(self, baseinstance) + + self.baseinstance = baseinstance + + if customWidgets is None: + self.customWidgets = {} + else: + self.customWidgets = customWidgets + + def createWidget(self, class_name, parent=None, name=''): + """ + Function that is called for each widget defined in ui file, + overridden here to populate baseinstance instead. + """ + + if parent is None and self.baseinstance: + # supposed to create the top-level widget, return the base + # instance instead + return self.baseinstance + + else: + + # For some reason, Line is not in the list of available + # widgets, but works fine, so we have to special case it here. + if class_name in self.availableWidgets() or class_name == 'Line': + # create a new widget for child widgets + widget = QUiLoader.createWidget(self, class_name, parent, name) + + else: + # If not in the list of availableWidgets, must be a custom + # widget. This will raise KeyError if the user has not + # supplied the relevant class_name in the dictionary or if + # customWidgets is empty. + try: + widget = self.customWidgets[class_name](parent) + except KeyError: + raise Exception('No custom widget ' + class_name + ' ' + 'found in customWidgets') + + if self.baseinstance: + # set an attribute for the new child widget on the base + # instance, just like PyQt4.uic.loadUi does. + setattr(self.baseinstance, name, widget) + + return widget + + def _get_custom_widgets(ui_file): + """ + This function is used to parse a ui file and look for the + section, then automatically load all the custom widget classes. + """ + + import sys + import importlib + from xml.etree.ElementTree import ElementTree + + # Parse the UI file + etree = ElementTree() + ui = etree.parse(ui_file) + + # Get the customwidgets section + custom_widgets = ui.find('customwidgets') + + if custom_widgets is None: + return {} + + custom_widget_classes = {} + + for custom_widget in list(custom_widgets): + + cw_class = custom_widget.find('class').text + cw_header = custom_widget.find('header').text + + module = importlib.import_module(cw_header) + + custom_widget_classes[cw_class] = getattr(module, cw_class) + + return custom_widget_classes + + def loadUi(uifile, baseinstance=None, workingDirectory=None): + """ + Dynamically load a user interface from the given ``uifile``. + + ``uifile`` is a string containing a file name of the UI file to load. + + If ``baseinstance`` is ``None``, the a new instance of the top-level + widget will be created. Otherwise, the user interface is created within + the given ``baseinstance``. In this case ``baseinstance`` must be an + instance of the top-level widget class in the UI file to load, or a + subclass thereof. In other words, if you've created a ``QMainWindow`` + interface in the designer, ``baseinstance`` must be a ``QMainWindow`` + or a subclass thereof, too. You cannot load a ``QMainWindow`` UI file + with a plain :class:`~PySide.QtGui.QWidget` as ``baseinstance``. + + :method:`~PySide.QtCore.QMetaObject.connectSlotsByName()` is called on + the created user interface, so you can implemented your slots according + to its conventions in your widget class. + + Return ``baseinstance``, if ``baseinstance`` is not ``None``. Otherwise + return the newly created instance of the user interface. + """ + + # We parse the UI file and import any required custom widgets + customWidgets = _get_custom_widgets(uifile) + + loader = UiLoader(baseinstance, customWidgets) + + if workingDirectory is not None: + loader.setWorkingDirectory(workingDirectory) + + widget = loader.load(uifile) + QMetaObject.connectSlotsByName(widget) + return widget + + def loadUiType(uifile, from_imports=False): + """Load a .ui file and return the generated form class and + the Qt base class. + + The "loadUiType" command convert the ui file to py code + in-memory first and then execute it in a special frame to + retrieve the form_class. + + Credit: https://stackoverflow.com/a/14195313/15954282 + """ + + import sys + if sys.version_info >= (3, 0): + from io import StringIO + else: + from io import BytesIO as StringIO + from xml.etree.ElementTree import ElementTree + from . import QtWidgets + + # Parse the UI file + etree = ElementTree() + ui = etree.parse(uifile) + + widget_class = ui.find('widget').get('class') + form_class = ui.find('class').text + + with open(uifile, 'r') as fd: + code_stream = StringIO() + frame = {} + + compileUi(fd, code_stream, indent=0, from_imports=from_imports) + pyc = compile(code_stream.getvalue(), '', 'exec') + exec(pyc, frame) + + # Fetch the base_class and form class based on their type in the + # xml from designer + form_class = frame['Ui_%s' % form_class] + base_class = getattr(QtWidgets, widget_class) + + return form_class, base_class From 8277adc7df0cb253ab35b3a67c4432955e5e5510 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 14:13:48 +0100 Subject: [PATCH 19/42] updated QtPy to 2.3.0 --- poetry.lock | 17 ++++++++++------- pyproject.toml | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5873ce50b64..a400a19c278 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1316,11 +1316,17 @@ six = "*" [[package]] name = "qtpy" -version = "1.11.3" -description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5, PyQt4 and PySide) and additional custom QWidgets." +version = "2.3.0" +description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6)." category = "main" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" +python-versions = ">=3.7" + +[package.dependencies] +packaging = "*" + +[package.extras] +test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] [[package]] name = "recommonmark" @@ -2925,10 +2931,7 @@ qtawesome = [ {file = "QtAwesome-0.7.3-py2.py3-none-any.whl", hash = "sha256:ddf4530b4af71cec13b24b88a4cdb56ec85b1e44c43c42d0698804c7137b09b0"}, {file = "QtAwesome-0.7.3.tar.gz", hash = "sha256:b98b9038d19190e83ab26d91c4d8fc3a36591ee2bc7f5016d4438b8240d097bd"}, ] -qtpy = [ - {file = "QtPy-1.11.3-py2.py3-none-any.whl", hash = "sha256:e121fbee8e95645af29c5a4aceba8d657991551fc1aa3b6b6012faf4725a1d20"}, - {file = "QtPy-1.11.3.tar.gz", hash = "sha256:d427addd37386a8d786db81864a5536700861d95bf085cb31d1bea855d699557"}, -] +qtpy = [] recommonmark = [ {file = "recommonmark-0.7.1-py2.py3-none-any.whl", hash = "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f"}, {file = "recommonmark-0.7.1.tar.gz", hash = "sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67"}, diff --git a/pyproject.toml b/pyproject.toml index 2a4bb5e86e2..72193f732e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ pyblish-base = "^1.8.8" pynput = "^1.7.2" # idle manager in tray pymongo = "^3.11.2" "Qt.py" = "^1.3.3" -qtpy = "^1.11.3" +QtPy = "^2.3.0" qtawesome = "0.7.3" speedcopy = "^2.1" six = "^1.15" From 8e19d0957d97396133bc817c383c6fd7ab60aee2 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 15:19:40 +0100 Subject: [PATCH 20/42] use class attributes from classes instead of objects --- openpype/modules/sync_server/tray/widgets.py | 12 ++++++++---- openpype/tools/launcher/window.py | 2 +- .../publisher/publish_report_viewer/widgets.py | 2 +- .../publisher/widgets/list_view_widgets.py | 9 ++++++--- openpype/tools/publisher/widgets/widgets.py | 6 ++++-- openpype/tools/pyblish_pype/view.py | 4 ++-- openpype/tools/sceneinventory/view.py | 8 ++++---- .../settings/settings/breadcrumbs_widget.py | 4 ++-- .../standalonepublish/widgets/widget_asset.py | 10 ++++++++-- openpype/tools/utils/assets_widget.py | 10 +++++++--- openpype/tools/utils/lib.py | 17 ++++++++++++----- openpype/tools/utils/tasks_widget.py | 5 ++++- 12 files changed, 59 insertions(+), 30 deletions(-) diff --git a/openpype/modules/sync_server/tray/widgets.py b/openpype/modules/sync_server/tray/widgets.py index b9ef45727a2..75a6d20d3cf 100644 --- a/openpype/modules/sync_server/tray/widgets.py +++ b/openpype/modules/sync_server/tray/widgets.py @@ -156,8 +156,10 @@ def refresh(self): if selected_index and \ selected_index.isValid() and \ not self._selection_changed: - mode = QtCore.QItemSelectionModel.Select | \ - QtCore.QItemSelectionModel.Rows + mode = ( + QtCore.QItemSelectionModel.Select + | QtCore.QItemSelectionModel.Rows + ) self.project_list.selectionModel().select(selected_index, mode) if self.current_project: @@ -271,8 +273,10 @@ def _set_selection(self): for selected_id in self._selected_ids: index = self.model.get_index(selected_id) if index and index.isValid(): - mode = QtCore.QItemSelectionModel.Select | \ - QtCore.QItemSelectionModel.Rows + mode = ( + QtCore.QItemSelectionModel.Select + | QtCore.QItemSelectionModel.Rows + ) self.selection_model.select(index, mode) existing_ids.add(selected_id) diff --git a/openpype/tools/launcher/window.py b/openpype/tools/launcher/window.py index f68fc4befc7..fcc8c0ba385 100644 --- a/openpype/tools/launcher/window.py +++ b/openpype/tools/launcher/window.py @@ -40,7 +40,7 @@ def __init__(self, parent=None, mode=ListMode): # Workaround for scrolling being super slow or fast when # toggling between the two visual modes - self.setVerticalScrollMode(self.ScrollPerPixel) + self.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) self.setObjectName("IconView") self._mode = None diff --git a/openpype/tools/publisher/publish_report_viewer/widgets.py b/openpype/tools/publisher/publish_report_viewer/widgets.py index 7066efed325..84af9bb1b86 100644 --- a/openpype/tools/publisher/publish_report_viewer/widgets.py +++ b/openpype/tools/publisher/publish_report_viewer/widgets.py @@ -80,7 +80,7 @@ def __init__(self, parent): view.setTextElideMode(QtCore.Qt.ElideLeft) view.setHeaderHidden(True) view.setAlternatingRowColors(True) - view.setVerticalScrollMode(view.ScrollPerPixel) + view.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) model = PluginLoadReportModel() view.setModel(model) diff --git a/openpype/tools/publisher/widgets/list_view_widgets.py b/openpype/tools/publisher/widgets/list_view_widgets.py index 57c1e769e48..28feeee7aa8 100644 --- a/openpype/tools/publisher/widgets/list_view_widgets.py +++ b/openpype/tools/publisher/widgets/list_view_widgets.py @@ -1031,17 +1031,20 @@ def set_selected_items( selection_model.setCurrentIndex( first_index, - selection_model.ClearAndSelect | selection_model.Rows + QtCore.QItemSelectionModel.ClearAndSelect + | QtCore.QItemSelectionModel.Rows ) for index in select_indexes: proxy_index = proxy_model.mapFromSource(index) selection_model.select( proxy_index, - selection_model.Select | selection_model.Rows + QtCore.QItemSelectionModel.Select + | QtCore.QItemSelectionModel.Rows ) selection_model.setCurrentIndex( last_index, - selection_model.Select | selection_model.Rows + QtCore.QItemSelectionModel.Select + | QtCore.QItemSelectionModel.Rows ) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index 16641bfb6c5..f65d0302c53 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -412,7 +412,8 @@ def __init__(self, controller, parent): icon_btn ): size_policy = widget.sizePolicy() - size_policy.setVerticalPolicy(size_policy.MinimumExpanding) + size_policy.setVerticalPolicy( + QtWidgets.QSizePolicy.MinimumExpanding) widget.setSizePolicy(size_policy) name_input.clicked.connect(self._mouse_release_callback) icon_btn.clicked.connect(self._mouse_release_callback) @@ -595,7 +596,8 @@ def __init__(self, controller, parent): # Make sure combobox is extended horizontally size_policy = self.sizePolicy() - size_policy.setHorizontalPolicy(size_policy.MinimumExpanding) + size_policy.setHorizontalPolicy( + QtWidgets.QSizePolicy.MinimumExpanding) self.setSizePolicy(size_policy) def set_invalid_empty_task(self, invalid=True): diff --git a/openpype/tools/pyblish_pype/view.py b/openpype/tools/pyblish_pype/view.py index 69dda6618d3..cc6604fc635 100644 --- a/openpype/tools/pyblish_pype/view.py +++ b/openpype/tools/pyblish_pype/view.py @@ -24,7 +24,7 @@ def __init__(self, parent=None): self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) self.setItemsExpandable(True) - self.setVerticalScrollMode(QtWidgets.QTreeView.ScrollPerPixel) + self.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) self.setHeaderHidden(True) self.setRootIsDecorated(False) self.setIndentation(0) @@ -248,7 +248,7 @@ def __init__(self, parent=None): self.setAutoScroll(False) self.setHeaderHidden(True) self.setIndentation(0) - self.setVerticalScrollMode(QtWidgets.QTreeView.ScrollPerPixel) + self.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) self.verticalScrollBar().setSingleStep(10) self.setRootIsDecorated(False) diff --git a/openpype/tools/sceneinventory/view.py b/openpype/tools/sceneinventory/view.py index ba3aa069f23..183bf2362bb 100644 --- a/openpype/tools/sceneinventory/view.py +++ b/openpype/tools/sceneinventory/view.py @@ -546,9 +546,9 @@ def _select_items_by_action(self, object_names, options=None): selection_model = self.selectionModel() select_mode = { - "select": selection_model.Select, - "deselect": selection_model.Deselect, - "toggle": selection_model.Toggle, + "select": QtCore.QItemSelectionModel.Select, + "deselect": QtCore.QItemSelectionModel.Deselect, + "toggle": QtCore.QItemSelectionModel.Toggle, }[options.get("mode", "select")] for index in iter_model_rows(model, 0): @@ -559,7 +559,7 @@ def _select_items_by_action(self, object_names, options=None): name = item.get("objectName") if name in object_names: self.scrollTo(index) # Ensure item is visible - flags = select_mode | selection_model.Rows + flags = select_mode | QtCore.QItemSelectionModel.Rows selection_model.select(index, flags) object_names.remove(name) diff --git a/openpype/tools/settings/settings/breadcrumbs_widget.py b/openpype/tools/settings/settings/breadcrumbs_widget.py index 2676d2f52db..c93e2108555 100644 --- a/openpype/tools/settings/settings/breadcrumbs_widget.py +++ b/openpype/tools/settings/settings/breadcrumbs_widget.py @@ -339,7 +339,7 @@ def __init__(self, path, model, parent): # fixed size breadcrumbs self.setMinimumSize(self.minimumSizeHint()) size_policy = self.sizePolicy() - size_policy.setVerticalPolicy(size_policy.Minimum) + size_policy.setVerticalPolicy(QtWidgets.QSizePolicy.Minimum) self.setSizePolicy(size_policy) menu.triggered.connect(self._on_menu_click) @@ -369,7 +369,7 @@ def __init__(self, parent=None): super(BreadcrumbsAddressBar, self).__init__(parent) self.setAutoFillBackground(True) - self.setFrameShape(self.StyledPanel) + self.setFrameShape(QtWidgets.QFrame.StyledPanel) # Edit presented path textually proxy_model = BreadcrumbsProxy() diff --git a/openpype/tools/standalonepublish/widgets/widget_asset.py b/openpype/tools/standalonepublish/widgets/widget_asset.py index 01f49b79ec3..5da25a0c3e3 100644 --- a/openpype/tools/standalonepublish/widgets/widget_asset.py +++ b/openpype/tools/standalonepublish/widgets/widget_asset.py @@ -86,7 +86,10 @@ def preserve_selection(tree_view, model = tree_view.model() selection_model = tree_view.selectionModel() - flags = selection_model.Select | selection_model.Rows + flags = ( + QtCore.QItemSelectionModel.Select + | QtCore.QItemSelectionModel.Rows + ) if current_index: current_index_value = tree_view.currentIndex().data(role) @@ -410,7 +413,10 @@ def select_assets(self, assets, expand=True, key="name"): selection_model.clearSelection() # Select - mode = selection_model.Select | selection_model.Rows + mode = ( + QtCore.QItemSelectionModel.Select + | QtCore.QItemSelectionModel.Rows + ) for index in _iter_model_rows( self.proxy, column=0, include_root=False ): diff --git a/openpype/tools/utils/assets_widget.py b/openpype/tools/utils/assets_widget.py index c92e68aa979..f33a412a7bb 100644 --- a/openpype/tools/utils/assets_widget.py +++ b/openpype/tools/utils/assets_widget.py @@ -60,7 +60,7 @@ def activate_flick_charm(self): self._flick_charm_activated = True self._before_flick_scroll_mode = self.verticalScrollMode() self._flick_charm.activateOn(self) - self.setVerticalScrollMode(self.ScrollPerPixel) + self.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) def deactivate_flick_charm(self): if not self._flick_charm_activated: @@ -623,7 +623,8 @@ def __init__(self, dbcon, parent=None): filter_input, ): size_policy = widget.sizePolicy() - size_policy.setVerticalPolicy(size_policy.MinimumExpanding) + size_policy.setVerticalPolicy( + QtWidgets.QSizePolicy.MinimumExpanding) widget.setSizePolicy(size_policy) # Layout @@ -778,7 +779,10 @@ def _select_indexes(self, indexes): selection_model = self._view.selectionModel() selection_model.clearSelection() - mode = selection_model.Select | selection_model.Rows + mode = ( + QtCore.QItemSelectionModel.Select + | QtCore.QItemSelectionModel.Rows + ) for index in valid_indexes: self._view.expand(self._proxy.parent(index)) selection_model.select(index, mode) diff --git a/openpype/tools/utils/lib.py b/openpype/tools/utils/lib.py index 403811699d6..ae9c5bc96c5 100644 --- a/openpype/tools/utils/lib.py +++ b/openpype/tools/utils/lib.py @@ -79,11 +79,15 @@ def paint_image_with_color(image, color): pixmap.fill(QtCore.Qt.transparent) painter = QtGui.QPainter(pixmap) - painter.setRenderHints( - painter.Antialiasing - | painter.SmoothPixmapTransform - | painter.HighQualityAntialiasing + render_hints = ( + QtGui.QPainter.Antialiasing + | QtGui.QPainter.SmoothPixmapTransform ) + # Deprecated since 5.14 + if hasattr(QtGui.QPainter, "HighQualityAntialiasing"): + render_hints |= QtGui.QPainter.HighQualityAntialiasing + painter.setRenderHints(render_hints) + painter.setClipRegion(alpha_region) painter.setPen(QtCore.Qt.NoPen) painter.setBrush(color) @@ -329,7 +333,10 @@ def preserve_selection(tree_view, column=0, role=None, current_index=True): role = QtCore.Qt.DisplayRole model = tree_view.model() selection_model = tree_view.selectionModel() - flags = selection_model.Select | selection_model.Rows + flags = ( + QtCore.QItemSelectionModel.Select + | QtCore.QItemSelectionModel.Rows + ) if current_index: current_index_value = tree_view.currentIndex().data(role) diff --git a/openpype/tools/utils/tasks_widget.py b/openpype/tools/utils/tasks_widget.py index 0605fd77433..b0ddedcb6e1 100644 --- a/openpype/tools/utils/tasks_widget.py +++ b/openpype/tools/utils/tasks_widget.py @@ -257,7 +257,10 @@ def select_task_name(self, task_name): selection_model.clearSelection() # Select the task - mode = selection_model.Select | selection_model.Rows + mode = ( + QtCore.QItemSelectionModel.Select + | QtCore.QItemSelectionModel.Rows + ) for row in range(task_view_model.rowCount()): index = task_view_model.index(row, 0) name = index.data(TASK_NAME_ROLE) From 7cd57e051a93b74af4b1e1b49085299a2f2e10a1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 15:19:57 +0100 Subject: [PATCH 21/42] support new method for regex filtering --- openpype/tools/loader/widgets.py | 11 +++++++++-- openpype/tools/sceneinventory/window.py | 5 ++++- openpype/tools/settings/settings/search_dialog.py | 5 ++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index c2c6c5dfcd3..8d58e822307 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -264,8 +264,8 @@ def __init__( group_checkbox.stateChanged.connect(self.set_grouping) - subset_filter.textChanged.connect(proxy.setFilterRegExp) - subset_filter.textChanged.connect(view.expandAll) + subset_filter.textChanged.connect(self._subset_changed) + model.refreshed.connect(self.refreshed) self.proxy = proxy @@ -293,6 +293,13 @@ def set_grouping(self, state): current_index=False): self.model.set_grouping(state) + def _subset_changed(self, text): + if hasattr(self.proxy, "setFilterRegularExpression"): + self.proxy.setFilterRegularExpression(text) + else: + self.proxy.setFilterRegExp(text) + self.view.expandAll() + def set_loading_state(self, loading, empty): view = self.view diff --git a/openpype/tools/sceneinventory/window.py b/openpype/tools/sceneinventory/window.py index 7b305e8e8f1..8a6e43f796b 100644 --- a/openpype/tools/sceneinventory/window.py +++ b/openpype/tools/sceneinventory/window.py @@ -160,7 +160,10 @@ def _on_hierarchy_view_change(self, enabled): self._model.set_hierarchy_view(enabled) def _on_text_filter_change(self, text_filter): - self._proxy.setFilterRegExp(text_filter) + if hasattr(self._proxy, "setFilterRegularExpression"): + self._proxy.setFilterRegularExpression(text_filter) + else: + self._proxy.setFilterRegExp(text_filter) def _on_outdated_state_change(self): self._proxy.set_filter_outdated( diff --git a/openpype/tools/settings/settings/search_dialog.py b/openpype/tools/settings/settings/search_dialog.py index 2860e7c943a..71d258febea 100644 --- a/openpype/tools/settings/settings/search_dialog.py +++ b/openpype/tools/settings/settings/search_dialog.py @@ -106,7 +106,10 @@ def _on_filter_changed(self, txt): def _on_filter_timer(self): text = self._filter_edit.text() - self._proxy.setFilterRegExp(text) + if hasattr(self._proxy, "setFilterRegularExpression"): + self._proxy.setFilterRegularExpression(text) + else: + self._proxy.setFilterRegExp(text) # WARNING This expanding and resizing is relatively slow. self._view.expandAll() From c849c83da49da705748ba58d2b9f7718abba7785 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 15:20:21 +0100 Subject: [PATCH 22/42] added pyside6 resources --- openpype/style/pyside6_resources.py | 1520 +++++++++++++++++++++++++++ openpype/style/qrc_resources.py | 4 +- 2 files changed, 1523 insertions(+), 1 deletion(-) create mode 100644 openpype/style/pyside6_resources.py diff --git a/openpype/style/pyside6_resources.py b/openpype/style/pyside6_resources.py new file mode 100644 index 00000000000..c7de95d14f3 --- /dev/null +++ b/openpype/style/pyside6_resources.py @@ -0,0 +1,1520 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 6.4.1 +# WARNING! All changes made in this file will be lost! + +from PySide6 import QtCore + +qt_resource_data = b"\ +\x00\x00\x00\xa6\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1f \xb9\ +\x8dw\xe9\x00\x00\x00*IDAT\x08\xd7c`\xc0\ +\x06\xe6|```B0\xa1\x1c\x08\x93\x81\x81\x09\xc1\ +d``b`H\x11@\xe2 s\x19\x90\x8d@\x02\ +\x00#\xed\x08\xafd\x9f\x0f\x15\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ +\x00\x00\x04\x12\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\xc4IDATh\x81\xed\ +\x9a_\x88\x94U\x18\xc6\x7f3;\x1a\x0b\x19\x15f\x17\ +\xca\x03IPM\x09J7Q^D)&f\x05[\ +\xb9\xd2\x82\xb1P\x17\x91$t\x11\x08z\xa1D\x17]\ +T\x94\x04\xd6E\xe1\xa2\x15L\xb1\x18\x99\xfd%\xd8\x08\ +\x82nj]\xa4\x22\xe2\x81\xa8\x96\xd5(\xe8\x9f\xae\xd5\ +\xc5\xf9\xb6\xc6\xd9\xf9\xbesf\xc6vf\xc0\xdf\xdd\x9c\ +\xef=\xefy\x9fs\xe6\x9c\xf3~\xdf9%2Fj\ +SK\x81\xdd\xc0Z\xe0:`\x11\xbd\xc5i`\x12\x98\ +\x00\xf6\x8c\x0dUg\x00J\x00#\xb5\xa9[\x80C\xc0\ +\xb2\xae\x85\xd7\x1a\xd3\xc0\xd6\xb1\xa1\xea\x07\xa5\xac\xe7\x8f\ +\xd1?\xc1\xcf1\x0d\x5c[&\xfcm\xfa-x\x081\ +\xef\xaa\x10\xfe\xf3\x8d\x9cY\xe0`R\x19h\xf8\xbd\xb6\ +B\x98\xb0\xf5\x9c\x19\x1b\xaaV\x16(\xa0\x96\x18\xa9M\ +\xcdr\xb6\x88Uezo\xb5i\x85E\xe5nG\xd0\ +)\xe7\x05t\x9b\xf3\x02\xfe\x0fl\xdfc\xfb\x90\xed\xf5\ +1\xdb\x9e\x13`\xfb\x11\xe05`\x188j{\x9f\xed\ +\xdc\x95\xb2\xa7\x04\xd8\x1e\x06\x9e\xaa+*\x01\x0f\x01/\ +\xe4\xd5\xe9\x19\x01\xb6\xd7\x01/\x93%\x98\x0dl\xb3\xfd\ +h\xb3z=!\xc0\xf6\xf5\xc0\xeb\xc0\xe2\x02\xb3\x8d\xcd\ +\x0a\xbb.\xc0\xf6\x95\xc0[\xc0\x92\x88\xe9\x8b\xcd\x0a\xbb\ +*\xc0\xf6\xe5\xc0Q\xe2\xd9\xf0\x93\x92^i\xf6\xa0k\ +\x02l/\x01\x8e\x00+#\xa6\x07\x80\xc7\xf2\x1evE\ +\x80\xed\xc5\xc0\x1b\xc0\x9a\x88\xe9\xdb\xc0\xa8\xa4\xbf\xf3\x0c\ +\x16\x5c\x80\xed2\xa1Wo\x8d\x98~\x0a\xdc-i\xb6\ +\xc8\xa8\x1b#\xf04po\xc4\xe6K`\x93\xa4_c\ +\xce\x92\x04\xd8.e=\xd7\x11\xb6w\x02\xdb#f\xdf\ +\x03\x1b$\xcd\xa4\xf8,\x0c*\x0b|\x07\xf0;0i\ +{UR\xa4\xcd}\x8d\x02\x8fG\xcc~\x06n\x93\xf4\ +m\xaa\xdf\x5c\x01Y\xfe1N\xd8\xda/\x00\xae\x01\xde\ +\xb3}U\xaa\xf3:_\x9b\x81\xfd\x11\xb3?\x81;%\ +}\xde\x8a\xef\xa2\x11x\x0e\xd8\xdcP\xb6\x0cx\xdf\xf6\ +\x15\xa9\x0d\xd8\xbe\x11x\x95\xf9/\xe4\xf5\xfc\x05\xdc'\ +\xe9\xa3T\xbfs4\x15\x90\xf5\xd8\x839u\x96\x13F\ +by\xcc\xb9\xed*p\x18\x18\x8c\x98>,\xa9\x16\xf3\ +\xd7\x8c\xbc\x11\xb84Ro%A\xc4ey\x06\xb6W\ +\x10v\xd9\x98\xaf\xbd\x92\x9e\x8f\xd8\xe4\x92'\xe0 a\ +\x1d.\xe2j\xe0\x1d\xdb\x177>\xb0}\x09!\xf8\x15\ +\x11\x1f\xfb%\xed\x8eFY@S\x01\x92N\x13\xb2\xbf\ +/\x22\xf5W\x03Gl_8W`{\x90\xf0\xb7\xa9\ +F\xea\x8e\x13r\xfd\x8e\xc8\x9d\xc4\x92N\x02\xeb\x81\xaf\ +\x22>n\x00\x0e\xdb\x1e\xb4=@\x98\xb07E\xeaL\ +\x00\xc3\x92:\xfe\x02X\xb8\x0fH\xfa\x11X\x078\xe2\ +\xe7f\xa0FX*\x1bW\xaeF&\x81;$\xfd\x91\ +\x18c!\xd1\xddU\x92\x09y\xcb\x0f\x11\xd3\x8d\xc0h\ +\xc4\xc6\x84\x8d\xea\xa7\xb4\xf0\xe2$\xa5\x07\x92\xbe&\x8c\ +\xc4\x89\x0e\xda:IH\x11\xbe\xeb\xc0\xc7<\x92\xf3\x1b\ +I\xc7\x80\x0d\xc0/m\xb4\xf3\x1bp\xbb\xa4\xe3m\xd4\ +-\xa4\xa5\x04M\xd2g\xc0\xa6,\xa0Tf\x81-\x92\ +>i\xa5\xadTZ\xce0%M\x00w\x11r\x97\x14\ +\x1e\x90\xf4f\xab\xed\xa4\xd2V\x8a,\xe9]`\x0b\xa1\ +w\x8b\xd8)\xe9\xa5v\xdaH\xa5\xed\x1c_\xd28\xb0\ +\x8d\x90\x885\xe3YIO\xb4\xeb?\x95\x8e^R$\ +\x1d\x04\xeeg\xfe\x9c\xd8\x07\xec\xe8\xc4w*\x1d\x1f%\ +I:`\xfbc\xc2\x06v\x11\xf0a6O\x16\x84s\ +r\x16&\xe9\x1b\xe0\x99s\xe1\xabU\xca\x84\x13\xf0~\ +\xe5T\x85\x90\x9b\xd4\x7f\x9f\x19\xc8N\x03{\x91\xc6\xb7\ +\xba\xc9\x0a!3l\xfc\xc0T\xf4\xfa\xd7KL\x94\x81\ +=\x84c\xfb~c\x1a\xd8[\xcen}l\xa5\xbfD\ +\xcc]\xf6\x98\xf9\xf70!\xbb\xf4\xb1\x8b\xff\xae\xdb\x14\ +}\xab\xef\x06\xa78\xfb\xba\xcd\x09\x80\x7f\x00\xc4\x1e\x10\ +)3[\x85\xf7\x00\x00\x00\x00IEND\xaeB`\ +\x82\ +\x00\x00\x01\xef\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\xa1IDATh\x81\xed\ +\x9a\xbfN\xc2P\x14\x87\xbf\x96\xe2\xa4\x9bq\xbc\x8b\x1b\ +\xea\xc0\xe2D\x1c\x8c\x83\x83\xd1\x81\x89\x84\xd1\x17\xf0\x01\ +p\xc0\x07\xf0\x05\x1cI\x9c\xba\xa8#q0<\x02v\ +\x92\xe5\x8e\x04'\xe3\xc2\x9f\xc4\xa1m\x04B\x8b\x95\xc2\ +\xa1\xe4~[{\xee\xf0\xfb\x9a{o\x9a\x9cc\x11P\ +u\xbd]\xe0\x16(\x01\x87@\x9e\xf5b\x00\xb4\x81\x16\ +Po\x94\x0b=\x00\x0b\xa0\xeaz\xa7\xc0#\xb0'\x16\ +/\x19]\xa0\xd2(\x17^\xad\xe0\xcb\xbf\x93\x9d\xf0!\ +]\xe0\xc0\xc6\xdf6Y\x0b\x0f~\xe6\x9a\x83\xbf\xe7\xa7\ +\x19\xad8\xcc_\xc9M=\x97\x1c\xfc\x03;\xce\xa8Q\ +.8+\x0a\x94\x88\xaa\xeb\x0d\x99\x948\xb2Y\xbf\xdb\ +&\x09y[:\xc1\xa2\x18\x01i\x8c\x804F@\x1a\ +# \x8d\x11\x90\xc6\x08H3\xf7\xb7Yk}\x06\x1c\ +\x03\xdb\xcb\x8f3\xc1\x10\xf0\x80g\xa5\xd4w\xd4\xa2H\ +\x01\xad\xb5\x03\xb8\xc0e\xfa\xd9\x12\xd1\xd1Z\x9f+\xa5\ +>f\x15\xe3\xb6\xd0\x0d\xf2\xe1\x01\xf6\x81\x87\xa8b\x9c\ +\xc0E\xfaY\xfe\xcd\x89\xd6zgV!\xf3\x878N\ +\xe0ee)\xe6\xf3\xa6\x94\xfa\x9aU\x88\x13\xb8\x07\x9e\ +\x96\x93'\x11\x1d\xe0:\xaa\x18y\x0b)\xa5\x86\xc0U\ +f\xaf\xd1\x10\xa5T\x13h\xa6\x18,U6\xfa\x10g\ +\x02# \x8d\x11\x90\xc6\x08Hc\x04\xa41\x02\xd2l\ +\x84\xc0@:\xc4\x02\xf4\x1d\xfc\xf6}q\xece.\xe8\ +\x06\xae#\xd3m\xd6\xb6\x83?{P\x9c\xb3p]i\ +\xd9@\x1d\xbfm\x9f5\xba\xc0\x9d\x1dL}T\xc8\x96\ +D8\xec\xd1\xb3\xc27\xc1\xd0G\x8d\xdfq\x9b-\xa1\ +pQ\xf4\x99\x1c\xb7\xf9\x04\xf8\x01o\xedXc-\xfd\ +\xb2Y\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\xa6\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15;\xdc\ +;\x0c\x9b\x00\x00\x00*IDAT\x08\xd7c`\xc0\ +\x00\x8c\x0c\x0cs> \x0b\xa4\x08020 \x0b\xa6\ +\x08000B\x98\x10\xc1\x14\x01\x14\x13P\xb5\xa3\x01\ +\x00\xc6\xb9\x07\x90]f\x1f\x83\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ +\x00\x00\x00\xa5\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\ +\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\ +\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\ +200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\ +\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\ +\xaeB`\x82\ +\x00\x00\x00\xa5\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\ +\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\ +\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\ +200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\ +\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\ +\xaeB`\x82\ +\x00\x00\x00\xa5\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\ +\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\ +\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\ +200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\ +\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\ +\xaeB`\x82\ +\x00\x00\x00\xa0\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1c\x1f$\ +\xc6\x09\x17\x00\x00\x00$IDAT\x08\xd7c`@\ +\x05\xff\xcf\xc3XL\xc8\x5c&dY&d\xc5p\x0e\ +\xa3!\x9c\xc3h\x88a\x1a\x0a\x00\x00m\x84\x09u7\ +\x9e\xd9#\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\xa6\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15;\xdc\ +;\x0c\x9b\x00\x00\x00*IDAT\x08\xd7c`\xc0\ +\x00\x8c\x0c\x0cs> \x0b\xa4\x08020 \x0b\xa6\ +\x08000B\x98\x10\xc1\x14\x01\x14\x13P\xb5\xa3\x01\ +\x00\xc6\xb9\x07\x90]f\x1f\x83\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ +\x00\x00\x01i\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x1bIDATh\x81\xed\ +\xda\xb1m\xc2@\x14\x87\xf1\xcf\xc7\x91\x09P\x86pB\ +AO\xc5\x0a\xae\x90\xbc\x0a)\xc8*\x96Ry\x05*\ +F \x1e\xc2\x82\x05H\x90R\xdcY\x01KQbE\ +\xe2\xef\x93\xde\xaf\xb3E\xf1>\xcb\xa6\xb9\x97\x11\x95u\ +3\x03^\x80%\xf0\x0cL\x19\x97\x0f\xe0\x00\xec\x81m\ +U\xe4G\x80\x0c\xa0\xac\x9b\x15\xf0\x06<\xca\xc6\x1b\xa6\ +\x05\xd6U\x91\xef\xb2\xf8\xe4\xdfIg\xf8N\x0b<9\ +\xc2k\x93\xda\xf0\x10f\xdex\xc2;\xdfw\xb9\xf30\ +\x7f5\xe9]/=\xe1\x83\xbdv\xa9\x8a\xdc\xdfi\xa0\ +A\xca\xba\xf9\xe46b\xee\x18\xdf\xbf\xcd\x10S\xa7\x9e\ +\xe0\xbf,@\xcd\x02\xd4,@\xcd\x02\xd4,@\xcd\x02\ +\xd4,@\xcd\x02\xd4,@\xcd\x02\xd4,@\xcd\x02\xd4\ +,@\xcd\x02\xd4,@\xcd\x02\xd4,@\xcd\x11N\xc0\ +Su\xf6\x84\xe3\xfb\xc5\xd5\xcdI<\x0d\x1c\xa3\xfe1\ +\xeb\xc1\x13v\x0f\x16\xbf\xfcp\xac\xf6\x0e\xd8\x12\x8e\xed\ +S\xd3\x02\xaf.n}\xacI+\xa2[\xf68f\xdd\ +\x9d\xb8\xf4\xb1\xe1{\xdd\xe6A4\xdcO\xce\xdc\xae\xdb\ +\x9c\x00\xbe\x00\x9f\xf64>6O7\x81\x00\x00\x00\x00\ +IEND\xaeB`\x82\ +\x00\x00\x07\x06\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x0a\x00\x00\x00\x07\x08\x06\x00\x00\x001\xac\xdcc\ +\x00\x00\x04\xb0iTXtXML:com.\ +adobe.xmp\x00\x00\x00\x00\x00\x0a\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a\x0a\x85\x9d\x9f\x08\x00\x00\x01\x83\ +iCCPsRGB IEC6196\ +6-2.1\x00\x00(\x91u\x91\xcf+DQ\x14\ +\xc7?fh\xfc\x18\x8dba1e\x12\x16B\x83\x12\ +\x1b\x8b\x99\x18\x0a\x8b\x99Q~mf\x9ey3j\xde\ +x\xbd7\xd2d\xabl\xa7(\xb1\xf1k\xc1_\xc0V\ +Y+E\xa4d\xa7\xac\x89\x0dz\xce\x9bQ#\x99s\ +;\xf7|\xee\xf7\xdes\xba\xf7\x5cpD\xd3\x8afV\ +\xfaA\xcbd\x8dp(\xe0\x9b\x99\x9d\xf3\xb9\x9e\xa8\xa2\ +\x85\x1a:\xf1\xc6\x14S\x9f\x8c\x8cF)k\xef\xb7T\ +\xd8\xf1\xba\xdb\xaeU\xfe\xdc\xbfV\xb7\x980\x15\xa8\xa8\ +\x16\x1eVt#+<&<\xb1\x9a\xd5m\xde\x12n\ +RR\xb1E\xe1\x13\xe1.C.(|c\xeb\xf1\x22\ +?\xdb\x9c,\xf2\xa7\xcdF4\x1c\x04G\x83\xb0/\xf9\ +\x8b\xe3\xbfXI\x19\x9a\xb0\xbc\x9c6-\xbd\xa2\xfc\xdc\ +\xc7~\x89;\x91\x99\x8eHl\x15\xf7b\x12&D\x00\ +\x1f\xe3\x8c\x10d\x80^\x86d\x1e\xa0\x9b>zdE\ +\x99|\x7f!\x7f\x8ae\xc9Ud\xd6\xc9a\xb0D\x92\ +\x14Y\xbaD]\x91\xea\x09\x89\xaa\xe8\x09\x19irv\ +\xff\xff\xf6\xd5T\xfb\xfb\x8a\xd5\xdd\x01\xa8z\xb4\xac\xd7\ +vpm\xc2W\xde\xb2>\x0e,\xeb\xeb\x10\x9c\x0fp\ +\x9e)\xe5/\xef\xc3\xe0\x9b\xe8\xf9\x92\xd6\xb6\x07\x9eu\ +8\xbd(i\xf1m8\xdb\x80\xe6{=f\xc4\x0a\x92\ +S\xdc\xa1\xaa\xf0r\x0c\xf5\xb3\xd0x\x05\xb5\xf3\xc5\x9e\ +\xfd\xecst\x07\xd15\xf9\xaaK\xd8\xd9\x85\x0e9\xef\ +Y\xf8\x06\x8e\xfdg\xf8\xfd\x8a\x18\x97\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00mIDAT\x18\x95u\xcf\xc1\x09\xc2P\ +\x10\x84\xe1\xd7\x85\x07\x9b\xd0C@\xd2\x82x\x14{0\ +W!\x8d\x84`?bKzH\xcc\x97\x83\xfb0\x04\ +\xdf\x9c\x86\x7fg\x99\xdd\x84\x0d\xaaT\x10jl\x13\x1e\ +\xbe\xba\xfe\x0951{\xe6\x8d\x0f&\x1c\x17\xa1S\xb0\ +\x11\x87\x0c/\x01\x07\xec\xb0\x0f?\xe1\xbc\xaei\xa3\xe6\ +\x85w\xf8[\xe9\xf0\xbb\x9f\xfa\xd2\x839\xdc\xa3[\xf3\ +\x19.\xa8\x89\xb50\xf7C\xa0\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ +\x00\x00\x00\xa6\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1d\x00\xb0\ +\xd55\xa3\x00\x00\x00*IDAT\x08\xd7c`\xc0\ +\x06\xfe\x9fg``B0\xa1\x1c\x08\x93\x81\x81\x09\xc1\ +d``b``4D\xe2 s\x19\x90\x8d@\x02\ +\x00d@\x09u\x86\xb3\xad\x9c\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ +\x00\x00\x07\xad\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x07\x00\x00\x00\x0a\x08\x06\x00\x00\x00x\xccD\x0d\ +\x00\x00\x05RiTXtXML:com.\ +adobe.xmp\x00\x00\x00\x00\x00\x0a\x0a \x0a \x0a \x0a \ +\x0a branch_close<\ +/rdf:li>\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a <\ +/rdf:RDF>\x0a\x0a$\xe15\x97\x00\x00\ +\x01\x83iCCPsRGB IEC61\ +966-2.1\x00\x00(\x91u\x91\xcf+D\ +Q\x14\xc7?fh\xfc\x18\x8dba1e\x12\x16B\ +\x83\x12\x1b\x8b\x99\x18\x0a\x8b\x99Q~mf\x9ey3\ +j\xdex\xbd7\xd2d\xabl\xa7(\xb1\xf1k\xc1_\ +\xc0VY+E\xa4d\xa7\xac\x89\x0dz\xce\x9bQ#\ +\x99s;\xf7|\xee\xf7\xdes\xba\xf7\x5cpD\xd3\x8a\ +fV\xfaA\xcbd\x8dp(\xe0\x9b\x99\x9d\xf3\xb9\x9e\ +\xa8\xa2\x85\x1a:\xf1\xc6\x14S\x9f\x8c\x8cF)k\xef\ +\xb7T\xd8\xf1\xba\xdb\xaeU\xfe\xdc\xbfV\xb7\x980\x15\ +\xa8\xa8\x16\x1eVt#+<&<\xb1\x9a\xd5m\xde\ +\x12nRR\xb1E\xe1\x13\xe1.C.(|c\xeb\ +\xf1\x22?\xdb\x9c,\xf2\xa7\xcdF4\x1c\x04G\x83\xb0\ +/\xf9\x8b\xe3\xbfXI\x19\x9a\xb0\xbc\x9c6-\xbd\xa2\ +\xfc\xdc\xc7~\x89;\x91\x99\x8eHl\x15\xf7b\x12&\ +D\x00\x1f\xe3\x8c\x10d\x80^\x86d\x1e\xa0\x9b>z\ +dE\x99|\x7f!\x7f\x8ae\xc9Ud\xd6\xc9a\xb0\ +D\x92\x14Y\xbaD]\x91\xea\x09\x89\xaa\xe8\x09\x19i\ +rv\xff\xff\xf6\xd5T\xfb\xfb\x8a\xd5\xdd\x01\xa8z\xb4\ +\xac\xd7vpm\xc2W\xde\xb2>\x0e,\xeb\xeb\x10\x9c\ +\x0fp\x9e)\xe5/\xef\xc3\xe0\x9b\xe8\xf9\x92\xd6\xb6\x07\ +\x9eu8\xbd(i\xf1m8\xdb\x80\xe6{=f\xc4\ +\x0a\x92S\xdc\xa1\xaa\xf0r\x0c\xf5\xb3\xd0x\x05\xb5\xf3\ +\xc5\x9e\xfd\xecst\x07\xd15\xf9\xaaK\xd8\xd9\x85\x0e\ +9\xefY\xf8\x06\x8e\xfdg\xf8\xfd\x8a\x18\x97\x00\x00\x00\ +\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\ +\x9c\x18\x00\x00\x00rIDAT\x18\x95m\xcf1\x0a\ +\xc2P\x14D\xd1\xe8\x02\xb4W\x08\xd6Ia\x99JC\ +t\x15\x82\xabI6(\xee@\x04\xdb\xa8\x95Xx,\ +\xf2\x09\xe1\xf3\x07\xa6\x9a\xfb\xe0\xbe\x0c\x1b\xb4Xdq\ +p0\xe4\x82U\x0a8\xe3\x8b\x1b\x8a\x14p\xc4\x1b=\ +v)`\x8b\x07>\xa8\xe6\xd1\xfe\x0b\x9d\x85\x8eW\x0d\ +^x\xa2\x9e\x0e\xa7 tG9\x1d\xf6\xe1\x95+\xd6\ +\xb1D\x8e\x0e\xcbX\xf0\x0fR\x8ay\x18\xdc\xe2\x02p\ +\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\x9f\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x14\x1f\xf9\ +#\xd9\x0b\x00\x00\x00#IDAT\x08\xd7c`\xc0\ +\x0d\xe6|\x80\xb1\x18\x91\x05R\x04\xe0B\x08\x15)\x02\ +\x0c\x0c\x8c\xc8\x02\x08\x95h\x00\x00\xac\xac\x07\x90Ne\ +4\xac\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x070\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x0a\x00\x00\x00\x07\x08\x06\x00\x00\x001\xac\xdcc\ +\x00\x00\x04\xb0iTXtXML:com.\ +adobe.xmp\x00\x00\x00\x00\x00\x0a\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a\x0aH\x8b[^\x00\x00\x01\x83\ +iCCPsRGB IEC6196\ +6-2.1\x00\x00(\x91u\x91\xcf+DQ\x14\ +\xc7?fh\xfc\x18\x8dba1e\x12\x16B\x83\x12\ +\x1b\x8b\x99\x18\x0a\x8b\x99Q~mf\x9ey3j\xde\ +x\xbd7\xd2d\xabl\xa7(\xb1\xf1k\xc1_\xc0V\ +Y+E\xa4d\xa7\xac\x89\x0dz\xce\x9bQ#\x99s\ +;\xf7|\xee\xf7\xdes\xba\xf7\x5cpD\xd3\x8afV\ +\xfaA\xcbd\x8dp(\xe0\x9b\x99\x9d\xf3\xb9\x9e\xa8\xa2\ +\x85\x1a:\xf1\xc6\x14S\x9f\x8c\x8cF)k\xef\xb7T\ +\xd8\xf1\xba\xdb\xaeU\xfe\xdc\xbfV\xb7\x980\x15\xa8\xa8\ +\x16\x1eVt#+<&<\xb1\x9a\xd5m\xde\x12n\ +RR\xb1E\xe1\x13\xe1.C.(|c\xeb\xf1\x22\ +?\xdb\x9c,\xf2\xa7\xcdF4\x1c\x04G\x83\xb0/\xf9\ +\x8b\xe3\xbfXI\x19\x9a\xb0\xbc\x9c6-\xbd\xa2\xfc\xdc\ +\xc7~\x89;\x91\x99\x8eHl\x15\xf7b\x12&D\x00\ +\x1f\xe3\x8c\x10d\x80^\x86d\x1e\xa0\x9b>zdE\ +\x99|\x7f!\x7f\x8ae\xc9Ud\xd6\xc9a\xb0D\x92\ +\x14Y\xbaD]\x91\xea\x09\x89\xaa\xe8\x09\x19irv\ +\xff\xff\xf6\xd5T\xfb\xfb\x8a\xd5\xdd\x01\xa8z\xb4\xac\xd7\ +vpm\xc2W\xde\xb2>\x0e,\xeb\xeb\x10\x9c\x0fp\ +\x9e)\xe5/\xef\xc3\xe0\x9b\xe8\xf9\x92\xd6\xb6\x07\x9eu\ +8\xbd(i\xf1m8\xdb\x80\xe6{=f\xc4\x0a\x92\ +S\xdc\xa1\xaa\xf0r\x0c\xf5\xb3\xd0x\x05\xb5\xf3\xc5\x9e\ +\xfd\xecst\x07\xd15\xf9\xaaK\xd8\xd9\x85\x0e9\xef\ +Y\xf8\x06\x8e\xfdg\xf8\xfd\x8a\x18\x97\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x97IDAT\x18\x95m\xcf\xb1j\x02A\ +\x14\x85\xe1o\xb7\xb6\xd0'H=Vi\x03\xb1\xb4H\ +;l\xa5\xf19\xf6Y\x02VB\xbaa\x0a\x0b;\x1b\ +\x1bkA\x18\x02)m\xe3\xbe\x82\xcd\x06\x16\xd9\xdb\xdd\ +\x9f\xff\x5c\xee\xa9b*\x13Ls\x13nF&\xa6\xf2\ +\x82\xaeF\x8b\xdf\x98\xca\xfb\x88\xb4\xc0\x0f\xda\x1a[t\ +\xd8\xc7T\xc2@\x9ac\x8f?|U=|\xc5\x09w\ +\xbc\xa1\xc2\x193,r\x13.\xd5\xe0\xc2\x12\x07\x5cQ\ +#\xe0#7\xe1\xa8O\x0e\x7f\xda`\xd7\xaf\x9f\xb9\x09\ +\xdfc\x05\xff\xe5uLe\xf5\xcc\x1f\x0d3,\x83\xb6\ +\x06D\x83\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x03\xff\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\xb1IDATh\x81\xed\ +\x9aOh\x1eE\x18\xc6\x7f\x9b&\x85\x82\x15\x15\xabB\ +\xcb\x03\x06\x05\xa9\x0a\x8a\xb7R<\xd4\x96\xaa\xb5\xe0A\ +\xad\xc5C%\xa0\x07Q\xccM(\xb4\x07E\x80\xae9\x1f\xc0\xff\ +\x81\xed\xbbm\xbff{W\xca6\x0b!\x84BY\xa7\ +\xdb\xa8\xedG\x81#\xf9\xcf\x00\x1c\x05&%-\x94l\ +\xa3\xc35\x03\xb6\xef\x05\x9e\xe9)\xca\x80\x87\x80\x17\xab\ +\xda\x0c\xcd\x81e{'\xf0\x0aQt\x91\x03\xb6\xbf*\ +k7\x143`\xfb&\xe0M`}\x8d\xd9me\x85\ +\x9d\x07`\xfb*\xe0]`c\xc2\xf4\xa5\xb2\xc2N\x03\ +\xb0}9\xf0>\xe9l\xf8iI\xaf\x97Ut\x16\x80\ +\xed\x8d\xc0\x140\x9e0}\x15x\xac\xaa\xb2\x93\x00l\ +\xaf\x07\xde\x02nL\x98\xbe\x07LH*n\xf5K\xac\ +z\x00\xb6G\x88\xa3zK\xc2\xf4\x0b\xe0.I\x8bu\ +F]\xcc\xc0\x11\xe0\x9e\x84\xcd\xb7\xc0\x1eI\xbf\xa5\x9c\ +5\x0a\xc0v\x96\x8f\xdc@\xd8>\x08<\x920\xfb\x11\ +\xd8-i.a\x07$\x02\xc8\x85O\x02\x7f\x003\xb6\ +\xafo\xa4\xb4\xdc\xd7\x04\xf0d\xc2\xec\x17\xe0VI\xdf\ +7\xf5[\x99\x0b\xd9\x1e\x03\x8e\x03{{\xeaf\x81\x9b\ +%}\xd3\xb4\x03\x00\xdb{\x89\x8b\xb6x\xa7\xed\xe5,\ +q\xe4?\xab2\xe87\x17z\x8e\xe5\xe2!\xee\xd7\x1f\ +\xdb\xbe\xb2Vq\x0f\xb6\xb7\x01o\x14;.\xf0\x17p\ +_\x9d\xf8*J\x03\xc8G\xec\xc1\x8a6\x9b\x81\x8fl\ +oN9\xb7\xbd\x15x\x1b\xd8\x900}X\xd2\xf1\x94\ +\xbf2\xaaf\xe0\x92D\xbbqb\x10\x9b\xaa\x0clo\ +!\x9e\xb2)_OH:\x9a\xb0\xa9\xa4*\x80c\xc4\ +}\xb8\x8ek\x80\x0fl_T\xac\xb0}1Q\xfc\x96\ +\x84\x8f\x17$\x1dN\xaa\xac\xa14\x00I\x0b\xc4\xec\xaf\ +4\x85\xed\xe1\x06`\xca\xf6\x05\xff\x14\xd8\xde@|l\ +\xb6&\xda\x9e \xe6\xfa\x03Q{#\xcb\x93\xad\x93\xc0\ +\xd5\x09?\x9f\x02\xb7\x03\xf3\xc4\xdd\xa6\xb8\xf8\x8bL\x03\ +\xbb$\xfd\xd9\x8f\xd8\xb2](y\xa5\xb4-b\x10J\ +\xf8\x9f\x22\x1eB\x13\x09\xbb\x19\xe2V\xfcs#\xd5=\ +\xb4\x0a\x00\x96r\xf6\x93\xc0\x15\xfdvZ\xc0\xc06I\ +?\xb4i\xdc\xfaN,\xe9;`'p\xa6M\xc79\ +?\x11\x0f\xaaV\xe2\xabh\x9c\xdfH:\x05\xec\x06~\ +m\xd1\xcf\xef\xc0\x1d\x92\xben\xd1\xb6\x96\xbe\x124I\ +_\x02{rAMY\x04\xf6I\xfa\xbc\x9f\xbe\x9a\xd2\ +w\x86)i\x1a\xb8\x93\x98\xbb4\xe1\x01I\xef\xf4\xdb\ +OSZ\xa5\xc8\x92>\x04\xf6\x11G\xb7\x8e\x83\x92^\ +n\xd3GSZ\xe7\xf8\x92N\x00\x07\x88\x89X\x19\xcf\ +Jz\xaa\xad\xff\xa6\x0ctI\x91t\x0c\xb8\x9f\xff\xae\ +\x89\xe7\x81\xc9A|7eE\xde\x8d\xda\x1e'\x9e\xbe\ +\x17\x02\x9f\xe4\xebd\xc5i}\x90\x0d\x0bU\x07\xd9B\ +7rV\x84\xf9Qbn\xd2\xfb~f]\x1e\xe90\ +R\xbc\xd5\xcd\x8c\x123\xc3\xe2\x0b\xa6\xba\xeb\xdf01\ +\xbd\xf6?5\xc8\xbf\xfa\xd8\x9f\x17\xac\x15f\x81\xfdY\ +\x96\xcd-\xfd\x99\x90\xcf\xc4!\xfe\xfd\xdc\xa6\xee]}\ +\x17\xcc\xb3\xfcs\x9b3\x00\x7f\x03\xd9\x1a\xfb\xdb\xbb\xa7\ +\x8f\x07\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x01[\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x0dIDATh\x81\xed\ +\xda\xb1m\x02A\x10F\xe1w\xc7\xe2\x0a,\x87\xd3\x00\ +8 'r\x17\x14\x83\x037\xe3.\x1cQ\x0240\ +!\xc2\x0d`\x90\x1c\xec\x9e\x0c'Y\xf6\x09\x89\xffV\ +\x9a/cE0\x0f\x0e\x92\x9d\x86\xc2\xdd\x1f\x81W`\ +\x09\xcc\x81)\xe3\xf2\x05l\x81\x0d\xf0ff\x07\x80\x06\ +\xc0\xdd_\x80w\xe0I6\xde0{`ef\x1fM\ +\xf9\xe4w\xd43|g\x0f\xccZ\xf2cS\xdb\xf0\x90\ +g^'\xf23\xdfw\xbe\xf30\xff5\xe9\xbd^&\ +\xf2\x0f\xf6\xd2\xd9\xcc\xd2\x9d\x06\x1a\xc4\xddO\x5cG<\ +\xb7\x8c\xef\xdff\x88i\xab\x9e\xe0V\x11\xa0\x16\x01j\ +\x11\xa0\x16\x01j\x11\xa0\x16\x01j\x11\xa0\x16\x01j\x11\ +\xa0\x16\x01j\x11\xa0\x16\x01j\x11\xa0\x16\x01j\x11\xa0\ +\x16\x01j\x11\xa0\xd6\x92o\xc0kuL\xe4\xeb\xfb\xc5\ +\xc5\xe1\xa4\xdc\x06\x8eQ\xff\x9au\x9b\xc8\xbb\x07\x8b?\ +\xde8V\x9b\xfaW\x0d\xca\xd6\xc7\xaa\x1c\xd4\xa2[\xf6\ +84\xddI\xf9&\xd6\xfc\xac\xdb<\x88\x86\xfb\xcd\x91\ +\xebu\x9bO\x80oV\x016\x1ew\x0d\xa5B\x00\x00\ +\x00\x00IEND\xaeB`\x82\ +\x00\x00\x05~\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x05\x17iTXtXML\ +:com.adobe.xmp\x00\x00\ +\x00\x00\x00 \ + \x07b\x0c\x81\x00\x00\x00\x0dIDAT\ +\x08\x1dc\xf8\xff\xff?\x03\x00\x08\xfc\x02\xfe\xe6\x0c\xff\ +\xab\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\xa6\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15;\xdc\ +;\x0c\x9b\x00\x00\x00*IDAT\x08\xd7c`\xc0\ +\x00\x8c\x0c\x0cs> \x0b\xa4\x08020 \x0b\xa6\ +\x08000B\x98\x10\xc1\x14\x01\x14\x13P\xb5\xa3\x01\ +\x00\xc6\xb9\x07\x90]f\x1f\x83\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ +\x00\x00\x043\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\xe5IDATh\x81\xed\ +\x9aM\x88\x1cE\x14\xc7\x7f3;\x89.\x18\xf13\x1e\ +\x92\x8b\x8b\xa2&\x06\x14/\xa29\x88\x15\x89\xa9\x18\x15\ +\xd1\xca\x06\x0f\x91\x05=\x88bnB\xc0\x1c\x12\xc4\x83\ +\x07\x15\x0dB\x14\x89\x04\xa2\x96DY\x22/F}\x8a\ +\xb0\x22\x08\x1e4\xbb\x22F\x8c,\x88\xba\xc4\x88\x82_\ +\xc9F=T\x0f\x8c\xbd\xdd]\xdd\xd3a\xa7\x07\xfc\xdd\ +\xa6\xfa\xd5\xab\xf7\xea\xf3\xdf\xd5\xd3\x22\xc1Xw\x11\xb0\ +\x03X\x0b\x5c\x0d,\xa1Y\x9c\x02\xa6\x81)`\xa7\x8a\ +?\x0e\xd0\x020\xd6\xdd\x0c\xbc\x02,\x1fXx\xd5\x98\ +\x03\xb6\xa8\xf8\xf7[I\xcf\xcf0<\xc1w\x99\x03V\ +\xb7\x09\xd3f\xd8\x82\x87\x10\xf3c\x1d\xc2\x9cOsz\ +\x91\x83)\xcbH\xea\xf7\xda\x0ea\xc1\xf6rZ\xc5w\ +\x16)\xa0J\x18\xeb\xe6\xf9o\x12k\xda4o\xb7\xa9\ +\xc2\x92\xf6\xa0#\xa8\xcb\xff\x09\x0c\x9a\xa1O\xa0\xa9\xbb\ +\xcd=\xc0]\xc0K*\xfe\xdd\x22\xdb\xc6\x8d\x80\xb1\xee\ +\x11\xc0\x03\xe3\xc0ac\xddnc]\xeeN\xd9\xa8\x04\ +\x8cu\xe3\xc0S=E-\xe0A\xe0\x85\xbc:\x8d\x99\ +B\xc6\xbau\xc0\xcb$\x023\xc5Vc\xdd\x91\xacz\ +\x8d\x18\x01c\xddu\xc0\x1b\xc0\xd2\x02\xb3\x0dY\x85\x03\ +O\xc0Xw\x19 \xc0\xb2\x88\xe9\x8bY\x85\x03M\xc0\ +Xw\x09p\x98\xb8\x1a~R\xc5\xbf\x9a\xf5``\x09\ +\x18\xeb\x96\x01\x87\x80\xb1\x88\xe9>\xe0\xd1\xbc\x87\x03I\ +\xc0X\xb7\x14x\x13\xb86b\xfa60\xa1\xe2\xff\xc9\ +3X\xf4\x04\x8cumB\xaf\x9a\x88\xe9'\xc0\xdd*\ +~\xbe\xc8h\x10#\xf04\xe0\x226_\x01\x1bU\xfc\ +o1g\xa5\x120\xd6\xb5\x92\x9e\xab\x85\xb1n;\xf0\ +p\xc4\xec{`}\xf7\xd6!FaPI\xe0\xdb\x80\ +?\x80ic\xdd\x9aR\x91f\xfb\x9a\x00\x1e\x8f\x98\xfd\ +\x02\xdc\xaa\xe2\xbf-\xeb77\x81D\x7fL\x12\x8e\xf6\ +\xb3\x80\xab\x80\xf7\x8cuW\x94u\xde\xe3k\x13\xb0'\ +b\xf6\x17p\x87\x8a\xff\xbc\x8a\xef\xa2\x11x\x0e\xd8\x94\ +*[\x0e\xa8\xb1\xee\xd2\xb2\x0d\x18\xebn\x00^c\xe1\ +\x0by/\x7f\x03\xf7\xaa\xf8\x0f\xcb\xfa\xed\x92\x99@\xd2\ +c\x0f\xe4\xd4YA\x18\x89\x151\xe7\xc6\xbaU\xc0A\ +`4b\xfa\x90\x8a?\x10\xf3\x97E\xde\x08\x5c\x10\xa9\ +7FH\xe2\xe2<\x03c\xddJ\xc2)\x1b\xf3\xb5K\ +\xc5?\x1f\xb1\xc9%/\x81\xfd\x84}\xb8\x88+\x81w\ +\x8cu\xe7\xa5\x1f\x18\xeb\xce'\x04\xbf2\xe2c\x8f\x8a\ +\xdf\x11\x8d\xb2\x80\xcc\x04T\xfc)\x82\xfa\xcb\x94\xb0=\ +\x5c\x03\x1c2\xd6\x9d\xd3-0\xd6\x8d\x12\xa6\xcd\xaaH\ +\xddI\x82\xd6\xafE\xee\x22V\xf1'\x80[\x80\xa3\x11\ +\x1f\xd7\x03\x07\x8du\xa3\xc6\xba\x11\xc2\x82\xbd1Rg\ +\x0a\x18W\xf1\xb5o\x00\x0b\xcf\x01\x15\xff#\xb0\x0e\x98\ +\x8d\xf8\xb9\x098@\xd8*\xd3;W\x9ai\xe0v\x15\ +\xffg\xc9\x18\x0b\x89\x9e\xae*~\x96\xa0[~\x88\x98\ +n\x00&\x226\xb3\x84\x83\xea\xe7r\xe1\xc5)%\x0f\ +T\xfc\xd7\x84\x91\xf8\xa9F['\x08\x12\xe1\xbb\x1a>\ +\x16PZ\xdf\xa8\xf8\x19`=\xf0k\x1f\xed\xfc\x0e\xdc\ +\xa6\xe2\xbf\xec\xa3n!\x95\x04\x9a\x8a\xff\x14\xd8\x98\x04\ +T\x96y`\xb3\x8a\xff\xb8J[e\xa9\xac0U\xfc\ +\x14p'A\xbb\x94\xe1~\x15\xffV\xd5v\xca\xd2\x97\ +DNn\xcb6\x13z\xb7\x88\xed*~o?m\x94\ +\xa5o\x8d\xaf\xe2'\x81\xad\x04!\x96\xc5\xb3*\xfe\x89\ +~\xfd\x97\xa5\xd6K\x8a\x8a\xdf\x0f\xdc\xc7\xc25\xb1\x1b\ +\xd8V\xc7wYj\xdf\xcc\xa9\xf8}\xc6\xba\x8f\x08\x07\ +\xd8\xb9\xc0\x07\xc9:Y\x14\xce\xc8\xd5\xa2\x8a\xff\x06x\ +\xe6L\xf8\xaaJ\x9b\xf0\x05|X9\xd9!h\x93\xde\ +\xfb\x99\x91\xe4k`\x13I\xbf\xd5Mw\x08\xca0}\ +\xc1T\xf4\xfa\xd7$\xa6\xda\xc0N\xc2g\xfbac\x0e\ +\xd8\xd5N\xee_\xb60\x5cIt\xff\xecq|\x04\xe0\ +\xd8\xd1\x99cc\x97\xaf\xde\x0b\x9cM\xf8\xf0}!\xcd\ +\x9bF'\x81\xcf\x80\xd7\x01\xa7\xe2\xbf\x00\xf8\x17]\x81\ +\x0b8\xb3\xfa \x9c\x00\x00\x00\x00IEND\xaeB\ +`\x82\ +\x00\x00\x00\xa0\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1c\x1f$\ +\xc6\x09\x17\x00\x00\x00$IDAT\x08\xd7c`@\ +\x05\xff\xcf\xc3XL\xc8\x5c&dY&d\xc5p\x0e\ +\xa3!\x9c\xc3h\x88a\x1a\x0a\x00\x00m\x84\x09u7\ +\x9e\xd9#\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x01\xdc\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x8eIDATh\x81\xed\ +\x9a\xafN\xc3P\x14\x87\xbfn\x1d\x0a\x1cA\x1e\x83\x04\ +\xc4\x0cjA\x10\x04\x82\x80\x9e\xe7\x05x\x80!x\x01\ +^\x00\x8f\xc2\x00rA\x90=\xc2@1s\xe42\x14\ +\xc1\xecO\x82h\x1b\xb6e\xed(\xebv\xda\xe5~\xae\ +\xf7\x5c\xf1\xfb\xda{o\x9a\xdc\xe3\x11\xa2\xaa\xdb\xc05\ +P\x03\xf6\x81\x0a\xf9b\x00\xb4\x81\x16p#\x22=\x00\ +\x0f@U\x8f\x81{`\xc7,^:\xba@]D^\ +\xbc\xf0\xcd\xbfQ\x9c\xf0\x11]`\xafD\xb0l\x8a\x16\ +\x1e\x82\xcc\x0d\x9f`\xcdO3Zq\x98\xbfR\x9ez\ +\xae\xf9\x04\x1bv\x9c\x91\x88\xf8+\x0a\x94\x0aU\x1d2\ +)qP\x22\x7f\xa7M\x1a*%\xeb\x04\x8b\xe2\x04\xac\ +q\x02\xd68\x01k\x9c\x805N\xc0\x1a'`\xcd\xdc\ +\xdffU=\x01\x0e\x81\xcd\xe5\xc7\x99`\x08\xbc\x03O\ +\x22\xf2\x1d7)V@U}\xe0\x018\xcf>[*\ +:\xaaz*\x22\x1f\xb3\x8aIK\xe8\x0a\xfb\xf0\x00\xbb\ +\xc0]\x5c1I\xe0,\xfb,\xff\xe6HU\xb7f\x15\ +\x0a\xbf\x89\x93\x04\x9eW\x96b>\xaf\x22\xf25\xab\x90\ +$p\x0b<.'O*:\xc0e\x5c1\xf6\x14\x12\ +\x91!pQ\xd8c4BD\x9a@3\xc3`\x99\xb2\ +\xd6\x9b\xb8\x108\x01k\x9c\x805N\xc0\x1a'`\x8d\ +\x13\xb0f-\x04\x06\xd6!\x16\xa0\xef\x13\x5c\xdfW\xc7\ +\x06\xcb\xe1m`\x1e\x99\xbefm\xfb\x04\xbd\x07\xd59\ +\x13\xf3J\xab\xf8\xad\x06a\xd7G=\x1c(\x0aQ\xb3\ +G\xcf\x8bF\xc2/\xd1\xe0\xb7\xddf\xc3(\x5c\x1c}\ +&\xdbm>\x01~\x00%\xf8ZCUN:\x7f\x00\ +\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x01\xfc\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\xaeIDATh\x81\xed\ +\x9a\xbdJ\x03A\x14FO6\x1b\xb0\xd0J\xf1\x01\x14\ +\xabh\x91\xc6*X\xb8\x16\xb2\x88v\x0b\xe9}\x01\x1f\ +@\x8b\xf8\x00\xbe\x80\x85\x9d0b\xa32U\xc6B\xf2\ +\x02B\x92F\x83}H'6\xf9\x01\x8b\xdd@\x12\xb2\ +\x89k~f7\xcc\xe9v\xef\x14\xdfY\xee\x0c\x0bw\ +R\x048\xae\xb7\x01\x5c\x01y`\x17\xc8\x10/\xda@\ +\x05(\x03E%E\x13 \x05\xe0\xb8\xde!p\x0fl\ +j\x8b\x17\x8d\x06PPR\xbc\xa6\x82/_%9\xe1\ +{4\x80\xac\x85\xdf6I\x0b\x0f~\xe6K\x1b\xbf\xe7\ +\x87\xe9.8\xcc_I\x0f=\xe7m\xfc\x0d\xdbOW\ +Ia/(P$\x1c\xd7\xeb0(\xb1g\x11\xbf\xd3\ +&\x0a\x19Kw\x82i1\x02\xba1\x02\xba1\x02\xba\ +1\x02\xba1\x02\xba1\x02\xba\x99\xf8\xdb\xec\xb8\xde\x11\ +\xb0\x0f\xac\xce?\xce\x00\x1d\xa0\x06<+)~\xc2\x16\ +\x85\x0a8\xaeg\x03\x8f\xc0\xe9\xec\xb3E\xa2\xee\xb8\xde\ +\xb1\x92\xe2sTq\x5c\x0b]\xa0?<\xc06p\x1b\ +V\x1c'p2\xfb,\xff\xe6\xc0q\xbd\xb5Q\x85\xc4\ +o\xe2q\x02/\x0bK1\x997%\xc5\xf7\xa8\xc28\ +\x81\x1b\xe0i>y\x22Q\x07\xce\xc3\x8a\xa1\xa7\x90\x92\ +\xa2\x03\x9c%\xf6\x18\xed\xa1\xa4(\x01\xa5\x19\x06\x9b)\ +K\xbd\x89\x13\x81\x11\xd0\x8d\x11\xd0\x8d\x11\xd0\x8d\x11\xd0\ +\x8d\x11\xd0\xcdR\x08\xb4u\x87\x98\x82\x96\x8d?\xbe\xcf\ +\xf5\xbdL\x07\xd3\xc082\xaa_[\ +;\xd9;`\x05\x7f\xf0\xbdN\xfc\xda\xa8\x05\xbc\x03\x0f\ +\x80\xa7\xa4\xa8\x01\xfc\x02Q\xab\x5c\x8a?\xde\xe3Y\x00\ +\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\x9e\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15\x0f\xfd\ +\x8f\xf8.\x00\x00\x00\x22IDAT\x08\xd7c`\xc0\ +\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1BH*\x0c\x19\ +\x18\x18\x91\x05\x10*\xd1\x00\x00\xca\xb5\x07\xd2v\xbb\xb2\ +\xc5\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\xa6\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1d\x00\xb0\ +\xd55\xa3\x00\x00\x00*IDAT\x08\xd7c`\xc0\ +\x06\xfe\x9fg``B0\xa1\x1c\x08\x93\x81\x81\x09\xc1\ +d``b``4D\xe2 s\x19\x90\x8d@\x02\ +\x00d@\x09u\x86\xb3\xad\x9c\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ +\x00\x00\x00\x9e\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15\x0f\xfd\ +\x8f\xf8.\x00\x00\x00\x22IDAT\x08\xd7c`\xc0\ +\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1BH*\x0c\x19\ +\x18\x18\x91\x05\x10*\xd1\x00\x00\xca\xb5\x07\xd2v\xbb\xb2\ +\xc5\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x07\xdd\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x07\x00\x00\x00\x0a\x08\x06\x00\x00\x00x\xccD\x0d\ +\x00\x00\x05RiTXtXML:com.\ +adobe.xmp\x00\x00\x00\x00\x00\x0a\x0a \x0a \x0a \x0a \ +\x0a branch_close<\ +/rdf:li>\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a <\ +/rdf:RDF>\x0a\x0aX\xad\xf2\x80\x00\x00\ +\x01\x83iCCPsRGB IEC61\ +966-2.1\x00\x00(\x91u\x91\xcf+D\ +Q\x14\xc7?fh\xfc\x18\x8dba1e\x12\x16B\ +\x83\x12\x1b\x8b\x99\x18\x0a\x8b\x99Q~mf\x9ey3\ +j\xdex\xbd7\xd2d\xabl\xa7(\xb1\xf1k\xc1_\ +\xc0VY+E\xa4d\xa7\xac\x89\x0dz\xce\x9bQ#\ +\x99s;\xf7|\xee\xf7\xdes\xba\xf7\x5cpD\xd3\x8a\ +fV\xfaA\xcbd\x8dp(\xe0\x9b\x99\x9d\xf3\xb9\x9e\ +\xa8\xa2\x85\x1a:\xf1\xc6\x14S\x9f\x8c\x8cF)k\xef\ +\xb7T\xd8\xf1\xba\xdb\xaeU\xfe\xdc\xbfV\xb7\x980\x15\ +\xa8\xa8\x16\x1eVt#+<&<\xb1\x9a\xd5m\xde\ +\x12nRR\xb1E\xe1\x13\xe1.C.(|c\xeb\ +\xf1\x22?\xdb\x9c,\xf2\xa7\xcdF4\x1c\x04G\x83\xb0\ +/\xf9\x8b\xe3\xbfXI\x19\x9a\xb0\xbc\x9c6-\xbd\xa2\ +\xfc\xdc\xc7~\x89;\x91\x99\x8eHl\x15\xf7b\x12&\ +D\x00\x1f\xe3\x8c\x10d\x80^\x86d\x1e\xa0\x9b>z\ +dE\x99|\x7f!\x7f\x8ae\xc9Ud\xd6\xc9a\xb0\ +D\x92\x14Y\xbaD]\x91\xea\x09\x89\xaa\xe8\x09\x19i\ +rv\xff\xff\xf6\xd5T\xfb\xfb\x8a\xd5\xdd\x01\xa8z\xb4\ +\xac\xd7vpm\xc2W\xde\xb2>\x0e,\xeb\xeb\x10\x9c\ +\x0fp\x9e)\xe5/\xef\xc3\xe0\x9b\xe8\xf9\x92\xd6\xb6\x07\ +\x9eu8\xbd(i\xf1m8\xdb\x80\xe6{=f\xc4\ +\x0a\x92S\xdc\xa1\xaa\xf0r\x0c\xf5\xb3\xd0x\x05\xb5\xf3\ +\xc5\x9e\xfd\xecst\x07\xd15\xf9\xaaK\xd8\xd9\x85\x0e\ +9\xefY\xf8\x06\x8e\xfdg\xf8\xfd\x8a\x18\x97\x00\x00\x00\ +\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\ +\x9c\x18\x00\x00\x00\xa2IDAT\x18\x95U\xcf\xb1J\ +\xc31\x00\xc4\xe1/\xff\xb9\x93\xa3\x93\xb8\xa5\x8b\x0f \ +UD\x10\x5c:\x84,\x1d\x5c|\x0f\xb7\x8e>J\x88\ +\xa3\xb8\x08m\x05\xbbw\xc8\xea\xe2\x0bto\xe9\xd2B\ +zpp\xf0\xe3\x0e.\xa4\xd2\xae\xf0\x8a\xf7\x9a\xe3V\ +\xa7\x01\xd7x\xc32\x95vy\x06k\x8e\xdfx\xc1\x18\ +\xbf\xa9\xb4\xf1\x09\x86SH\xa5=\xe2\x03;Lk\x8e\ +\xab\xd0\xcf\xa4\xd2n\xf0\x89\x0b\xdc\x0f\xce\xb5?: \ +\x0c]\xeb\x01?\x18\xe1\xa9\xe6\xb8\x1e\x8e`\x86/l\ +q[s\x5c@H\xa5\xdda\x81\x0d\x9ek\x8e\xff\xfd\ +\xcf?\xcc1\xe9\x01\x1c\x00sR-q\xe4J\x1bi\ +\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x03\xfb\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\xadIDATh\x81\xed\ +\x9aO\xa8\x15U\x1c\xc7?\xf7\xbe\xab\xf2 \xa3\x22m\ +\xa1|!\x09*K(\xdaD\xb9\x88RL\xccjQ\ +\xf9\xa4\x85\xf1\xa0\x16Q\xe4.\x10tQD\x8b\x16\x15\ +%\x81\xb5(\x04\xad\xc0\xe2ad\xf6\x97\xe0E\x10\xb4\ +\xa9'DE\xc4\x17\xa2\x125\x0a*\xff<\xab\xc5\x99\ +[\xd7y3s\xce\xdcko\xee\x05?\xbb9\xf3;\ +\xbf\xf3\xfb\x9d3\xe7\x9c\xef\x9c\x99\x16\x19\xb6/\x06v\ +\x00\xab\x81\xab\x81\x05\x0c\x17\xa7\x80\x19`\x1axL\xd2\ +\x11\x80\x16\x80\xed\x9b\x81\xbd\xc0\xd2\xc6\xc2\xab\xc7a`\ +\xb3\xa4\x0f[Y\xcf\x1fbt\x82\xefr\x18\xb8\xaaM\ +xlF-x\x081o\xef\x10\x9e\xf9<\xa7\xe79\ +\x98T\xc6r\xd7\xab;\x84\x09\xdb\xcbiI\x9dy\x0a\ +\xa8\x16\xb6g93\x89Um\x86o\xb5\xa9\xc3\x82v\ +\xd3\x11\x0c\xca\xb9\x04\x9a\xe6\x5c\x02\xff\x07\xb6\xef\xb6\xbd\ +\xd7\xf6\xda\x98\xed\xd0%`\xfb\x11\xe0u`\x028h\ +{\xa7\xed\xd2\x95r\xa8\x12\xb0=\x01<\xddS\xd4\x02\ +\x1e\x04^,\xab34\x1b\x96\xed5\xc0+d\x023\ +\xc7\x16\xdb_\x16\xd5\x1b\x8a\x11\xb0}\x1d\xf0\x06\xb0\xb0\ +\xc2l}Qa\xe3\x09\xd8\xbe\x0cx\x1bX\x1c1}\ +\xa9\xa8\xb0\xd1\x04l_\x02\x1c$\xae\x86\x9f\x92\xf4j\ +\xd1\x8d\xc6\x12\xb0\xbd\x188\x00\xac\x88\x98\xee\x06\x1e-\ +\xbb\xd9H\x02\xb6\x17\x02o\x02\xd7FL\xdf\x01&%\ +\xfd]f0\xef\x09\xd8n\x13z\xf5\x96\x88\xe9g\xc0\ +]\x92f\xab\x8c\x9a\x18\x81g\x80{\x226_\x03\x1b\ +$\xfd\x1es\x96\x94\x80\xedV\xd6s\x03a{\x1b\xf0\ +p\xc4\xecG`]\xf7\xd4!FePY\xe0[\x81\ +?\x81\x19\xdb\xab\x92\x22-\xf65\x09<\x111\xfb\x15\ +\xb8U\xd2\xf7\xa9~K\x13\xc8\xf4\xc7\x14ak_\x04\ +\x5c\x09\xbco\xfb\xf2T\xe7=\xbe6\x02\xbb\x22f'\ +\x80;$}Q\xc7w\xd5\x08<\x0fl\xcc\x95-\x05\ +>\xb0}ij\x03\xb6o\x00^c\xee\x0by/\x7f\ +\x01\xf7J\xfa8\xd5o\x97\xc2\x04\xb2\x1e{\xa0\xa4\xce\ +2\xc2H,\x8b9\xb7\xbd\x12\xd8\x0f\x8cGL\x1f\x92\ +\xb4/\xe6\xaf\x88\xb2\x11\xb8(Ro\x05!\x89%e\ +\x06\xb6\x97\x13v\xd9\x98\xaf\xc7%\xbd\x10\xb1)\xa5,\ +\x81=\x84u\xb8\x8a+\x80wm_\x90\xbfa\xfbB\ +B\xf0\xcb#>vI\xda\x11\x8d\xb2\x82\xc2\x04$\x9d\ +\x22\xa8\xbfB\x09\xdb\xc35\xc0\x01\xdb\xe7u\x0bl\x8f\ +\x13\x1e\x9b\x95\x91\xbaS\x04\xad?\x10\xa5\x93X\xd21\ +`-\xf0M\xc4\xc7\xf5\xc0~\xdb\xe3\xb6\xc7\x08\x13\xf6\ +\xc6H\x9di`B\xd2\xc0'\x80\x95\xfb\x80\xa4\x9f\x81\ +5\x80#~n\x02\xf6\x11\x96\xca\xfc\xca\x95g\x06\xb8\ +]\xd2\xf1\xc4\x18+\x89\xee\xae\x92L\xd0-?EL\ +\xd7\x03\x93\x11\x1b\x136\xaa_\xd2\xc2\x8b\x93$\x0f$\ +}K\x18\x89\xa3\x03\xb4u\x8c \x11~\x18\xc0\xc7\x1c\ +\x92\xf5\x8d\xa4C\xc0:\xe0\xb7>\xda\xf9\x03\xb8M\xd2\ +W}\xd4\xad\xa4\x96@\x93\xf49\xb0!\x0b(\x95Y\ +`\x93\xa4O\xeb\xb4\x95Jm\x85)i\x1a\xb8\x93\xa0\ +]R\xb8_\xd2[u\xdbI\xa5/\x89,\xe9=`\ +\x13\xa1w\xab\xd8&\xe9\xe5~\xdaH\xa5o\x8d/i\ +\x0a\xd8B\x10bE<'\xe9\xc9~\xfd\xa72\xd0K\ +\x8a\xa4=\xc0}\xcc\x9d\x13;\x81\xad\x83\xf8Ne\xe0\ +\x939I\xbbm\x7fB\xd8\xc0\xce\x07>\xca\xe6\xc9\xbc\ +pV\x8e\x16%}\x07<{6|\xd5\xa5M\xf8\x02\ +>\xaa\x9c\xec\x10\xb4I\xef\xf9\xccX\xf65p\x18\xc9\ +\xbf\xd5\xcdt\x08\xca0\x7f\xc0T\xf5\xfa7LL\x8f\ +\xfe\xaf\x06\xd9\xf9\xcb\xe6\xac`T\xe8\xfe\xecq\xe4\xdf\ +\x8f\x09\xd9Hl\xe7\xbf\xdfm\xaa\xce\xea\x9b\xe0$g\ +\xfens\x14\xe0\x1f\x0aC\x12kO\xfd?\x13\x00\x00\ +\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\xa0\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1f\x0d\xfc\ +R+\x9c\x00\x00\x00$IDAT\x08\xd7c`@\ +\x05s>\xc0XL\xc8\x5c&dY&d\xc5pN\ +\x8a\x00\x9c\x93\x22\x80a\x1a\x0a\x00\x00)\x95\x08\xaf\x88\ +\xac\xba4\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x01\xe1\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x93IDATh\x81\xed\ +\x9a;N\xc3@\x10\x86\xbfq\x1c*\xe8\x10\xe56\x94\ +\xd0\xa4\xa1\x8a(\x22\x0a\x0aD\x9f\x9e\x0bp\x80Pp\ +\x01.\xc0\x15h\x80\x13\xa0\x1c!P\x91f\xbbD\xa1\ +B4yh(l\x1e\xb1\xfcH\x08\xc9\xda\xd2~\x9d\ +w\x5c\xfc\x9f\xb3\x1e9\xda\x11bTu\x17\xb8\x02\x9a\ +\xc0!P\xa7\x5cL\x80\x1e\xd0\x05\xaeEd\xf4]Q\ +\xd5\x96\xaa\x0e\xb4:\x0cT\xb5\x05 \x1a=\xf9g`\ +\xcf\xc5c]\x81!p\x10\x10m\x9b\xaa\x85\x87(s\ +'$\xda\xf3If\x1b\x0e\xb3(\xb5\xc4uSTu\ +\xcc\xfc\x0b;\x13\x91p\x83\xa1\x16FU\xa7\xccKL\ +\x02\xca\xd7m\x96\xa1\x1e\xb8N\xb0*^\xc05^\xc0\ +5^\xc05^\xc05^\xc05^\xc05\x85\x9f\xcd\ +\xd6\xda\x13\xe0\x08\xd8^\x7f\x9c9\xa6\xc0\x0b\xf0`\x8c\ +\xf9\xc8\xbaITU\x13k3\x11\x09\xad\xb5!p\x07\ +\x9c\xaf1\xe4\x22\xf4\x81Sc\xcck\xca\xff\x81\xdc-\ +t\x89\xfb\xf0\x00\xfb\xc0mV1O\xe0\xec\xff\xb3\xfc\ +\x99ck\xedNZ\xa1\xf2/q\x9e\xc0\xe3\xc6R\x14\ +\xf3d\x8cyO+\xe4\x09\xdc\x00\xf7\xeb\xc9\xb3\x14}\ +\xe0\x22\xab\x98\xd9\x85\xbe.\xca\xd4F\xd3\xbaP\xa1@\ +\x99X\xb6\x8dV\x02/\xe0\x1a/\xe0\x1a/\xe0\x1a/\ +\xe0\x1a/\xe0\x1a/\xe0\x9a\x80\xe8\x04\xbc\xaa\x8cC\xa2\ +\xe3\xfb\xc6\xaf\xc5Z\xfc\xd9ZF\x92\xc7\xac\xbd\x90h\ +\xf6\xa0QpcY\xe9V\x7f\xd4 \x9e\xfah\xc7\x0b\ +Ua\x08\xb4Ed$_+\xf1/\xd1\xe1g\xdcf\ +\xcbQ\xb8,\xc6\xcc\x8f\xdb\xbc\x01|\x02mw#\xb3\ +\xd4\x95Sv\x00\x00\x00\x00IEND\xaeB`\x82\ +\ +\x00\x00\x01W\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x09IDATh\x81\xed\ +\xda\xcdm\xc2@\x14E\xe1\xf3\x8cI\x05Q\x9aH6\ +\xecY\xd1\x05\xc5\x90Ej\xa3\x04R\x04\x884`\x82\ +n\x163\xf9\xb1\xa5(DH\x5c[z\xdf\x8e\xc1\x8b\ +w\x8c\xcdf&\xa8$\xdd\x03\xcf\xc0\x12x\x02\xe6\x8c\ +\xcb\x09\xd8\x01[\xe0%\x22\x8e_\xdfHZI\xdak\ +:\xf6\x92V\x00\xa1r\xe7_\x81\x07\xc7m\xbd\xc2\x01\ +xl(\x8f\xcd\xd4\x86\x872\xf3\xa6\xa5<\xf3C\xe7\ +\x1b\x0fs\xa9\xd9\xe0\xf32$u\xf4_\xd8sD\xb4\ +7\x1c\xeab\x92\xde\xe9G\x9c\x1a\xc6\xf7o\xf3\x1f\xf3\ +\xc6=\xc1\xb52\xc0-\x03\xdc2\xc0-\x03\xdc2\xc0\ +-\x03\xdc2\xc0-\x03\xdc2\xc0-\x03\xdc2\xc0-\ +\x03\xdc2\xc0-\x03\xdc2\xc0-\x03\xdc2\xc0\xad\xa1\ +\xec\x80OU\xd7R\xb6\xef\x17?\x16gu7p\x8c\ +\x86\xdb\xac\xbb\x96r\xf6`\xf1\xc7\x85c\xb5\x9d\xfeQ\ +\x83z\xeac]\x17\xa6\xe2\x00\xac#\xe2\x18\x9f+\xf5\ +\x97\xd8\xf0}\xdc\xe6\xce4\xdco:\xfa\xc7m\xde\x00\ +>\x00G\xd7\xea\xb1\xadi\xe1\xd6\x00\x00\x00\x00IE\ +ND\xaeB`\x82\ +\x00\x00\x01v\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01(IDATh\x81\xed\ +\xda\xb1J\xc3P\x14\x87\xf1/7\xb7\xe0\xae\xf8\x00\x82\ +Su\xe8\xde\xc9ly\x80@\x1fF\x87\xfa\x22nB\ +\xdc\xb3\xc5\xa9/ \xb4]:t\x0f}\x82j\xc1\xe1\ +\xa6P\xb3h\x10\xfa\xcf\x85\xf3\xdbR:\x9c\xaf\xdcf\ +97\xa1\x95\xe5\xc5\x15\xf0\x04L\x81;`\xc4\xb0|\ +\x02K`\x01\xcc\xeb\xaa\xdc\x01$\x00Y^<\x00\xaf\ +\xc0\xb5l\xbc~\x1a`VW\xe5{\xd2\xfe\xf2+\xe2\ +\x19\xfe\xa8\x01\xc6\x8eplb\x1b\x1e\xc2\xcc\x8f\x9ep\ +\xe6\xbb\x0eg\x1e\xe6\xaf\xd2\xce\xf3\xd4\x13\xfe\xb0\xa7\x0e\ +uU\xfa3\x0d\xd4K\x96\x17_\xfc\x8c\xb8w\x0c\xef\ +m\xd3\xc7\xc8\xa9'\xf8/\x0bP\xb3\x005\x0bP\xb3\ +\x005\x0bP\xb3\x005\x0bP\xb3\x005\x0bP\xb3\x00\ +5\x0bP\xb3\x005\x0bP\xb3\x005\x0bP\xb3\x005\ +\x0bPs\x84\x0dx\xac\xf6\x9e\xb0\xbe\x9f\x9c|\x98\xb6\ +\xdb\xc0!\xea\xaeY\x97\x9ep\xf7`\xf2\xcb\x17\x87j\ +\xe1\x809am\x1f\x9b\x06xv\xed\xad\x8f\x19qE\ +\x1c/{\xecR\x80\xedf\xb5\xbd\xb9\x1d\xbf\x00\x17\x84\ +\xc5\xf7%\xc3;F{\xe0\x03x\x03\x8a\xba*\xd7\x00\ +\xdf\xa4\xb56\xa2\xca\x99tG\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ +" + +qt_resource_name = b"\ +\x00\x08\ +\x06\xc5\x8e\xa5\ +\x00o\ +\x00p\x00e\x00n\x00p\x00y\x00p\x00e\ +\x00\x06\ +\x07\x03}\xc3\ +\x00i\ +\x00m\x00a\x00g\x00e\x00s\ +\x00\x17\ +\x0ce\xce\x07\ +\x00l\ +\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\ +\x00e\x00d\x00.\x00p\x00n\x00g\ +\x00\x1a\ +\x03\x0e\xe4\x87\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00c\x00h\x00e\x00c\x00k\x00e\x00d\x00_\ +\x00h\x00o\x00v\x00e\x00r\x00.\x00p\x00n\x00g\ +\x00 \ +\x0f\xd4\x1b\xc7\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00i\x00n\x00d\x00e\x00t\x00e\x00r\x00m\ +\x00i\x00n\x00a\x00t\x00e\x00_\x00h\x00o\x00v\x00e\x00r\x00.\x00p\x00n\x00g\ +\x00\x15\ +\x03'rg\ +\x00c\ +\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\ +\x00.\x00p\x00n\x00g\ +\x00\x11\ +\x01\x1f\xc3\x87\ +\x00d\ +\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\ +\ +\x00\x0e\ +\x04\xa2\xfc\xa7\ +\x00d\ +\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\ +\x00\x1b\ +\x03Z2'\ +\x00c\ +\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\ +\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\x00n\x00g\ +\x00\x0f\ +\x02\x9f\x05\x87\ +\x00r\ +\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\ +\x00\x12\ +\x01.\x03'\ +\x00c\ +\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\ +\x00g\ +\x00\x1c\ +\x0e<\xde\x07\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00u\x00n\x00c\x00h\x00e\x00c\x00k\x00e\ +\x00d\x00_\x00h\x00o\x00v\x00e\x00r\x00.\x00p\x00n\x00g\ +\x00\x0f\ +\x06S%\xa7\ +\x00b\ +\x00r\x00a\x00n\x00c\x00h\x00_\x00o\x00p\x00e\x00n\x00.\x00p\x00n\x00g\ +\x00\x0e\ +\x0e\xde\xfa\xc7\ +\x00l\ +\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\ +\x00\x11\ +\x0b\xda0\xa7\ +\x00b\ +\x00r\x00a\x00n\x00c\x00h\x00_\x00c\x00l\x00o\x00s\x00e\x00d\x00.\x00p\x00n\x00g\ +\ +\x00\x15\ +\x0f\xf3\xc0\x07\ +\x00u\ +\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\ +\x00.\x00p\x00n\x00g\ +\x00\x12\ +\x05\x8f\x9d\x07\ +\x00b\ +\x00r\x00a\x00n\x00c\x00h\x00_\x00o\x00p\x00e\x00n\x00_\x00o\x00n\x00.\x00p\x00n\ +\x00g\ +\x00\x1a\ +\x05\x11\xe0\xe7\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00c\x00h\x00e\x00c\x00k\x00e\x00d\x00_\ +\x00f\x00o\x00c\x00u\x00s\x00.\x00p\x00n\x00g\ +\x00\x16\ +\x01u\xcc\x87\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00u\x00n\x00c\x00h\x00e\x00c\x00k\x00e\ +\x00d\x00.\x00p\x00n\x00g\ +\x00\x0f\ +\x0c\xe2hg\ +\x00t\ +\x00r\x00a\x00n\x00s\x00p\x00a\x00r\x00e\x00n\x00t\x00.\x00p\x00n\x00g\ +\x00\x17\ +\x0c\xabQ\x07\ +\x00d\ +\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\ +\x00e\x00d\x00.\x00p\x00n\x00g\ +\x00\x1d\ +\x09\x07\x81\x07\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00c\x00h\x00e\x00c\x00k\x00e\x00d\x00_\ +\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\x00n\x00g\ +\x00\x12\ +\x03\x8d\x04G\ +\x00r\ +\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\ +\x00g\ +\x00\x1a\ +\x01\x87\xaeg\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00i\x00n\x00d\x00e\x00t\x00e\x00r\x00m\ +\x00i\x00n\x00a\x00t\x00e\x00.\x00p\x00n\x00g\ +\x00#\ +\x06\xf2\x1aG\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00i\x00n\x00d\x00e\x00t\x00e\x00r\x00m\ +\x00i\x00n\x00a\x00t\x00e\x00_\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\ +\x00n\x00g\ +\x00\x0c\ +\x06\xe6\xe6g\ +\x00u\ +\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\ +\x00\x11\ +\x00\xb8\x8c\x07\ +\x00l\ +\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\ +\ +\x00\x0f\ +\x01s\x8b\x07\ +\x00u\ +\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\ +\x00\x14\ +\x04^-\xa7\ +\x00b\ +\x00r\x00a\x00n\x00c\x00h\x00_\x00c\x00l\x00o\x00s\x00e\x00d\x00_\x00o\x00n\x00.\ +\x00p\x00n\x00g\ +\x00\x14\ +\x07\xec\xd1\xc7\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00c\x00h\x00e\x00c\x00k\x00e\x00d\x00.\ +\x00p\x00n\x00g\ +\x00\x18\ +\x03\x8e\xdeg\ +\x00r\ +\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\ +\x00l\x00e\x00d\x00.\x00p\x00n\x00g\ +\x00 \ +\x09\xd7\x1f\xa7\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00i\x00n\x00d\x00e\x00t\x00e\x00r\x00m\ +\x00i\x00n\x00a\x00t\x00e\x00_\x00f\x00o\x00c\x00u\x00s\x00.\x00p\x00n\x00g\ +\x00\x1c\ +\x08?\xdag\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00u\x00n\x00c\x00h\x00e\x00c\x00k\x00e\ +\x00d\x00_\x00f\x00o\x00c\x00u\x00s\x00.\x00p\x00n\x00g\ +\x00\x1f\ +\x0a\xae'G\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00u\x00n\x00c\x00h\x00e\x00c\x00k\x00e\ +\x00d\x00_\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x16\x00\x02\x00\x00\x00 \x00\x00\x00\x03\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x04\xb8\x00\x00\x00\x00\x00\x01\x00\x008:\ +\x00\x00\x01{\xe9xF\xdd\ +\x00\x00\x01\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x07]\ +\x00\x00\x01{\xe9xF\xdb\ +\x00\x00\x01\xb6\x00\x00\x00\x00\x00\x01\x00\x00\x09\xfc\ +\x00\x00\x01{\xe9xF\xd9\ +\x00\x00\x04\xe0\x00\x00\x00\x00\x00\x01\x00\x008\xe4\ +\x00\x00\x01{\xe9xF\xe0\ +\x00\x00\x03 \x00\x00\x00\x00\x00\x01\x00\x00'R\ +\x00\x00\x01}\x0f$Y\x81\ +\x00\x00\x04\x14\x00\x00\x00\x00\x00\x01\x00\x003\xb8\ +\x00\x00\x01}\x0f$Y~\ +\x00\x00\x01\x92\x00\x00\x00\x00\x00\x01\x00\x00\x09X\ +\x00\x00\x01{\xe9xF\xdd\ +\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x00\xaa\ +\x00\x00\x01}\x0f$Y~\ +\x00\x00\x00\xdc\x00\x00\x00\x00\x00\x01\x00\x00\x06\xb3\ +\x00\x00\x01{\xe9xF\xda\ +\x00\x00\x01V\x00\x00\x00\x00\x00\x01\x00\x00\x08\xaf\ +\x00\x00\x01{\xe9xF\xd9\ +\x00\x00\x03\xea\x00\x00\x00\x00\x00\x01\x00\x003\x14\ +\x00\x00\x01{\xe9xF\xde\ +\x00\x00\x05`\x00\x00\x00\x00\x00\x01\x00\x00Ef\ +\x00\x00\x01{\xe9xF\xde\ +\x00\x00\x05\x04\x00\x00\x00\x00\x00\x01\x00\x009\x86\ +\x00\x00\x01{\xe9xF\xd7\ +\x00\x00\x014\x00\x00\x00\x00\x00\x01\x00\x00\x08\x06\ +\x00\x00\x01{\xe9xF\xda\ +\x00\x00\x02\xe6\x00\x00\x00\x00\x00\x01\x00\x00#O\ +\x00\x00\x01}\x0f$Y}\ +\x00\x00\x02\xbc\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x1b\ +\x00\x00\x01{\xe9xF\xd8\ +\x00\x00\x02\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x0c\x13\ +\x00\x00\x01{\xe9xF\xd8\ +\x00\x00\x04\x9a\x00\x00\x00\x00\x00\x01\x00\x007\x98\ +\x00\x00\x01{\xe9xF\xdf\ +\x00\x00\x04N\x00\x00\x00\x00\x00\x01\x00\x005\x98\ +\x00\x00\x01}\x0f$Y\x7f\ +\x00\x00\x052\x00\x00\x00\x00\x00\x01\x00\x00Ag\ +\x00\x00\x01}\x0f$Y|\ +\x00\x00\x05\xdc\x00\x00\x00\x00\x00\x01\x00\x00G\xef\ +\x00\x00\x01}\x0f$Y\x82\ +\x00\x00\x03\xaa\x00\x00\x00\x00\x00\x01\x00\x00.\xdd\ +\x00\x00\x01}\x0f$Y}\ +\x00\x00\x05\x96\x00\x00\x00\x00\x00\x01\x00\x00F\x0a\ +\x00\x00\x01}\x0f$Y\x80\ +\x00\x00\x06\x1a\x00\x00\x00\x00\x00\x01\x00\x00IJ\ +\x00\x00\x01}\x0f$Y\x81\ +\x00\x00\x02d\x00\x00\x00\x00\x00\x01\x00\x00\x13\xc7\ +\x00\x00\x01{\xe9xF\xd7\ +\x00\x00\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01{\xe9xF\xdc\ +\x00\x00\x03v\x00\x00\x00\x00\x00\x01\x00\x00.3\ +\x00\x00\x01{\xe9xF\xdb\ +\x00\x00\x03R\x00\x00\x00\x00\x00\x01\x00\x00(\xb1\ +\x00\x00\x01}\x0f$k\xb6\ +\x00\x00\x01\xe0\x00\x00\x00\x00\x00\x01\x00\x00\x0a\xa6\ +\x00\x00\x01}\x0f$Y\x82\ +\x00\x00\x02B\x00\x00\x00\x00\x00\x01\x00\x00\x13\x1d\ +\x00\x00\x01{\xe9xF\xdc\ +\x00\x00\x00\x96\x00\x00\x00\x00\x00\x01\x00\x00\x04\xc0\ +\x00\x00\x01}\x0f$Y\x80\ +\x00\x00\x02\x8c\x00\x00\x00\x00\x00\x01\x00\x00\x1bx\ +\x00\x00\x01{\xe9xF\xdf\ +" + + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) diff --git a/openpype/style/qrc_resources.py b/openpype/style/qrc_resources.py index beacb75f2cd..85f912228d2 100644 --- a/openpype/style/qrc_resources.py +++ b/openpype/style/qrc_resources.py @@ -3,7 +3,9 @@ initialized = False resources = None -if qtpy.API == "pyside2": +if qtpy.API == "pyside6": + from . import pyside6_resources as resources +elif qtpy.API == "pyside2": from . import pyside2_resources as resources elif qtpy.API == "pyqt5": from . import pyqt5_resources as resources From 1fdf261ab74e8e625dbc4e1e38fb891c624c21f8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 15:21:19 +0100 Subject: [PATCH 23/42] added ability to define qtbinding per platform --- pyproject.toml | 14 +- tools/fetch_thirdparty_libs.py | 293 ++++++++++++++++++--------------- 2 files changed, 170 insertions(+), 137 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 72193f732e6..c5a61991717 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -109,12 +109,20 @@ requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" [openpype] - -[openpype.pyside2] # note: in here we can use pip version specifiers as this is installed with pip until # Poetry will support custom location (-t flag for pip) # https://pip.pypa.io/en/stable/cli/pip_install/#requirement-specifiers -version = "==5.15.2" +[openpype.qtbinding.windows] +package = "PySide2" +version = "5.15.2" + +[openpype.qtbinding.darwin] +package = "PySide2" +version = "5.15.2" + +[openpype.qtbinding.linux] +package = "PySide2" +version = "5.15.2" # TODO: we will need to handle different linux flavours here and # also different macos versions too. diff --git a/tools/fetch_thirdparty_libs.py b/tools/fetch_thirdparty_libs.py index 421cc32dbd9..be9c271bf6f 100644 --- a/tools/fetch_thirdparty_libs.py +++ b/tools/fetch_thirdparty_libs.py @@ -64,139 +64,164 @@ def _print(msg: str, message_type: int = 0) -> None: else: header = term.darkolivegreen3("--- ") - print("{}{}".format(header, msg)) - -start_time = time.time_ns() -openpype_root = Path(os.path.dirname(__file__)).parent -pyproject = toml.load(openpype_root / "pyproject.toml") -_print("Handling PySide2 Qt framework ...") -pyside2_version = None -try: - pyside2_version = pyproject["openpype"]["pyside2"]["version"] - _print("We'll install PySide2{}".format(pyside2_version)) -except AttributeError: - _print("No PySide2 version was specified, using latest available.", 2) - -pyside2_arg = "PySide2" if not pyside2_version else "PySide2{}".format(pyside2_version) # noqa: E501 -python_vendor_dir = openpype_root / "vendor" / "python" -try: - subprocess.run( - [sys.executable, "-m", "pip", "install", "--upgrade", - pyside2_arg, "-t", str(python_vendor_dir)], - check=True, stdout=subprocess.DEVNULL) -except subprocess.CalledProcessError as e: - _print("Error during PySide2 installation.", 1) - _print(str(e), 1) - sys.exit(1) - -# Remove libraries for QtSql which don't have available libraries -# by default and Postgre library would require to modify rpath of dependency -platform_name = platform.system().lower() -if platform_name == "darwin": - pyside2_sqldrivers_dir = ( - python_vendor_dir / "PySide2" / "Qt" / "plugins" / "sqldrivers" - ) - for filepath in pyside2_sqldrivers_dir.iterdir(): - os.remove(str(filepath)) - -_print("Processing third-party dependencies ...") - -try: - thirdparty = pyproject["openpype"]["thirdparty"] -except AttributeError: - _print("No third-party libraries specified in pyproject.toml", 1) - sys.exit(1) - -for k, v in thirdparty.items(): - _print(f"processing {k}") - destination_path = openpype_root / "vendor" / "bin" / k - - - if not v.get(platform_name): - _print(("missing definition for current " - f"platform [ {platform_name} ]"), 2) - _print("trying to get universal url for all platforms") - url = v.get("url") - if not url: - _print("cannot get url", 1) - sys.exit(1) - else: - url = v.get(platform_name).get("url") - destination_path = destination_path / platform_name - - parsed_url = urlparse(url) - - # check if file is already extracted in /vendor/bin - if destination_path.exists(): - _print("destination path already exists, deleting ...", 2) - if destination_path.is_dir(): - try: - shutil.rmtree(destination_path) - except OSError as e: - _print("cannot delete folder.", 1) - raise SystemExit(e) - - # download file - _print(f"Downloading {url} ...") - with tempfile.TemporaryDirectory() as temp_dir: - temp_file = Path(temp_dir) / Path(parsed_url.path).name - - r = requests.get(url, stream=True) - content_len = int(r.headers.get('Content-Length', '0')) or None - with manager.counter(color='green', - total=content_len and math.ceil(content_len / 2 ** 20), # noqa: E501 - unit='MiB', leave=False) as counter: - with open(temp_file, 'wb', buffering=2 ** 24) as file_handle: - for chunk in r.iter_content(chunk_size=2 ** 20): - file_handle.write(chunk) - counter.update() - - # get file with checksum - _print("Calculating sha256 ...", 2) - calc_checksum = sha256_sum(temp_file) - - if v.get(platform_name): - item_hash = v.get(platform_name).get("hash") + print(f"{header}{msg}") + + +def install_qtbinding(pyproject, openpype_root, platform_name): + _print("Handling Qt binding framework ...") + qtbinding_def = pyproject["openpype"]["qtbinding"][platform_name] + package = qtbinding_def["package"] + version = qtbinding_def.get("version") + + qtbinding_arg = None + if package and version: + qtbinding_arg = f"{package}=={version}" + elif package: + qtbinding_arg = package + + if not qtbinding_arg: + _print("Didn't find Qt binding to install") + sys.exit(1) + + _print(f"We'll install {qtbinding_arg}") + + python_vendor_dir = openpype_root / "vendor" / "python" + try: + subprocess.run( + [ + sys.executable, + "-m", "pip", "install", "--upgrade", qtbinding_arg, + "-t", str(python_vendor_dir) + ], + check=True, + stdout=subprocess.DEVNULL + ) + except subprocess.CalledProcessError as e: + _print("Error during PySide2 installation.", 1) + _print(str(e), 1) + sys.exit(1) + + # Remove libraries for QtSql which don't have available libraries + # by default and Postgre library would require to modify rpath of + # dependency + if platform_name == "darwin": + sqldrivers_dir = ( + python_vendor_dir / package / "Qt" / "plugins" / "sqldrivers" + ) + for filepath in sqldrivers_dir.iterdir(): + os.remove(str(filepath)) + + +def install_thirdparty(pyproject, openpype_root, platform_name): + _print("Processing third-party dependencies ...") + try: + thirdparty = pyproject["openpype"]["thirdparty"] + except AttributeError: + _print("No third-party libraries specified in pyproject.toml", 1) + sys.exit(1) + + for k, v in thirdparty.items(): + _print(f"processing {k}") + destination_path = openpype_root / "vendor" / "bin" / k + + if not v.get(platform_name): + _print(("missing definition for current " + f"platform [ {platform_name} ]"), 2) + _print("trying to get universal url for all platforms") + url = v.get("url") + if not url: + _print("cannot get url", 1) + sys.exit(1) else: - item_hash = v.get("hash") - - if item_hash != calc_checksum: - _print("Downloaded files checksum invalid.") - sys.exit(1) - - _print("File OK", 3) - if not destination_path.exists(): - destination_path.mkdir(parents=True) - - # extract to destination - archive_type = temp_file.suffix.lstrip(".") - _print(f"Extracting {archive_type} file to {destination_path}") - if archive_type in ['zip']: - zip_file = zipfile.ZipFile(temp_file) - zip_file.extractall(destination_path) - zip_file.close() - - elif archive_type in [ - 'tar', 'tgz', 'tar.gz', 'tar.xz', 'tar.bz2' - ]: - if archive_type == 'tar': - tar_type = 'r:' - elif archive_type.endswith('xz'): - tar_type = 'r:xz' - elif archive_type.endswith('gz'): - tar_type = 'r:gz' - elif archive_type.endswith('bz2'): - tar_type = 'r:bz2' + url = v.get(platform_name).get("url") + destination_path = destination_path / platform_name + + parsed_url = urlparse(url) + + # check if file is already extracted in /vendor/bin + if destination_path.exists(): + _print("destination path already exists, deleting ...", 2) + if destination_path.is_dir(): + try: + shutil.rmtree(destination_path) + except OSError as e: + _print("cannot delete folder.", 1) + raise SystemExit(e) + + # download file + _print(f"Downloading {url} ...") + with tempfile.TemporaryDirectory() as temp_dir: + temp_file = Path(temp_dir) / Path(parsed_url.path).name + + r = requests.get(url, stream=True) + content_len = int(r.headers.get('Content-Length', '0')) or None + with manager.counter( + color='green', + total=content_len and math.ceil(content_len / 2 ** 20), + unit='MiB', leave=False) as counter: + with open(temp_file, 'wb', buffering=2 ** 24) as file_handle: + for chunk in r.iter_content(chunk_size=2 ** 20): + file_handle.write(chunk) + counter.update() + + # get file with checksum + _print("Calculating sha256 ...", 2) + calc_checksum = sha256_sum(temp_file) + + if v.get(platform_name): + item_hash = v.get(platform_name).get("hash") else: - tar_type = 'r:*' - try: - tar_file = tarfile.open(temp_file, tar_type) - except tarfile.ReadError: - raise SystemExit("corrupted archive") - tar_file.extractall(destination_path) - tar_file.close() - _print("Extraction OK", 3) - -end_time = time.time_ns() -total_time = (end_time - start_time) / 1000000000 -_print(f"Downloading and extracting took {total_time} secs.") + item_hash = v.get("hash") + + if item_hash != calc_checksum: + _print("Downloaded files checksum invalid.") + sys.exit(1) + + _print("File OK", 3) + if not destination_path.exists(): + destination_path.mkdir(parents=True) + + # extract to destination + archive_type = temp_file.suffix.lstrip(".") + _print(f"Extracting {archive_type} file to {destination_path}") + if archive_type in ['zip']: + zip_file = zipfile.ZipFile(temp_file) + zip_file.extractall(destination_path) + zip_file.close() + + elif archive_type in [ + 'tar', 'tgz', 'tar.gz', 'tar.xz', 'tar.bz2' + ]: + if archive_type == 'tar': + tar_type = 'r:' + elif archive_type.endswith('xz'): + tar_type = 'r:xz' + elif archive_type.endswith('gz'): + tar_type = 'r:gz' + elif archive_type.endswith('bz2'): + tar_type = 'r:bz2' + else: + tar_type = 'r:*' + try: + tar_file = tarfile.open(temp_file, tar_type) + except tarfile.ReadError: + raise SystemExit("corrupted archive") + tar_file.extractall(destination_path) + tar_file.close() + _print("Extraction OK", 3) + + +def main(): + start_time = time.time_ns() + openpype_root = Path(os.path.dirname(__file__)).parent + pyproject = toml.load(openpype_root / "pyproject.toml") + platform_name = platform.system().lower() + install_qtbinding(pyproject, openpype_root, platform_name) + install_thirdparty(pyproject, openpype_root, platform_name) + end_time = time.time_ns() + total_time = (end_time - start_time) / 1000000000 + _print(f"Downloading and extracting took {total_time} secs.") + + +if __name__ == "__main__": + main() From b5b8119f493fa302a37e280acd2872b529f9f500 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 15:54:46 +0100 Subject: [PATCH 24/42] use class attributes from classes --- openpype/tools/attribute_defs/files_widget.py | 8 ++--- openpype/tools/launcher/widgets.py | 2 +- .../publish_report_viewer/delegates.py | 6 ++-- .../publish_report_viewer/widgets.py | 14 +++++--- .../tools/publisher/widgets/assets_widget.py | 2 +- .../publisher/widgets/border_label_widget.py | 12 +++---- .../publisher/widgets/list_view_widgets.py | 6 ++-- .../publisher/widgets/overview_widget.py | 6 ++-- .../tools/publisher/widgets/publish_frame.py | 2 +- .../publisher/widgets/thumbnail_widget.py | 33 ++++++++++++------- openpype/tools/publisher/widgets/widgets.py | 14 ++++---- openpype/tools/utils/delegates.py | 7 ++-- openpype/tools/utils/tasks_widget.py | 2 +- openpype/tools/utils/widgets.py | 11 ++++--- openpype/vendor/python/common/qargparse.py | 6 ++-- 15 files changed, 75 insertions(+), 56 deletions(-) diff --git a/openpype/tools/attribute_defs/files_widget.py b/openpype/tools/attribute_defs/files_widget.py index 71714fdf161..067866035f1 100644 --- a/openpype/tools/attribute_defs/files_widget.py +++ b/openpype/tools/attribute_defs/files_widget.py @@ -599,14 +599,14 @@ class FilesView(QtWidgets.QListView): def __init__(self, *args, **kwargs): super(FilesView, self).__init__(*args, **kwargs) - self.setEditTriggers(QtWidgets.QListView.NoEditTriggers) + self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.setSelectionMode( QtWidgets.QAbstractItemView.ExtendedSelection ) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.setAcceptDrops(True) self.setDragEnabled(True) - self.setDragDropMode(self.InternalMove) + self.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove) remove_btn = InViewButton(self) pix_enabled = paint_image_with_color( @@ -616,7 +616,7 @@ def __init__(self, *args, **kwargs): get_image(filename="delete.png"), QtCore.Qt.gray ) icon = QtGui.QIcon(pix_enabled) - icon.addPixmap(pix_disabled, icon.Disabled, icon.Off) + icon.addPixmap(pix_disabled, QtGui.QIcon.Disabled, QtGui.QIcon.Off) remove_btn.setIcon(icon) remove_btn.setEnabled(False) @@ -734,7 +734,7 @@ def __init__(self, single_item, allow_sequences, extensions_label, parent): layout = QtWidgets.QStackedLayout(self) layout.setContentsMargins(0, 0, 0, 0) - layout.setStackingMode(layout.StackAll) + layout.setStackingMode(QtWidgets.QStackedLayout.StackAll) layout.addWidget(empty_widget) layout.addWidget(files_view) layout.setCurrentWidget(empty_widget) diff --git a/openpype/tools/launcher/widgets.py b/openpype/tools/launcher/widgets.py index 3eb641bdb33..81636c2206b 100644 --- a/openpype/tools/launcher/widgets.py +++ b/openpype/tools/launcher/widgets.py @@ -173,7 +173,7 @@ def __init__(self, launcher_model, dbcon, parent=None): view.setResizeMode(QtWidgets.QListView.Adjust) view.setSelectionMode(QtWidgets.QListView.NoSelection) view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - view.setEditTriggers(QtWidgets.QListView.NoEditTriggers) + view.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) view.setWrapping(True) view.setGridSize(QtCore.QSize(70, 75)) view.setIconSize(QtCore.QSize(30, 30)) diff --git a/openpype/tools/publisher/publish_report_viewer/delegates.py b/openpype/tools/publisher/publish_report_viewer/delegates.py index fc06b23900d..6cd0886e6bc 100644 --- a/openpype/tools/publisher/publish_report_viewer/delegates.py +++ b/openpype/tools/publisher/publish_report_viewer/delegates.py @@ -201,10 +201,10 @@ def item_paint(self, painter, option, index): style = QtWidgets.QApplicaion.style() style.proxy().drawPrimitive( - style.PE_PanelItemViewItem, option, painter, widget + QtWidgets.QStyle.PE_PanelItemViewItem, option, painter, widget ) _rect = style.proxy().subElementRect( - style.SE_ItemViewItemText, option, widget + QtWidgets.QStyle.SE_ItemViewItemText, option, widget ) bg_rect = QtCore.QRectF(option.rect) bg_rect.setY(_rect.y()) @@ -265,7 +265,7 @@ def group_item_paint(self, painter, option, index): else: style = QtWidgets.QApplicaion.style() _rect = style.proxy().subElementRect( - style.SE_ItemViewItemText, option, widget + QtWidgets.QStyle.SE_ItemViewItemText, option, widget ) bg_rect = QtCore.QRectF(option.rect) diff --git a/openpype/tools/publisher/publish_report_viewer/widgets.py b/openpype/tools/publisher/publish_report_viewer/widgets.py index 84af9bb1b86..dc449b6b69f 100644 --- a/openpype/tools/publisher/publish_report_viewer/widgets.py +++ b/openpype/tools/publisher/publish_report_viewer/widgets.py @@ -76,7 +76,7 @@ def __init__(self, parent): super(PluginLoadReportWidget, self).__init__(parent) view = QtWidgets.QTreeView(self) - view.setEditTriggers(view.NoEditTriggers) + view.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) view.setTextElideMode(QtCore.Qt.ElideLeft) view.setHeaderHidden(True) view.setAlternatingRowColors(True) @@ -372,8 +372,10 @@ def __init__(self, parent=None): instances_view.setModel(instances_proxy) instances_view.setIndentation(0) instances_view.setHeaderHidden(True) - instances_view.setEditTriggers(QtWidgets.QTreeView.NoEditTriggers) - instances_view.setSelectionMode(QtWidgets.QTreeView.ExtendedSelection) + instances_view.setEditTriggers( + QtWidgets.QAbstractItemView.NoEditTriggers) + instances_view.setSelectionMode( + QtWidgets.QAbstractItemView.ExtendedSelection) instances_view.setExpandsOnDoubleClick(False) instances_delegate = GroupItemDelegate(instances_view) @@ -393,8 +395,10 @@ def __init__(self, parent=None): plugins_view.setModel(plugins_proxy) plugins_view.setIndentation(0) plugins_view.setHeaderHidden(True) - plugins_view.setSelectionMode(QtWidgets.QTreeView.ExtendedSelection) - plugins_view.setEditTriggers(QtWidgets.QTreeView.NoEditTriggers) + plugins_view.setSelectionMode( + QtWidgets.QAbstractItemView.ExtendedSelection) + plugins_view.setEditTriggers( + QtWidgets.QAbstractItemView.NoEditTriggers) plugins_view.setExpandsOnDoubleClick(False) plugins_delegate = GroupItemDelegate(plugins_view) diff --git a/openpype/tools/publisher/widgets/assets_widget.py b/openpype/tools/publisher/widgets/assets_widget.py index 583e70ad5a9..402f8c2f9f0 100644 --- a/openpype/tools/publisher/widgets/assets_widget.py +++ b/openpype/tools/publisher/widgets/assets_widget.py @@ -193,7 +193,7 @@ def __init__(self, controller, parent): asset_view.setModel(proxy_model) asset_view.setHeaderHidden(True) asset_view.setFrameShape(QtWidgets.QFrame.NoFrame) - asset_view.setEditTriggers(QtWidgets.QTreeView.NoEditTriggers) + asset_view.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) asset_view.setAlternatingRowColors(True) asset_view.setSelectionBehavior(QtWidgets.QTreeView.SelectRows) asset_view.setAllColumnsShowFocus(True) diff --git a/openpype/tools/publisher/widgets/border_label_widget.py b/openpype/tools/publisher/widgets/border_label_widget.py index db575d7b906..5617e159cdc 100644 --- a/openpype/tools/publisher/widgets/border_label_widget.py +++ b/openpype/tools/publisher/widgets/border_label_widget.py @@ -29,8 +29,8 @@ def paintEvent(self, event): pos_x = self.width() painter = QtGui.QPainter(self) painter.setRenderHints( - painter.Antialiasing - | painter.SmoothPixmapTransform + QtGui.QPainter.Antialiasing + | QtGui.QPainter.SmoothPixmapTransform ) if self._color: pen = QtGui.QPen(self._color) @@ -73,8 +73,8 @@ def paintEvent(self, event): ) painter = QtGui.QPainter(self) painter.setRenderHints( - painter.Antialiasing - | painter.SmoothPixmapTransform + QtGui.QPainter.Antialiasing + | QtGui.QPainter.SmoothPixmapTransform ) if self._color: pen = QtGui.QPen(self._color) @@ -131,8 +131,8 @@ def paintEvent(self, event): painter = QtGui.QPainter(self) painter.setRenderHints( - painter.Antialiasing - | painter.SmoothPixmapTransform + QtGui.QPainter.Antialiasing + | QtGui.QPainter.SmoothPixmapTransform ) if self._color: pen = QtGui.QPen(self._color) diff --git a/openpype/tools/publisher/widgets/list_view_widgets.py b/openpype/tools/publisher/widgets/list_view_widgets.py index 28feeee7aa8..e6dad48b67d 100644 --- a/openpype/tools/publisher/widgets/list_view_widgets.py +++ b/openpype/tools/publisher/widgets/list_view_widgets.py @@ -86,9 +86,9 @@ def group_item_paint(self, painter, option, index): painter.save() painter.setRenderHints( - painter.Antialiasing - | painter.SmoothPixmapTransform - | painter.TextAntialiasing + QtGui.QPainter.Antialiasing + | QtGui.QPainter.SmoothPixmapTransform + | QtGui.QPainter.TextAntialiasing ) # Draw backgrounds diff --git a/openpype/tools/publisher/widgets/overview_widget.py b/openpype/tools/publisher/widgets/overview_widget.py index 2566806228c..022de2dc342 100644 --- a/openpype/tools/publisher/widgets/overview_widget.py +++ b/openpype/tools/publisher/widgets/overview_widget.py @@ -172,7 +172,7 @@ def set_state(self, new_state, animate): self._current_state = new_state anim_is_running = ( - self._change_anim.state() == self._change_anim.Running + self._change_anim.state() == QtCore.QAbstractAnimation.Running ) if not animate: self._change_visibility_for_state() @@ -184,9 +184,9 @@ def set_state(self, new_state, animate): self._max_widget_width = self._subset_views_widget.maximumWidth() if new_state == "create": - direction = self._change_anim.Backward + direction = QtCore.QAbstractAnimation.Backward else: - direction = self._change_anim.Forward + direction = QtCore.QAbstractAnimation.Forward self._change_anim.setDirection(direction) if not anim_is_running: diff --git a/openpype/tools/publisher/widgets/publish_frame.py b/openpype/tools/publisher/widgets/publish_frame.py index fe349e52a60..e4e67405329 100644 --- a/openpype/tools/publisher/widgets/publish_frame.py +++ b/openpype/tools/publisher/widgets/publish_frame.py @@ -230,7 +230,7 @@ def set_shrunk_state(self, shrunk): self._shrunken = shrunk anim_is_running = ( - self._shrunk_anim.state() == self._shrunk_anim.Running + self._shrunk_anim.state() == QtCore.QAbstractAnimation.Running ) if not self.isVisible(): if anim_is_running: diff --git a/openpype/tools/publisher/widgets/thumbnail_widget.py b/openpype/tools/publisher/widgets/thumbnail_widget.py index 07423d47648..e234f4cdc13 100644 --- a/openpype/tools/publisher/widgets/thumbnail_widget.py +++ b/openpype/tools/publisher/widgets/thumbnail_widget.py @@ -126,11 +126,14 @@ def _paint_default_pix(self, pix_width, pix_height): new_pix.fill(QtCore.Qt.transparent) pix_painter = QtGui.QPainter() pix_painter.begin(new_pix) - pix_painter.setRenderHints( - pix_painter.Antialiasing - | pix_painter.SmoothPixmapTransform - | pix_painter.HighQualityAntialiasing + render_hints = ( + QtGui.QPainter.Antialiasing + | QtGui.QPainter.SmoothPixmapTransform ) + if hasattr(QtGui.QPainter, "HighQualityAntialiasing"): + render_hints |= QtGui.QPainter.HighQualityAntialiasing + + pix_painter.setRenderHints(render_hints) pix_painter.drawPixmap(pos_x, pos_y, scaled_pix) pix_painter.end() return new_pix @@ -159,11 +162,13 @@ def _draw_thumbnails(self, thumbnails, pix_width, pix_height): new_pix.fill(QtCore.Qt.transparent) pix_painter = QtGui.QPainter() pix_painter.begin(new_pix) - pix_painter.setRenderHints( - pix_painter.Antialiasing - | pix_painter.SmoothPixmapTransform - | pix_painter.HighQualityAntialiasing + render_hints = ( + QtGui.QPainter.Antialiasing + | QtGui.QPainter.SmoothPixmapTransform ) + if hasattr(QtGui.QPainter, "HighQualityAntialiasing"): + render_hints |= QtGui.QPainter.HighQualityAntialiasing + pix_painter.setRenderHints(render_hints) tiled_rect = QtCore.QRectF( pos_x, pos_y, scaled_pix.width(), scaled_pix.height() @@ -239,11 +244,15 @@ def _cache_pix(self): final_painter = QtGui.QPainter() final_painter.begin(final_pix) - final_painter.setRenderHints( - final_painter.Antialiasing - | final_painter.SmoothPixmapTransform - | final_painter.HighQualityAntialiasing + render_hints = ( + QtGui.QPainter.Antialiasing + | QtGui.QPainter.SmoothPixmapTransform ) + if hasattr(QtGui.QPainter, "HighQualityAntialiasing"): + render_hints |= QtGui.QPainter.HighQualityAntialiasing + + final_painter.setRenderHints(render_hints) + final_painter.setBrush(QtGui.QBrush(self.thumbnail_bg_color)) final_painter.setPen(bg_pen) final_painter.drawRect(rect) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index f65d0302c53..2e8d0ce37cd 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -143,9 +143,9 @@ def generate_icon(self, pixmap_path, enabled_color, disabled_color): icon = QtGui.QIcon() image = QtGui.QImage(pixmap_path) enabled_pixmap = self.paint_image_with_color(image, enabled_color) - icon.addPixmap(enabled_pixmap, icon.Normal) + icon.addPixmap(enabled_pixmap, QtGui.QIcon.Normal) disabled_pixmap = self.paint_image_with_color(image, disabled_color) - icon.addPixmap(disabled_pixmap, icon.Disabled) + icon.addPixmap(disabled_pixmap, QtGui.QIcon.Disabled) return icon @staticmethod @@ -1779,11 +1779,11 @@ def set_increasing(self, increasing): return self._increasing = increasing if increasing: - self._change_anim.setDirection(self._change_anim.Forward) + self._change_anim.setDirection(QtCore.QAbstractAnimation.Forward) else: - self._change_anim.setDirection(self._change_anim.Backward) + self._change_anim.setDirection(QtCore.QAbstractAnimation.Backward) - if self._change_anim.state() != self._change_anim.Running: + if self._change_anim.state() != QtCore.QAbstractAnimation.Running: self._change_anim.start() def set_visible(self, visible): @@ -1857,8 +1857,8 @@ def paintEvent(self, event): painter.setClipRect(event.rect()) painter.setRenderHints( - painter.Antialiasing - | painter.SmoothPixmapTransform + QtGui.QPainter.Antialiasing + | QtGui.QPainter.SmoothPixmapTransform ) painter.setPen(QtCore.Qt.NoPen) diff --git a/openpype/tools/utils/delegates.py b/openpype/tools/utils/delegates.py index 17479488003..604df689c48 100644 --- a/openpype/tools/utils/delegates.py +++ b/openpype/tools/utils/delegates.py @@ -66,9 +66,12 @@ def paint(self, painter, option, index): pen.setColor(fg_color) painter.setPen(pen) - text_rect = style.subElementRect(style.SE_ItemViewItemText, option) + text_rect = style.subElementRect( + QtWidgets.QStyle.SE_ItemViewItemText, + option + ) text_margin = style.proxy().pixelMetric( - style.PM_FocusFrameHMargin, option, option.widget + QtWidgets.QStyle.PM_FocusFrameHMargin, option, option.widget ) + 1 painter.drawText( diff --git a/openpype/tools/utils/tasks_widget.py b/openpype/tools/utils/tasks_widget.py index b0ddedcb6e1..8c0505223e3 100644 --- a/openpype/tools/utils/tasks_widget.py +++ b/openpype/tools/utils/tasks_widget.py @@ -180,7 +180,7 @@ def __init__(self, dbcon, parent=None): tasks_view = DeselectableTreeView(self) tasks_view.setIndentation(0) tasks_view.setSortingEnabled(True) - tasks_view.setEditTriggers(QtWidgets.QTreeView.NoEditTriggers) + tasks_view.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) header_view = tasks_view.header() header_view.setSortIndicator(0, QtCore.Qt.AscendingOrder) diff --git a/openpype/tools/utils/widgets.py b/openpype/tools/utils/widgets.py index c64b6e3400d..a9d6fa35b26 100644 --- a/openpype/tools/utils/widgets.py +++ b/openpype/tools/utils/widgets.py @@ -283,11 +283,14 @@ def paintEvent(self, event): painter.end() return - painter.setRenderHints( - painter.Antialiasing - | painter.SmoothPixmapTransform - | painter.HighQualityAntialiasing + render_hints = ( + QtGui.QPainter.Antialiasing + | QtGui.QPainter.SmoothPixmapTransform ) + if hasattr(QtGui.QPainter, "HighQualityAntialiasing"): + render_hints |= QtGui.QPainter.HighQualityAntialiasing + + painter.setRenderHints(render_hints) if self._cached_pixmap is None: self._cache_pixmap() diff --git a/openpype/vendor/python/common/qargparse.py b/openpype/vendor/python/common/qargparse.py index 172c594d1dd..17cf493a898 100644 --- a/openpype/vendor/python/common/qargparse.py +++ b/openpype/vendor/python/common/qargparse.py @@ -570,7 +570,7 @@ def data(self, index, role): model = QtCore.QStringListModel(self["default"]) widget = QtWidgets.QListView() widget.setModel(model) - widget.setEditTriggers(widget.NoEditTriggers) + widget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self._read = lambda: model.stringList() self._write = lambda value: model.setStringList(value) @@ -640,8 +640,8 @@ def reset(items, default=None): model = QtCore.QStringListModel() widget = QtWidgets.QListView() widget.setModel(model) - widget.setEditTriggers(widget.NoEditTriggers) - widget.setSelectionMode(widget.SingleSelection) + widget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + widget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) smodel = widget.selectionModel() smodel.selectionChanged.connect(on_changed) From 940cb35e0d2f56feec5eefd7de81005971456307 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 15:55:05 +0100 Subject: [PATCH 25/42] fix usage of filteregexp --- openpype/tools/sceneinventory/model.py | 9 +++++++-- openpype/tools/settings/settings/search_dialog.py | 9 +++++++-- .../widgets/model_filter_proxy_recursive_sort.py | 11 ++++++----- openpype/tools/utils/models.py | 9 +++++++-- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/openpype/tools/sceneinventory/model.py b/openpype/tools/sceneinventory/model.py index 9b45ed6cc1b..3398743aec5 100644 --- a/openpype/tools/sceneinventory/model.py +++ b/openpype/tools/sceneinventory/model.py @@ -482,8 +482,13 @@ def filterAcceptsRow(self, row, parent): return True # Filter by regex - if not self.filterRegExp().isEmpty(): - pattern = re.escape(self.filterRegExp().pattern()) + if hasattr(self, "filterRegularExpression"): + regex = self.filterRegularExpression() + else: + regex = self.filterRegExp() + pattern = regex.pattern() + if pattern: + pattern = re.escape(pattern) if not self._matches(row, parent, pattern): return False diff --git a/openpype/tools/settings/settings/search_dialog.py b/openpype/tools/settings/settings/search_dialog.py index 71d258febea..33a4d16e982 100644 --- a/openpype/tools/settings/settings/search_dialog.py +++ b/openpype/tools/settings/settings/search_dialog.py @@ -27,8 +27,13 @@ def filterAcceptsRow(self, row, parent): if not parent.isValid(): return False - regex = self.filterRegExp() - if not regex.isEmpty() and regex.isValid(): + if hasattr(self, "filterRegularExpression"): + regex = self.filterRegularExpression() + else: + regex = self.filterRegExp() + + pattern = regex.pattern() + if pattern and regex.isValid(): pattern = regex.pattern() compiled_regex = re.compile(pattern, re.IGNORECASE) source_model = self.sourceModel() diff --git a/openpype/tools/standalonepublish/widgets/model_filter_proxy_recursive_sort.py b/openpype/tools/standalonepublish/widgets/model_filter_proxy_recursive_sort.py index 727d3a97d70..5c72e2049b9 100644 --- a/openpype/tools/standalonepublish/widgets/model_filter_proxy_recursive_sort.py +++ b/openpype/tools/standalonepublish/widgets/model_filter_proxy_recursive_sort.py @@ -5,14 +5,15 @@ class RecursiveSortFilterProxyModel(QtCore.QSortFilterProxyModel): """Filters to the regex if any of the children matches allow parent""" def filterAcceptsRow(self, row, parent): - - regex = self.filterRegExp() - if not regex.isEmpty(): - pattern = regex.pattern() + if hasattr(self, "filterRegularExpression"): + regex = self.filterRegularExpression() + else: + regex = self.filterRegExp() + pattern = regex.pattern() + if pattern: model = self.sourceModel() source_index = model.index(row, self.filterKeyColumn(), parent) if source_index.isValid(): - # Check current index itself key = model.data(source_index, self.filterRole()) if re.search(pattern, key, re.IGNORECASE): diff --git a/openpype/tools/utils/models.py b/openpype/tools/utils/models.py index b26ec566fee..270e00b2ef8 100644 --- a/openpype/tools/utils/models.py +++ b/openpype/tools/utils/models.py @@ -203,8 +203,13 @@ class RecursiveSortFilterProxyModel(QtCore.QSortFilterProxyModel): the filter string but first checks if any children does. """ def filterAcceptsRow(self, row, parent_index): - regex = self.filterRegExp() - if not regex.isEmpty(): + if hasattr(self, "filterRegularExpression"): + regex = self.filterRegularExpression() + else: + regex = self.filterRegExp() + + pattern = regex.pattern() + if pattern: model = self.sourceModel() source_index = model.index( row, self.filterKeyColumn(), parent_index From 7ce1dfb2c803d861a0f2f2fb60842cb89c2f61f9 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 15:55:17 +0100 Subject: [PATCH 26/42] fix center window 'maybe' --- openpype/tools/utils/lib.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/openpype/tools/utils/lib.py b/openpype/tools/utils/lib.py index ae9c5bc96c5..fb5530b100d 100644 --- a/openpype/tools/utils/lib.py +++ b/openpype/tools/utils/lib.py @@ -25,9 +25,15 @@ def center_window(window): """Move window to center of it's screen.""" - desktop = QtWidgets.QApplication.desktop() - screen_idx = desktop.screenNumber(window) - screen_geo = desktop.screenGeometry(screen_idx) + + if hasattr(QtWidgets.QApplication, "desktop"): + desktop = QtWidgets.QApplication.desktop() + screen_idx = desktop.screenNumber(window) + screen_geo = desktop.screenGeometry(screen_idx) + else: + screen = window.screen() + screen_geo = screen.geometry() + geo = window.frameGeometry() geo.moveCenter(screen_geo.center()) if geo.y() < screen_geo.y(): From dd8a7e565343a59d8a5b8479d3fb969fd4177c94 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 15:55:27 +0100 Subject: [PATCH 27/42] fix usage of qtpy in assets widget --- openpype/tools/utils/assets_widget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/utils/assets_widget.py b/openpype/tools/utils/assets_widget.py index f33a412a7bb..8a7511e6c5a 100644 --- a/openpype/tools/utils/assets_widget.py +++ b/openpype/tools/utils/assets_widget.py @@ -136,7 +136,7 @@ def sizeHint(self, option, index): def paint(self, painter, option, index): """Replicate painting of an item and draw color bars if needed.""" # Qt4 compat - if Qt.__binding__ in ("PySide", "PyQt4"): + if qtpy.API in ("pyside", "pyqt4"): option = QStyleOptionViewItemV4(option) painter.save() From fd611bdae7ad639ddb0d3a641cab04bcbde208db Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Dec 2022 16:01:51 +0100 Subject: [PATCH 28/42] changed PySide2 to PySide2 in pyproject toml --- pyproject.toml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c5a61991717..cdf0a5cd972 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -113,16 +113,16 @@ build-backend = "poetry.core.masonry.api" # Poetry will support custom location (-t flag for pip) # https://pip.pypa.io/en/stable/cli/pip_install/#requirement-specifiers [openpype.qtbinding.windows] -package = "PySide2" -version = "5.15.2" +package = "PySide6" +version = "6.4.1" [openpype.qtbinding.darwin] -package = "PySide2" -version = "5.15.2" +package = "PySide6" +version = "6.4.1" [openpype.qtbinding.linux] -package = "PySide2" -version = "5.15.2" +package = "PySide6" +version = "6.4.1" # TODO: we will need to handle different linux flavours here and # also different macos versions too. From 0aa011184b7a07d71225ba2898c4412a37d7af43 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 6 Jan 2023 17:38:06 +0100 Subject: [PATCH 29/42] fix checked int for pyside6 --- openpype/tools/loader/widgets.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 8d58e822307..f222b3e9822 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -67,6 +67,8 @@ REMOTE_AVAILABILITY_ROLE ) +CHECKED_INT = getattr(QtCore.Qt.Checked, "value", 2) + class OverlayFrame(QtWidgets.QFrame): def __init__(self, label, parent): @@ -1066,7 +1068,9 @@ def get_enabled_families(self): checked_families = [] for row in range(model.rowCount()): index = model.index(row, 0) - if index.data(QtCore.Qt.CheckStateRole) == QtCore.Qt.Checked: + if index.data(QtCore.Qt.CheckStateRole) in ( + QtCore.Qt.Checked, CHECKED_INT + ): family = index.data(QtCore.Qt.DisplayRole) checked_families.append(family) From 679becc3a85b2f30e87a8a745c33fcbaa6dd8f95 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 6 Jan 2023 18:51:51 +0100 Subject: [PATCH 30/42] fix work with checkstate constants --- openpype/tools/loader/widgets.py | 30 ++++++++++--------- .../multiselection_combobox.py | 14 +++++++-- .../publisher/widgets/list_view_widgets.py | 7 +++-- .../settings/multiselection_combobox.py | 13 ++++++-- openpype/tools/utils/constants.py | 4 +++ openpype/tools/utils/lib.py | 24 +++++++++++++++ openpype/widgets/nice_checkbox.py | 22 +++++++++++++- 7 files changed, 91 insertions(+), 23 deletions(-) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index f222b3e9822..6181fd63f01 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -35,6 +35,7 @@ ErrorMessageBox, lib as tools_lib ) +from openpype.tools.utils.lib import checkstate_int_to_enum from openpype.tools.utils.delegates import ( VersionDelegate, PrettyTimeDelegate @@ -47,6 +48,13 @@ TreeViewSpinner, DeselectableTreeView ) +from openpype.tools.utils.constants import ( + LOCAL_PROVIDER_ROLE, + REMOTE_PROVIDER_ROLE, + LOCAL_AVAILABILITY_ROLE, + REMOTE_AVAILABILITY_ROLE, + CHECKED_INT, +) from openpype.tools.assetlinks.widgets import SimpleLinkView from .model import ( @@ -60,15 +68,6 @@ from . import lib from .delegates import LoadedInSceneDelegate -from openpype.tools.utils.constants import ( - LOCAL_PROVIDER_ROLE, - REMOTE_PROVIDER_ROLE, - LOCAL_AVAILABILITY_ROLE, - REMOTE_AVAILABILITY_ROLE -) - -CHECKED_INT = getattr(QtCore.Qt.Checked, "value", 2) - class OverlayFrame(QtWidgets.QFrame): def __init__(self, label, parent): @@ -1068,9 +1067,10 @@ def get_enabled_families(self): checked_families = [] for row in range(model.rowCount()): index = model.index(row, 0) - if index.data(QtCore.Qt.CheckStateRole) in ( - QtCore.Qt.Checked, CHECKED_INT - ): + checked = checkstate_int_to_enum( + index.data(QtCore.Qt.CheckStateRole) + ) + if checked == QtCore.Qt.Checked: family = index.data(QtCore.Qt.DisplayRole) checked_families.append(family) @@ -1104,13 +1104,15 @@ def _set_checkstates(self, checked, indexes): self.blockSignals(True) for index in indexes: - index_state = index.data(QtCore.Qt.CheckStateRole) + index_state = checkstate_int_to_enum( + index.data(QtCore.Qt.CheckStateRole) + ) if index_state == state: continue new_state = state if new_state is None: - if index_state == QtCore.Qt.Checked: + if index_state in QtCore.Qt.Checked: new_state = QtCore.Qt.Unchecked else: new_state = QtCore.Qt.Checked diff --git a/openpype/tools/project_manager/project_manager/multiselection_combobox.py b/openpype/tools/project_manager/project_manager/multiselection_combobox.py index f12f402d1ad..4b5d4689829 100644 --- a/openpype/tools/project_manager/project_manager/multiselection_combobox.py +++ b/openpype/tools/project_manager/project_manager/multiselection_combobox.py @@ -1,5 +1,7 @@ from qtpy import QtCore, QtWidgets +from openpype.tools.utils.lib import checkstate_int_to_enum + class ComboItemDelegate(QtWidgets.QStyledItemDelegate): """ @@ -87,7 +89,9 @@ def _event_popup_shown(self, obj, event): return index_flags = current_index.flags() - state = current_index.data(QtCore.Qt.CheckStateRole) + state = checkstate_int_to_enum( + current_index.data(QtCore.Qt.CheckStateRole) + ) new_state = None if event.type() == QtCore.QEvent.MouseButtonRelease: @@ -184,7 +188,9 @@ def set_value(self, values): def value(self): items = list() for idx in range(self.count()): - state = self.itemData(idx, role=QtCore.Qt.CheckStateRole) + state = checkstate_int_to_enum( + self.itemData(idx, role=QtCore.Qt.CheckStateRole) + ) if state == QtCore.Qt.Checked: items.append( self.itemData(idx, role=QtCore.Qt.UserRole) @@ -194,7 +200,9 @@ def value(self): def checked_items_text(self): items = list() for idx in range(self.count()): - state = self.itemData(idx, role=QtCore.Qt.CheckStateRole) + state = checkstate_int_to_enum( + self.itemData(idx, role=QtCore.Qt.CheckStateRole) + ) if state == QtCore.Qt.Checked: items.append(self.itemText(idx)) return items diff --git a/openpype/tools/publisher/widgets/list_view_widgets.py b/openpype/tools/publisher/widgets/list_view_widgets.py index e6dad48b67d..172563d15cc 100644 --- a/openpype/tools/publisher/widgets/list_view_widgets.py +++ b/openpype/tools/publisher/widgets/list_view_widgets.py @@ -28,7 +28,7 @@ from openpype.style import get_objected_colors from openpype.widgets.nice_checkbox import NiceCheckbox -from openpype.tools.utils.lib import html_escape +from openpype.tools.utils.lib import html_escape, checkstate_int_to_enum from .widgets import AbstractInstanceView from ..constants import ( INSTANCE_ID_ROLE, @@ -272,6 +272,7 @@ def set_checkstate(self, state): state(QtCore.Qt.CheckState): Checkstate of checkbox. Have 3 variants Unchecked, Checked and PartiallyChecked. """ + if self.checkstate() == state: return self._ignore_state_change = True @@ -279,7 +280,8 @@ def set_checkstate(self, state): self._ignore_state_change = False def checkstate(self): - """CUrrent checkstate of "active" checkbox.""" + """Current checkstate of "active" checkbox.""" + return self.toggle_checkbox.checkState() def _on_checkbox_change(self, state): @@ -887,6 +889,7 @@ def _on_convertor_group_expand_request(self, _, expanded): self._instance_view.setExpanded(proxy_index, expanded) def _on_group_toggle_request(self, group_name, state): + state = checkstate_int_to_enum(state) if state == QtCore.Qt.PartiallyChecked: return diff --git a/openpype/tools/settings/settings/multiselection_combobox.py b/openpype/tools/settings/settings/multiselection_combobox.py index 4cc81ff56e7..896be3c06ce 100644 --- a/openpype/tools/settings/settings/multiselection_combobox.py +++ b/openpype/tools/settings/settings/multiselection_combobox.py @@ -1,4 +1,5 @@ from qtpy import QtCore, QtGui, QtWidgets +from openpype.tools.utils.lib import checkstate_int_to_enum class ComboItemDelegate(QtWidgets.QStyledItemDelegate): @@ -108,7 +109,9 @@ def _event_popup_shown(self, obj, event): return index_flags = current_index.flags() - state = current_index.data(QtCore.Qt.CheckStateRole) + state = checkstate_int_to_enum( + current_index.data(QtCore.Qt.CheckStateRole) + ) new_state = None if event.type() == QtCore.QEvent.MouseButtonRelease: @@ -311,7 +314,9 @@ def set_value(self, values): def value(self): items = list() for idx in range(self.count()): - state = self.itemData(idx, role=QtCore.Qt.CheckStateRole) + state = checkstate_int_to_enum( + self.itemData(idx, role=QtCore.Qt.CheckStateRole) + ) if state == QtCore.Qt.Checked: items.append( self.itemData(idx, role=QtCore.Qt.UserRole) @@ -321,7 +326,9 @@ def value(self): def checked_items_text(self): items = list() for idx in range(self.count()): - state = self.itemData(idx, role=QtCore.Qt.CheckStateRole) + state = checkstate_int_to_enum( + self.itemData(idx, role=QtCore.Qt.CheckStateRole) + ) if state == QtCore.Qt.Checked: items.append(self.itemText(idx)) return items diff --git a/openpype/tools/utils/constants.py b/openpype/tools/utils/constants.py index a3b1557f264..99f2602ee3b 100644 --- a/openpype/tools/utils/constants.py +++ b/openpype/tools/utils/constants.py @@ -1,6 +1,10 @@ from qtpy import QtCore +UNCHECKED_INT = getattr(QtCore.Qt.Unchecked, "value", 0) +PARTIALLY_CHECKED_INT = getattr(QtCore.Qt.PartiallyChecked, "value", 1) +CHECKED_INT = getattr(QtCore.Qt.Checked, "value", 2) + DEFAULT_PROJECT_LABEL = "< Default >" PROJECT_NAME_ROLE = QtCore.Qt.UserRole + 101 PROJECT_IS_ACTIVE_ROLE = QtCore.Qt.UserRole + 102 diff --git a/openpype/tools/utils/lib.py b/openpype/tools/utils/lib.py index fb5530b100d..3f7293d4702 100644 --- a/openpype/tools/utils/lib.py +++ b/openpype/tools/utils/lib.py @@ -20,9 +20,33 @@ from openpype.settings import get_project_settings from openpype.pipeline import registered_host +from .constants import CHECKED_INT, UNCHECKED_INT + log = Logger.get_logger(__name__) +def checkstate_int_to_enum(state): + if not isinstance(state, int): + return state + if state == CHECKED_INT: + return QtCore.Qt.Checked + + if state == UNCHECKED_INT: + return QtCore.Qt.Unchecked + return QtCore.Qt.PartiallyChecked + + +def checkstate_enum_to_int(state): + if isinstance(state, int): + return state + if state == QtCore.Qt.Checked: + return 0 + if state == QtCore.Qt.PartiallyChecked: + return 1 + return 2 + + + def center_window(window): """Move window to center of it's screen.""" diff --git a/openpype/widgets/nice_checkbox.py b/openpype/widgets/nice_checkbox.py index d28a09a5dc2..651187a8ab0 100644 --- a/openpype/widgets/nice_checkbox.py +++ b/openpype/widgets/nice_checkbox.py @@ -166,7 +166,27 @@ def checkState(self): def isChecked(self): return self._checked + def _checkstate_int_to_enum(self, state): + if not isinstance(state, int): + return state + + if state == 2: + return QtCore.Qt.Checked + if state == 1: + return QtCore.Qt.PartiallyChecked + return QtCore.Qt.Unchecked + + def _checkstate_enum_to_int(self, state): + if isinstance(state, int): + return state + if state == QtCore.Qt.Checked: + return 2 + if state == QtCore.Qt.PartiallyChecked: + return 1 + return 0 + def setCheckState(self, state): + state = self._checkstate_int_to_enum(state) if self._checkstate == state: return @@ -176,7 +196,7 @@ def setCheckState(self, state): elif state == QtCore.Qt.Unchecked: self._checked = False - self.stateChanged.emit(self.checkState()) + self.stateChanged.emit(self._checkstate_enum_to_int(self.checkState())) if self._animation_timer.isActive(): self._animation_timer.stop() From 77df80aa8394c9e68573847ae896e5a2fe9dae38 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 6 Jan 2023 18:59:32 +0100 Subject: [PATCH 31/42] removed unused import --- openpype/tools/loader/widgets.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 6181fd63f01..0885a024a3d 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -53,7 +53,6 @@ REMOTE_PROVIDER_ROLE, LOCAL_AVAILABILITY_ROLE, REMOTE_AVAILABILITY_ROLE, - CHECKED_INT, ) from openpype.tools.assetlinks.widgets import SimpleLinkView From aaf9be080ad337622c2ee166bf89bb11251e1324 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 9 Jan 2023 11:57:44 +0100 Subject: [PATCH 32/42] keep Pyside6 only for macos --- pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cdf0a5cd972..991c2ef7ed3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -113,16 +113,16 @@ build-backend = "poetry.core.masonry.api" # Poetry will support custom location (-t flag for pip) # https://pip.pypa.io/en/stable/cli/pip_install/#requirement-specifiers [openpype.qtbinding.windows] -package = "PySide6" -version = "6.4.1" +package = "PySide2" +version = "5.15.2" [openpype.qtbinding.darwin] package = "PySide6" version = "6.4.1" [openpype.qtbinding.linux] -package = "PySide6" -version = "6.4.1" +package = "PySide2" +version = "5.15.2" # TODO: we will need to handle different linux flavours here and # also different macos versions too. From bc61b450db090aa9620648aa95051c27fac13d45 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 16 Jan 2023 11:19:24 +0100 Subject: [PATCH 33/42] use right constants --- openpype/tools/launcher/widgets.py | 2 +- openpype/tools/mayalookassigner/views.py | 2 +- openpype/tools/project_manager/project_manager/view.py | 4 ++-- openpype/tools/publisher/widgets/validations_widget.py | 2 +- openpype/tools/sceneinventory/view.py | 2 +- openpype/tools/utils/assets_widget.py | 4 +++- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/openpype/tools/launcher/widgets.py b/openpype/tools/launcher/widgets.py index 81636c2206b..a5bdd616b1b 100644 --- a/openpype/tools/launcher/widgets.py +++ b/openpype/tools/launcher/widgets.py @@ -423,7 +423,7 @@ def show_history(self): return widget = QtWidgets.QListWidget() - widget.setSelectionMode(widget.NoSelection) + widget.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) widget.setStyleSheet(""" * { font-family: "Courier New"; diff --git a/openpype/tools/mayalookassigner/views.py b/openpype/tools/mayalookassigner/views.py index 87459ad897c..489c194f600 100644 --- a/openpype/tools/mayalookassigner/views.py +++ b/openpype/tools/mayalookassigner/views.py @@ -10,7 +10,7 @@ def __init__(self, parent=None): # view settings self.setAlternatingRowColors(False) self.setSortingEnabled(True) - self.setSelectionMode(self.ExtendedSelection) + self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) def get_indices(self): diff --git a/openpype/tools/project_manager/project_manager/view.py b/openpype/tools/project_manager/project_manager/view.py index 609db30a817..fa08943ea53 100644 --- a/openpype/tools/project_manager/project_manager/view.py +++ b/openpype/tools/project_manager/project_manager/view.py @@ -134,9 +134,9 @@ def __init__(self, dbcon, source_model, parent): main_delegate = QtWidgets.QStyledItemDelegate() self.setItemDelegate(main_delegate) self.setAlternatingRowColors(True) - self.setSelectionMode(HierarchyView.ExtendedSelection) + self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - self.setEditTriggers(HierarchyView.AllEditTriggers) + self.setEditTriggers(QtWidgets.QAbstractItemView.AllEditTriggers) column_delegates = {} column_key_to_index = {} diff --git a/openpype/tools/publisher/widgets/validations_widget.py b/openpype/tools/publisher/widgets/validations_widget.py index c5b5a00883e..84ec2c067ac 100644 --- a/openpype/tools/publisher/widgets/validations_widget.py +++ b/openpype/tools/publisher/widgets/validations_widget.py @@ -26,7 +26,7 @@ def __init__(self, *args, **kwargs): self.setObjectName("ValidationErrorInstanceList") self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - self.setSelectionMode(QtWidgets.QListView.ExtendedSelection) + self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) def minimumSizeHint(self): return self.sizeHint() diff --git a/openpype/tools/sceneinventory/view.py b/openpype/tools/sceneinventory/view.py index 183bf2362bb..3c4e03a195e 100644 --- a/openpype/tools/sceneinventory/view.py +++ b/openpype/tools/sceneinventory/view.py @@ -48,7 +48,7 @@ def __init__(self, parent=None): self.setIndentation(12) self.setAlternatingRowColors(True) self.setSortingEnabled(True) - self.setSelectionMode(self.ExtendedSelection) + self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.customContextMenuRequested.connect(self._show_right_mouse_menu) self._hierarchy_view = False diff --git a/openpype/tools/utils/assets_widget.py b/openpype/tools/utils/assets_widget.py index 8a7511e6c5a..ffbdd995d6f 100644 --- a/openpype/tools/utils/assets_widget.py +++ b/openpype/tools/utils/assets_widget.py @@ -821,7 +821,9 @@ class MultiSelectAssetsWidget(AssetsWidget): """ def __init__(self, *args, **kwargs): super(MultiSelectAssetsWidget, self).__init__(*args, **kwargs) - self._view.setSelectionMode(QtWidgets.QTreeView.ExtendedSelection) + self._view.setSelectionMode( + QtWidgets.QAbstractItemView.ExtendedSelection + ) delegate = UnderlinesAssetDelegate() self._view.setItemDelegate(delegate) From 681364bbea80b33bf34507cf1934eda42b78e3f5 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 16 Jan 2023 11:19:42 +0100 Subject: [PATCH 34/42] fix custom UserType items --- openpype/tools/pyblish_pype/model.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/openpype/tools/pyblish_pype/model.py b/openpype/tools/pyblish_pype/model.py index 774c3054acb..8a07bb447a0 100644 --- a/openpype/tools/pyblish_pype/model.py +++ b/openpype/tools/pyblish_pype/model.py @@ -38,11 +38,14 @@ # ItemTypes -InstanceType = QtGui.QStandardItem.UserType -PluginType = QtGui.QStandardItem.UserType + 1 -GroupType = QtGui.QStandardItem.UserType + 2 -TerminalLabelType = QtGui.QStandardItem.UserType + 3 -TerminalDetailType = QtGui.QStandardItem.UserType + 4 +UserType = QtGui.QStandardItem.UserType +if hasattr(UserType, "value"): + UserType = UserType.value +InstanceType = UserType +PluginType = UserType + 1 +GroupType = UserType + 2 +TerminalLabelType = UserType + 3 +TerminalDetailType = UserType + 4 class QAwesomeTextIconFactory: From 118d1eee16846293cce3d91edc8cb0c1e603cab2 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 16 Jan 2023 11:24:38 +0100 Subject: [PATCH 35/42] Fix 'QRegExpValidator' vs. 'QRegularExpressionValidator' --- openpype/tools/creator/widgets.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openpype/tools/creator/widgets.py b/openpype/tools/creator/widgets.py index 8ea3cbd03f8..8269cee42c4 100644 --- a/openpype/tools/creator/widgets.py +++ b/openpype/tools/creator/widgets.py @@ -8,6 +8,11 @@ from openpype.pipeline.create import SUBSET_NAME_ALLOWED_SYMBOLS from openpype.tools.utils import ErrorMessageBox +if hasattr(QtGui, "QRegularExpressionValidator"): + RegExpValidatorClass = QtGui.QRegularExpressionValidator +else: + RegExpValidatorClass = QtGui.QRegExpValidator + class CreateErrorMessageBox(ErrorMessageBox): def __init__( @@ -82,7 +87,7 @@ def _create_content(self, content_layout): content_layout.addWidget(tb_widget) -class SubsetNameValidator(QtGui.QRegExpValidator): +class SubsetNameValidator(RegExpValidatorClass): invalid = QtCore.Signal(set) pattern = "^[{}]*$".format(SUBSET_NAME_ALLOWED_SYMBOLS) From 1d2cf742f2a444279074f41b6c246c7b2e8513dc Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 16 Jan 2023 11:27:20 +0100 Subject: [PATCH 36/42] fix also 'QRegExp' vs. 'QRegularExpression' --- openpype/tools/creator/widgets.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/openpype/tools/creator/widgets.py b/openpype/tools/creator/widgets.py index 8269cee42c4..74f75811ffa 100644 --- a/openpype/tools/creator/widgets.py +++ b/openpype/tools/creator/widgets.py @@ -9,9 +9,11 @@ from openpype.tools.utils import ErrorMessageBox if hasattr(QtGui, "QRegularExpressionValidator"): - RegExpValidatorClass = QtGui.QRegularExpressionValidator + RegularExpressionValidatorClass = QtGui.QRegularExpressionValidator + RegularExpressionClass = QtCore.QRegularExpression else: - RegExpValidatorClass = QtGui.QRegExpValidator + RegularExpressionValidatorClass = QtGui.QRegExpValidator + RegularExpressionClass = QtCore.QRegExp class CreateErrorMessageBox(ErrorMessageBox): @@ -87,12 +89,12 @@ def _create_content(self, content_layout): content_layout.addWidget(tb_widget) -class SubsetNameValidator(RegExpValidatorClass): +class SubsetNameValidator(RegularExpressionValidatorClass): invalid = QtCore.Signal(set) pattern = "^[{}]*$".format(SUBSET_NAME_ALLOWED_SYMBOLS) def __init__(self): - reg = QtCore.QRegExp(self.pattern) + reg = RegularExpressionClass(self.pattern) super(SubsetNameValidator, self).__init__(reg) def validate(self, text, pos): From 0aad4cd224c3441ef5008c7e4222ecd0978e7357 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 16 Jan 2023 11:39:12 +0100 Subject: [PATCH 37/42] ignore 'QT_API' before application launch --- openpype/lib/applications.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/openpype/lib/applications.py b/openpype/lib/applications.py index 317a17796e4..0047b886953 100644 --- a/openpype/lib/applications.py +++ b/openpype/lib/applications.py @@ -908,24 +908,25 @@ def __init__(self, application, executable, env_group=None, **data): self.launch_args.extend(self.data.pop("app_args")) # Handle launch environemtns - env = self.data.pop("env", None) - if env is not None and not isinstance(env, dict): + src_env = self.data.pop("env", None) + if src_env is not None and not isinstance(src_env, dict): self.log.warning(( "Passed `env` kwarg has invalid type: {}. Expected: `dict`." " Using `os.environ` instead." - ).format(str(type(env)))) - env = None + ).format(str(type(src_env)))) + src_env = None - if env is None: - env = os.environ + if src_env is None: + src_env = os.environ - # subprocess.Popen keyword arguments - self.kwargs = { - "env": { - key: str(value) - for key, value in env.items() - } + ignored_env = {"QT_API",} + env = { + key: str(value) + for key, value in src_env.items() + if key not in ignored_env } + # subprocess.Popen keyword arguments + self.kwargs = {"env": env} if platform.system().lower() == "windows": # Detach new process from currently running process on Windows From 2546274c55de23f3cf65409ed0314becc6ad10ed Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 16 Jan 2023 11:50:20 +0100 Subject: [PATCH 38/42] Fix whitespace --- openpype/lib/applications.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/lib/applications.py b/openpype/lib/applications.py index 0047b886953..7cc296f47bc 100644 --- a/openpype/lib/applications.py +++ b/openpype/lib/applications.py @@ -919,7 +919,7 @@ def __init__(self, application, executable, env_group=None, **data): if src_env is None: src_env = os.environ - ignored_env = {"QT_API",} + ignored_env = {"QT_API", } env = { key: str(value) for key, value in src_env.items() From 459ed76ae2b3edc9b05e609a0f181650b2cc685d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 16 Jan 2023 18:02:20 +0100 Subject: [PATCH 39/42] fix access to 'CE_ItemViewItem' constant --- openpype/tools/utils/delegates.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/tools/utils/delegates.py b/openpype/tools/utils/delegates.py index 604df689c48..d76284afb1a 100644 --- a/openpype/tools/utils/delegates.py +++ b/openpype/tools/utils/delegates.py @@ -54,7 +54,10 @@ def paint(self, painter, option, index): style = QtWidgets.QApplication.style() style.drawControl( - style.CE_ItemViewItem, option, painter, option.widget + QtWidgets.QStyle.CE_ItemViewItem, + option, + painter, + option.widget ) painter.save() From da99fb25cedb3c1483a882affc687b347190744c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 16 Jan 2023 18:20:29 +0100 Subject: [PATCH 40/42] update qtpy --- poetry.lock | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index ca0b3c5c23b..cf780e8dd29 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2705,16 +2705,22 @@ six = "*" [[package]] name = "qtpy" -version = "1.11.3" -description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5, PyQt4 and PySide) and additional custom QWidgets." +version = "2.3.0" +description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6)." category = "main" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" +python-versions = ">=3.7" files = [ - {file = "QtPy-1.11.3-py2.py3-none-any.whl", hash = "sha256:e121fbee8e95645af29c5a4aceba8d657991551fc1aa3b6b6012faf4725a1d20"}, - {file = "QtPy-1.11.3.tar.gz", hash = "sha256:d427addd37386a8d786db81864a5536700861d95bf085cb31d1bea855d699557"}, + {file = "QtPy-2.3.0-py3-none-any.whl", hash = "sha256:8d6d544fc20facd27360ea189592e6135c614785f0dec0b4f083289de6beb408"}, + {file = "QtPy-2.3.0.tar.gz", hash = "sha256:0603c9c83ccc035a4717a12908bf6bc6cb22509827ea2ec0e94c2da7c9ed57c5"}, ] +[package.dependencies] +packaging = "*" + +[package.extras] +test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] + [[package]] name = "recommonmark" version = "0.7.1" From 9c01caf9be8db706567ebeb5278fea156487bcf1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 17 Jan 2023 13:51:08 +0100 Subject: [PATCH 41/42] again fix constant changes --- openpype/tools/sceneinventory/widgets.py | 4 ++-- openpype/tools/settings/settings/tests.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/tools/sceneinventory/widgets.py b/openpype/tools/sceneinventory/widgets.py index 994e6c8108d..49b0dd407dc 100644 --- a/openpype/tools/sceneinventory/widgets.py +++ b/openpype/tools/sceneinventory/widgets.py @@ -8,7 +8,7 @@ def __init__(self, parent=None): self.setObjectName("ButtonWithMenu") - self.setPopupMode(self.MenuButtonPopup) + self.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup) menu = QtWidgets.QMenu(self) self.setMenu(menu) @@ -42,7 +42,7 @@ def __init__(self, parent): super(SearchComboBox, self).__init__(parent) self.setEditable(True) - self.setInsertPolicy(self.NoInsert) + self.setInsertPolicy(QtWidgets.QComboBox.NoInsert) combobox_delegate = QtWidgets.QStyledItemDelegate(self) self.setItemDelegate(combobox_delegate) diff --git a/openpype/tools/settings/settings/tests.py b/openpype/tools/settings/settings/tests.py index 772d4618f72..8353ac1c8f7 100644 --- a/openpype/tools/settings/settings/tests.py +++ b/openpype/tools/settings/settings/tests.py @@ -54,7 +54,7 @@ def __init__(self, placeholder="", parent=None): super(AddibleComboBox, self).__init__(parent) self.setEditable(True) - # self.setInsertPolicy(self.NoInsert) + # self.setInsertPolicy(QtWidgets.QComboBox.NoInsert) self.lineEdit().setPlaceholderText(placeholder) # self.lineEdit().returnPressed.connect(self.on_return_pressed) From 0994795dc99819044b92b2027f3f5207457dd3b3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 17 Jan 2023 14:09:02 +0100 Subject: [PATCH 42/42] fix another one constant usage --- openpype/modules/log_viewer/tray/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/log_viewer/tray/widgets.py b/openpype/modules/log_viewer/tray/widgets.py index 981152e6e20..399d174fa6e 100644 --- a/openpype/modules/log_viewer/tray/widgets.py +++ b/openpype/modules/log_viewer/tray/widgets.py @@ -11,7 +11,7 @@ def __init__(self, parent=None, placeholder=""): super(SearchComboBox, self).__init__(parent) self.setEditable(True) - self.setInsertPolicy(self.NoInsert) + self.setInsertPolicy(QtWidgets.QComboBox.NoInsert) self.lineEdit().setPlaceholderText(placeholder) # Apply completer settings