Integrating up through commit 90f050496
This commit is contained in:
+3
-4
@@ -10,14 +10,13 @@
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# -- This line is 75 characters -------------------------------------------
|
||||
# The __init__.py files help guide import statements without automatically
|
||||
# importing all of the modules
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
"""azpy.shared.ui.__init__"""
|
||||
|
||||
import os
|
||||
|
||||
from azpy import env_bool
|
||||
from azpy.env_bool import env_bool
|
||||
from azpy.constants import ENVAR_DCCSI_GDEBUG
|
||||
from azpy.constants import ENVAR_DCCSI_DEV_MODE
|
||||
|
||||
|
||||
+355
@@ -0,0 +1,355 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# from builtins import str
|
||||
|
||||
# built in's
|
||||
import os
|
||||
import sys
|
||||
import uuid
|
||||
import weakref
|
||||
import logging as _logging
|
||||
|
||||
# 3rd Party
|
||||
from unipath import Path
|
||||
|
||||
# azpy extensions
|
||||
import azpy.config_utils
|
||||
_config = azpy.config_utils.get_dccsi_config()
|
||||
settings = _config.get_config_settings(setup_ly_pyside=True)
|
||||
|
||||
import PySide2.QtWidgets as QtWidgets
|
||||
import PySide2.QtCore as QtCore
|
||||
from shiboken2 import wrapInstance
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# global space debug flag
|
||||
_G_DEBUG = settings.DCCSI_GDEBUG
|
||||
|
||||
# global space debug flag
|
||||
_DCCSI_DEV_MODE = settings.DCCSI_DEV_MODE
|
||||
|
||||
# global maya state (if we are running in maya with gui)
|
||||
# or another dcc tool with pyside2
|
||||
# TODO implement that check
|
||||
_G_PYSIDE2_DCC = None
|
||||
|
||||
_MODULE_PATH = Path(__file__)
|
||||
|
||||
_MODULENAME = 'azpy.shared.ui.azpy_base_widget'
|
||||
_LOGGER = _logging.getLogger(_MODULENAME)
|
||||
_LOGGER.debug('Something invoked :: {0}.'.format(_MODULENAME))
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
class DccWidget(object):
|
||||
"""This is an experimental Class to make a widget compatible with
|
||||
a number of PySide2/Python compatible DCC Tools like Maya and Houdini"""
|
||||
|
||||
_LABEL_NAME = 'no name window' # Window display name
|
||||
_instances = list()
|
||||
|
||||
# --constructor--------------------------------------------------------
|
||||
def __init__(self, parent=None, dcc_gui=_G_PYSIDE2_DCC, *args, **kwargs):
|
||||
|
||||
# False or None, 'Maya', 'Houdini' ... or another pysdie2 dcc
|
||||
self._dcc_gui = dcc_gui
|
||||
|
||||
self._name = '{0}_{1}'.format(self.__class__.__name__, uuid.uuid4())
|
||||
|
||||
self._parent = parent
|
||||
self._parent = self._base_setup()
|
||||
|
||||
# Init all baseclasses (including QWidget) of the main class
|
||||
try:
|
||||
super().__init__(*args, **kwargs)
|
||||
except Exception as Err:
|
||||
print(Err)
|
||||
|
||||
self.__class__._instances.append(weakref.proxy(self))
|
||||
|
||||
if isinstance(self, QtWidgets.QWidget):
|
||||
self.setParent(self._parent)
|
||||
|
||||
# camel case because this is a Qt|Pyside2 widget method
|
||||
if self.objectName() == '':
|
||||
# Set a unique object name string so Maya can easily look it up
|
||||
self.setObjectName('{0}_{1}'.format(self._name))
|
||||
|
||||
# -- properties -------------------------------------------------------
|
||||
@property
|
||||
def dcc_gui(self):
|
||||
return self._dcc_gui
|
||||
|
||||
@dcc_gui.setter
|
||||
def dcc_gui(self, type):
|
||||
self._dcc_gui = type
|
||||
return self._dcc_gui
|
||||
|
||||
@dcc_gui.getter
|
||||
def dcc_gui(self):
|
||||
return self._dcc_gui
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
return self._parent
|
||||
|
||||
@parent.setter
|
||||
def parent(self, type):
|
||||
self._parent = type
|
||||
return self._parent
|
||||
|
||||
@parent.getter
|
||||
def parent(self):
|
||||
return self._parent
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
def _base_setup(self, *args, **kwargs):
|
||||
'''TODO'''
|
||||
# if there is not a parent, we want a mainwindow to parent to
|
||||
if self.parent == None:
|
||||
self.parent = self._make_standalone_mainwindow()
|
||||
return self.parent
|
||||
|
||||
def _make_standalone_mainwindow(self):
|
||||
'''Make a standalone mainwindow parent to existing Qapp
|
||||
We parent so that this Qwidget will not be auto-destroyed or garbage
|
||||
collected if the instance variable goes out of scope.
|
||||
|
||||
If a Qapp doesn't exist, start one.
|
||||
'''
|
||||
original_parent = self._parent
|
||||
new_parent = None
|
||||
|
||||
if self.dcc_gui:
|
||||
if self.dcc_gui == 'Maya':
|
||||
# import the Maya ui class
|
||||
import OpenMaya as omui
|
||||
# Parent under the main Maya window
|
||||
mainWindowPtr = omui.MQtUtil.mainWindow()
|
||||
new_parent = wrapInstance(long(mainWindowPtr), QMainWindow)
|
||||
elif self.dcc_gui == 'Houdini':
|
||||
pass # not implemented
|
||||
else:
|
||||
from azpy.shared.ui.templates import TemplateMainWindow
|
||||
new_parent = TemplateMainWindow()
|
||||
|
||||
return new_parent
|
||||
|
||||
def objectName(self):
|
||||
# stand in for Qt call on mixed objects, thus camelCase
|
||||
return None
|
||||
|
||||
def show(self):
|
||||
# stand in for Qt call on mixed objects, thus camelCase
|
||||
return None
|
||||
|
||||
def thing(self):
|
||||
# Make this widget appear as a standalone window even though it is parented
|
||||
if isinstance(self, QtWidgets.QDockWidget):
|
||||
self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.FramelessWindowHint)
|
||||
else:
|
||||
try:
|
||||
self.setWindowFlags(QtCore.Qt.Window)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Delete the parent QDockWidget if applicable
|
||||
if isinstance(original_parent, QtWidgets.QDockWidget):
|
||||
original_parent.close()
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
class BaseQwidgetAzpy(object):
|
||||
"""Inheret from to handle common base functionality for Qt Widgets
|
||||
Parents to a standalone Qapp and mainwindow if not explicitly provided
|
||||
Place this before the Qt Widget Class in inheretance order"""
|
||||
|
||||
_LABEL_NAME = 'no name window' # Window display name
|
||||
_instances = list()
|
||||
|
||||
_ORG_TAG = 'Amazon_Lumberyard'
|
||||
_APP_TAG = 'DCCsi'
|
||||
|
||||
# --constructor--------------------------------------------------------
|
||||
def __init__(self,
|
||||
parent=None,
|
||||
logger=None,
|
||||
qapp=None,
|
||||
window_title=_LABEL_NAME,
|
||||
*args, **kwargs):
|
||||
"""To DO"""
|
||||
self._name_uuid = '{0}_{1}'.format(self.__class__.__name__, uuid.uuid4())
|
||||
|
||||
self._logger = logger
|
||||
if not self._logger:
|
||||
self._logger = _logging.getLogger(self._name_uuid)
|
||||
|
||||
self._parent = parent
|
||||
|
||||
self._qapp = qapp or QtWidgets.QApplication.instance()
|
||||
if self._qapp == None:
|
||||
self.logger.debug('No QApplication has been instantiated')
|
||||
self._qapp = self._base_setup(window_title)
|
||||
|
||||
# Init all baseclasses (including QWidget) of the main class
|
||||
try:
|
||||
super(BaseQwidgetAzpy, self).__init__(*args, **kwargs)
|
||||
except Exception as Err:
|
||||
print(Err)
|
||||
|
||||
self.__class__._instances.append(weakref.proxy(self))
|
||||
|
||||
if isinstance(self, QtWidgets.QWidget):
|
||||
self.setParent(self._parent)
|
||||
|
||||
# camel case because this is a Qt|Pyside2 widget method
|
||||
if self.objectName() == '':
|
||||
# Set a unique object name string so Maya can easily look it up
|
||||
self.setObjectName(self._name)
|
||||
|
||||
# -- properties -------------------------------------------------------
|
||||
@property
|
||||
def parent(self):
|
||||
return self._parent
|
||||
|
||||
@parent.setter
|
||||
def parent(self, type):
|
||||
self._parent = type
|
||||
return self._parent
|
||||
|
||||
@parent.getter
|
||||
def parent(self):
|
||||
return self._parent
|
||||
|
||||
@property
|
||||
def logger(self):
|
||||
return self._logger
|
||||
|
||||
@logger.setter
|
||||
def logger(self, logger):
|
||||
self._logger = logger
|
||||
return self._logger
|
||||
|
||||
@logger.getter
|
||||
def logger(self):
|
||||
return self._logger
|
||||
|
||||
@property
|
||||
def qapp(self):
|
||||
return self._qapp
|
||||
|
||||
@qapp.setter
|
||||
def qapp(self, qapp):
|
||||
self._qapp = qapp
|
||||
return self._qapp
|
||||
|
||||
@qapp.getter
|
||||
def qapp(self):
|
||||
return self._qapp
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def objectName(self):
|
||||
# stand in for Qt call on mixed objects, thus camelCase
|
||||
return self._name_uuid
|
||||
|
||||
def show(self):
|
||||
# stand in for Qt call on mixed objects, thus camelCase
|
||||
return None
|
||||
|
||||
def _base_setup(self, *args, **kwargs):
|
||||
'''TODO'''
|
||||
# if there is not a parent, we want a mainwindow to parent to
|
||||
if self.parent == None:
|
||||
try:
|
||||
self.parent = self._make_standalone_app(self.objectName())
|
||||
except:
|
||||
self.parent = self._make_standalone_app(self._name_uuid)
|
||||
return self.parent
|
||||
|
||||
def _make_standalone_app(self, name):
|
||||
useGUI = not '-no-gui' in sys.argv
|
||||
self.qapp = QtWidgets.QApplication(sys.argv) if useGUI else QtWidgets.QCoreApplication(sys.argv)
|
||||
self.qapp.setOrganizationName(self.__class__._ORG_TAG)
|
||||
self.qapp.setApplicationName('{app}:{tool}'.format(app=self.__class__._APP_TAG,
|
||||
tool=name))
|
||||
return self.qapp
|
||||
|
||||
@QtCore.Slot()
|
||||
def closeEvent(self, *args, **kwargs):
|
||||
"""Event which is run when window closes"""
|
||||
self.logger.debug("Method: {0}.{1}".format(self.__class__.__name__, 'closeEvent'))
|
||||
self.logger.debug("Closing: {0}".format(self.objectName()))
|
||||
self.__class__._instances.remove(self)
|
||||
self.qapp.instance().quit
|
||||
self.qapp.exit()
|
||||
# ----------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestWidget(BaseQwidgetAzpy, QtWidgets.QPushButton):
|
||||
def __init__(self, parent=None, *args, **kwargs):
|
||||
|
||||
# Init all baseclasses (including QWidget) of the main class
|
||||
try:
|
||||
super().__init__(*args, **kwargs)
|
||||
except Exception as Err:
|
||||
print(Err)
|
||||
|
||||
try:
|
||||
self.logger.debug('{0}'.format(self.parent))
|
||||
except Exception as Err:
|
||||
print(Err)
|
||||
|
||||
# self.setParent(parent)
|
||||
|
||||
self.setText('Push Me')
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
"""Run this file as main"""
|
||||
import sys
|
||||
|
||||
_TEST_APP_NAME = '{0}-{1}'.format(_MODULENAME, 'TEST')
|
||||
|
||||
_LOGGER = azpy.initialize_logger(_TEST_APP_NAME,
|
||||
log_to_file=True,
|
||||
default_log_level=_logging.DEBUG)
|
||||
|
||||
from azpy.constants import STR_CROSSBAR
|
||||
_LOGGER.info(STR_CROSSBAR)
|
||||
_LOGGER.info("{0} :: if __name__ == '__main__':".format(_MODULENAME))
|
||||
_LOGGER.info(STR_CROSSBAR)
|
||||
|
||||
|
||||
# test raw BaseWidget
|
||||
_TEST_BASE_WIDGET = BaseQwidgetAzpy()
|
||||
_LOGGER.info(_TEST_BASE_WIDGET.objectName())
|
||||
_TEST_BASE_WIDGET.show() # this should do nothing,it is a dummy call
|
||||
# this call is replaced with version the QWidget
|
||||
_TEST_BASE_WIDGET.closeEvent() # mimic Qt close
|
||||
_TEST_BASE_WIDGET = None
|
||||
|
||||
# NEED TO DELETE ^ Makes a Qapp
|
||||
|
||||
_TEST_WIDGET = TestWidget()
|
||||
_LOGGER.info(_TEST_WIDGET.objectName())
|
||||
_TEST_WIDGET.show()
|
||||
|
||||
del _LOGGER
|
||||
sys.exit(_TEST_WIDGET.qapp.exec_())
|
||||
# -------------------------------------------------------------------------
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# from builtins import str
|
||||
|
||||
# built in's
|
||||
import os
|
||||
# from io import StringIO # for handling unicode strings
|
||||
|
||||
# azpy
|
||||
from azpy import initialize_logger
|
||||
|
||||
# 3rd Party
|
||||
from unipath import Path
|
||||
import PySide2.QtCore as QtCore
|
||||
import PySide2.QtWidgets as QtWidgets
|
||||
import PySide2.QtGui as QtGui
|
||||
# -------------------------------------------------------------------------
|
||||
# global space debug flag
|
||||
_G_DEBUG = os.getenv('DCCSI_GDEBUG', False)
|
||||
|
||||
# global space debug flag
|
||||
_DCCSI_DEV_MODE = os.getenv('DCCSI_DEV_MODE', False)
|
||||
|
||||
_MODULE_PATH = Path(__file__)
|
||||
|
||||
_ORG_TAG = 'Amazon_Lumberyard'
|
||||
_APP_TAG = 'DCCsi'
|
||||
_TOOL_TAG = 'azpy.shared.ui.custom_treemodel'
|
||||
_TYPE_TAG = 'test'
|
||||
|
||||
_MODULENAME = __name__
|
||||
if _MODULENAME is '__main__':
|
||||
_MODULENAME = _TOOL_TAG
|
||||
|
||||
_UI_FILE = Path(_MODULE_PATH.parent, 'resources', 'example.ui')
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
###########################################################################
|
||||
## CustomTreeModel, Class
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
class CustomFileTreeModel(QtCore.QAbstractItemModel):
|
||||
"""
|
||||
Creates a customized model subclassed from, QAbstractItemModel
|
||||
Compatible with a TreeView
|
||||
"""
|
||||
|
||||
# --constructor--------------------------------------------------------
|
||||
def __init__(self, parent=None, *args, **kwargs):
|
||||
'''
|
||||
Constructor, INPUTS: Node, QObject
|
||||
'''
|
||||
super(CustomFileTreeModel, self).__init__(parent=parent, *args, **kwargs)
|
||||
|
||||
# can use these later (maybe?)
|
||||
# easily extended later, TODO implement as property, add append
|
||||
self._file_ext_list = ['.sbs', '.sbsar']
|
||||
|
||||
# we assume this is a file tree, we need a root path (lmbr project?)
|
||||
self._root_filepath = root_filepath
|
||||
# TODO: need to make sure we are getting path objects
|
||||
|
||||
# build the root node
|
||||
self._root_node = self.buildRootNode('root', None, self._rootFilePath)
|
||||
|
||||
# master selection
|
||||
self._masterSelection = masterSelection
|
||||
|
||||
# build the master selection node
|
||||
self._masterNode = self.buildMasterNode('master', None, self._masterSelection, self._rootNode.path())
|
||||
|
||||
# want to store off a couple lists in the model, for retreival later
|
||||
self._nodeList = None
|
||||
self._depNodesList = None
|
||||
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
"""help_menu.py: Setup a standard Help item in the menubar for PySide2 GUIs"""
|
||||
|
||||
# built in's
|
||||
import os
|
||||
import logging
|
||||
|
||||
# azpy
|
||||
from azpy import initialize_logger
|
||||
# import azpy.shared.ui.qt_settings as qt_settings
|
||||
|
||||
# 3rd Party
|
||||
from unipath import Path
|
||||
import PySide2.QtCore as QtCore
|
||||
import PySide2.QtGui as QtGui
|
||||
import PySide2.QtWidgets as QtWidgets
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# global space debug flag
|
||||
_G_DEBUG = os.getenv('DCCSI_GDEBUG', False)
|
||||
|
||||
# global space developer mode flag
|
||||
_DCCSI_DEV_MODE = os.getenv('DCCSI_DEV_MODE', False)
|
||||
|
||||
_MODULE_PATH = Path(__file__)
|
||||
|
||||
_ORG_TAG = 'Amazon_Lumberyard'
|
||||
_APP_TAG = 'DCCsi'
|
||||
_TOOL_TAG = 'azpy.shared.ui.help_menu'
|
||||
_TYPE_TAG = 'test'
|
||||
|
||||
_MODULENAME = __name__
|
||||
if _MODULENAME is '__main__':
|
||||
_MODULENAME = _TOOL_TAG
|
||||
|
||||
_LOGGER = logging.getLogger(_MODULENAME)
|
||||
_LOGGER.debug('Something invoked :: {0}.'.format({_MODULENAME}))
|
||||
|
||||
# TODO: implement this
|
||||
# checks the run configuration to determine if we are running in maya
|
||||
_G_MAYA = False
|
||||
try:
|
||||
from azpy.config.maya import _G_MAYA
|
||||
if _G_MAYA:
|
||||
import maya.cmds as mc
|
||||
except:
|
||||
pass
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
class HelpMenu():
|
||||
"""
|
||||
Setup a standard Help item in the menubar for PySide2 GUIs
|
||||
|
||||
INPUTS:
|
||||
main_window = the class instance of the QMainWindow
|
||||
tool_label = the menu label for the tool's help item
|
||||
tool_help_page = the http:// path to the specific bpTool help page
|
||||
|
||||
Here's an example
|
||||
# self.help_menu = azpy.shared.ui.help_menu.setup(self, 'Help...', 'https://some.site.com/azpy')
|
||||
|
||||
"""
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def __init__(self, main_window, tool_label, tool_help_page):
|
||||
"""Constructor"""
|
||||
|
||||
self.main_window = main_window
|
||||
# store mainwindow menubar, we can attach the Help menu to this
|
||||
self.menubar = self.main_window.menuBar()
|
||||
self.tool_label = tool_label
|
||||
self.tool_help_page = tool_help_page
|
||||
|
||||
self.help_menu = QtWidgets.QMenu(self.menubar)
|
||||
self.help_menu.setObjectName("help_menu")
|
||||
self.help_menu.setTitle("Help")
|
||||
|
||||
self.generic_tool_help_setup()
|
||||
self.specific_tool_help_setup()
|
||||
self.tool_bug_report_setup()
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def specific_tool_help_setup(self):
|
||||
""""""
|
||||
self.tool_action_help = QtWidgets.QAction(self.main_window)
|
||||
self.tool_action_help.setObjectName("tool_action_help")
|
||||
self.help_menu.addAction(self.tool_action_help)
|
||||
self.menubar.addAction(self.help_menu.menuAction())
|
||||
self.tool_action_help.setText(self.tool_label)
|
||||
self.main_window.connect(self.tool_action_help, QtCore.SIGNAL("triggered()"), self.tool_help_display)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def generic_tool_help_setup(self):
|
||||
""""""
|
||||
self.azpy_tool_action_help = QtWidgets.QAction(self.main_window)
|
||||
self.azpy_tool_action_help.setObjectName("azpy_tool_action_help")
|
||||
self.help_menu.addAction(self.azpy_tool_action_help)
|
||||
self.menubar.addAction(self.help_menu.menuAction())
|
||||
self.azpy_tool_action_help.setText("DCCsi help...")
|
||||
self.main_window.connect(self.azpy_tool_action_help, QtCore.SIGNAL("triggered()"), self.azpy_tool_help_display)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def tool_bug_report_setup(self):
|
||||
""""""
|
||||
self.tool_action_bug_report = QtWidgets.QAction(self.main_window)
|
||||
self.tool_action_bug_report.setObjectName("tool_action_bug_report")
|
||||
self.help_menu.addAction(self.tool_action_bug_report)
|
||||
self.menubar.addAction(self.help_menu.menuAction())
|
||||
self.tool_action_bug_report.setText("Report a Tool Bug...")
|
||||
self.main_window.connect(self.tool_action_bug_report, QtCore.SIGNAL("triggered()"), self.bug_report_display)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def tool_help_display(self):
|
||||
""""""
|
||||
if _G_MAYA:
|
||||
mc.showHelp(self.tool_help_page, absolute=True)
|
||||
else:
|
||||
_LOGGER.debug('This command, {0}: currently only works when running in Maya.'.format('tool_help_display'))
|
||||
pass
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def azpy_tool_help_display(self):
|
||||
""""""
|
||||
if _G_MAYA:
|
||||
mc.showHelp('https://some.site.com/azpy/maya_tools/', absolute=True)
|
||||
else:
|
||||
_LOGGER.debug('This command, {0}: currently only works when running in Maya.'.format('azpy_tool_help_display'))
|
||||
pass
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def bug_report_display(self):
|
||||
""""""
|
||||
if _G_MAYA:
|
||||
mc.showHelp('https://some.site.com/azpy/report_bug', absolute=True)
|
||||
else:
|
||||
_LOGGER.debug('This command, {0}: currently only works when running in Maya.'.format('bug_report_display'))
|
||||
pass
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestMainWindow(QtWidgets.QMainWindow):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setup_ui()
|
||||
|
||||
def setup_ui(self):
|
||||
self.setWindowTitle('PySide2-HelpMenu-Test')
|
||||
|
||||
# Setup Help Menu
|
||||
self.help_menu = HelpMenu(self, 'PySide2-Test Help...', 'http://dccSI.com/NewTool')
|
||||
|
||||
# main widget
|
||||
self.main_widget = QtWidgets.QWidget(self)
|
||||
self.setCentralWidget(self.main_widget)
|
||||
|
||||
# layout initialize
|
||||
self.global_layout = QtWidgets.QVBoxLayout()
|
||||
self.main_widget.setLayout(self.global_layout)
|
||||
|
||||
# Add Widgets
|
||||
self.spinbox = QtWidgets.QSpinBox()
|
||||
self.spinbox.setValue(30)
|
||||
layout = QtWidgets.QFormLayout()
|
||||
layout.addRow('Parameter', self.spinbox)
|
||||
self.button = QtWidgets.QPushButton('Execute')
|
||||
|
||||
# global layout setting
|
||||
self.global_layout.addLayout(layout)
|
||||
self.global_layout.addWidget(self.button)
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""Event which is run when window closes"""
|
||||
|
||||
_LOGGER.debug("Exiting: {0}".format(_TOOL_TAG))
|
||||
# ----------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
"""Run this file as main"""
|
||||
import sys
|
||||
|
||||
_LOGGER.debug("{0} :: if __name__ == '__main__':".format(_TOOL_TAG))
|
||||
_LOGGER.debug("Starting App: {0} ...".format(_TOOL_TAG))
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
mainWin = TestMainWindow()
|
||||
mainWin.show()
|
||||
|
||||
del _LOGGER
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
from __future__ import unicode_literals
|
||||
# from builtins import str
|
||||
|
||||
# built in's
|
||||
import sys
|
||||
import os
|
||||
import uuid
|
||||
|
||||
# azpy
|
||||
from azpy import initialize_logger
|
||||
from azpy.shared.ui.base_widget import BaseQwidgetAzpy
|
||||
|
||||
# 3rd Party
|
||||
from unipath import Path
|
||||
import PySide2.QtCore as QtCore
|
||||
import PySide2.QtWidgets as QtWidgets
|
||||
|
||||
from PySide2.QtCore import QProcess, Signal, Slot, QTextCodec
|
||||
from PySide2.QtGui import QTextCursor
|
||||
from PySide2.QtWidgets import QPlainTextEdit
|
||||
from PySide2.QtCore import QTimer
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# global space debug flag
|
||||
_G_DEBUG = os.getenv('DCCSI_GDEBUG', False)
|
||||
|
||||
# global space debug flag
|
||||
_DCCSI_DEV_MODE = os.getenv('DCCSI_DEV_MODE', False)
|
||||
|
||||
_MODULE_PATH = Path(__file__)
|
||||
|
||||
_ORG_TAG = 'Amazon_Lumberyard'
|
||||
_APP_TAG = 'DCCsi'
|
||||
_TOOL_TAG = 'azpy.shared.ui.pyside2_qtextedit_stdout'
|
||||
_TYPE_TAG = 'test'
|
||||
|
||||
_MODULENAME = __name__
|
||||
if _MODULENAME is '__main__':
|
||||
_MODULENAME = _TOOL_TAG
|
||||
|
||||
if _G_DEBUG:
|
||||
_LOGGER = initialize_logger(_MODULENAME, log_to_file=True)
|
||||
_LOGGER.debug('Something invoked :: {0}.'.format({_MODULENAME}))
|
||||
else:
|
||||
_LOGGER = initialize_logger(_MODULENAME)
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
class ProcessOutputReader(QProcess):
|
||||
produce_output = Signal(str)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
|
||||
# merge stderr channel into stdout channel
|
||||
self.setProcessChannelMode(QProcess.MergedChannels)
|
||||
# prepare decoding process' output to Unicode
|
||||
self._codec = QTextCodec.codecForLocale()
|
||||
self._decoder_stdout = self._codec.makeDecoder()
|
||||
# only necessary when stderr channel isn't merged into stdout:
|
||||
# self._decoder_stderr = codec.makeDecoder()
|
||||
|
||||
self.readyReadStandardOutput.connect(self._ready_read_standard_output)
|
||||
# only necessary when stderr channel isn't merged into stdout:
|
||||
# self.readyReadStandardError.connect(self._ready_read_standard_error)
|
||||
|
||||
@Slot()
|
||||
def _ready_read_standard_output(self):
|
||||
raw_bytes = self.readAllStandardOutput()
|
||||
text = self._decoder_stdout.toUnicode(raw_bytes)
|
||||
self.produce_output.emit(text)
|
||||
|
||||
# only necessary when stderr channel isn't merged into stdout:
|
||||
# @Slot()
|
||||
# def _ready_read_standard_error(self):
|
||||
# raw_bytes = self.readAllStandardError()
|
||||
# text = self._decoder_stderr.toUnicode(raw_bytes)
|
||||
# self.produce_output.emit(text)
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
|
||||
class MyConsole(BaseQwidgetAzpy, QPlainTextEdit):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
|
||||
# Set a unique object name string so Maya can easily look it up
|
||||
self.setObjectName('{0}_{1}'.format(self.__class__.__name__,
|
||||
uuid.uuid4()))
|
||||
|
||||
self.setReadOnly(True)
|
||||
self.setMaximumBlockCount(10000) # limit console to 10000 lines
|
||||
|
||||
self._cursor_output = self.textCursor()
|
||||
|
||||
@Slot(str)
|
||||
def append_output(self, text):
|
||||
self._cursor_output.insertText(text)
|
||||
self.scroll_to_last_line()
|
||||
|
||||
def scroll_to_last_line(self):
|
||||
cursor = self.textCursor()
|
||||
cursor.movePosition(QTextCursor.End)
|
||||
cursor.movePosition(QTextCursor.Up if cursor.atBlockStart() else
|
||||
QTextCursor.StartOfLine)
|
||||
self.setTextCursor(cursor)
|
||||
|
||||
def output_text(self, text):
|
||||
self._cursor_output.insertText(text)
|
||||
self.scroll_to_last_line()
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
"""Run this file as main"""
|
||||
import sys
|
||||
|
||||
_ORG_TAG = 'Amazon_Lumberyard'
|
||||
_APP_TAG = 'DCCsi'
|
||||
_TOOL_TAG = 'azpy.shared.ui.pyside2_qtextedit_stdout'
|
||||
_TYPE_TAG = 'test'
|
||||
|
||||
if _G_DEBUG:
|
||||
_LOGGER = initialize_logger('{0}-TEST'.format(_TOOL_TAG), log_to_file=True)
|
||||
_LOGGER.debug('Something invoked :: {0}.'.format({_MODULENAME}))
|
||||
|
||||
_LOGGER.debug("{0} :: if __name__ == '__main__':".format(_TOOL_TAG))
|
||||
_LOGGER.debug("Starting App:{0} TEST ...".format(_TOOL_TAG))
|
||||
|
||||
# # create the application instance
|
||||
# _APP = QtWidgets.QApplication(sys.argv)
|
||||
# _APP.setOrganizationName(_ORG_TAG)
|
||||
# _APP.setApplicationName('{app}:{tool}'.format(app=_APP_TAG, tool=_TOOL_TAG))
|
||||
|
||||
# create a console and connect the process output reader to it
|
||||
_CONSOLE = MyConsole()
|
||||
|
||||
# create a process output reader
|
||||
_READER = ProcessOutputReader(parent=_CONSOLE)
|
||||
_READER.produce_output.connect(_CONSOLE.append_output)
|
||||
|
||||
# start something and log (including to console)
|
||||
# this starts a test app
|
||||
_TEST_PY_FILE = Path(_MODULE_PATH.parent, 'pyside2_ui_utils.py')
|
||||
_READER.start('python', ['-u', _TEST_PY_FILE]) # start the process
|
||||
|
||||
# after that starts, this will show the console
|
||||
# LY_QSS = Path(_MODULE_PATH.parent, 'resources', 'stylesheets', 'LYstyle.qss')
|
||||
_DARK_STYLE = Path(_MODULE_PATH.parent, 'resources', 'qdarkstyle', 'style.qss')
|
||||
_CONSOLE.qapp.setStyleSheet(_DARK_STYLE.read_file())
|
||||
_CONSOLE.show() # make the console visible
|
||||
|
||||
_LOGGER.debug(_CONSOLE.objectName())
|
||||
|
||||
_TIMER = QTimer()
|
||||
_TIMER.timeout.connect(lambda: None)
|
||||
_TIMER.start(100)
|
||||
|
||||
del _LOGGER
|
||||
sys.exit(_CONSOLE.qapp.exec_())
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
from __future__ import unicode_literals
|
||||
# from builtins import str
|
||||
|
||||
# built in's
|
||||
import os
|
||||
import site
|
||||
import uuid
|
||||
import logging as _logging
|
||||
import xml.etree.ElementTree as xml # Qt .ui files are xml
|
||||
from io import StringIO # for handling unicode strings
|
||||
|
||||
# azpy extensions
|
||||
import azpy.config_utils
|
||||
_config = azpy.config_utils.get_dccsi_config()
|
||||
# ^ this is effectively an import and retreive of <dccsi>\config.py
|
||||
# and init's access to Qt/Pyside2
|
||||
# init lumberyard Qy/PySide2 access
|
||||
|
||||
# now default settings are extended with PySide2
|
||||
# this is an alternative to "from dynaconf import settings" with Qt
|
||||
settings = _config.get_config_settings(setup_ly_pyside=True)
|
||||
|
||||
# 3rd Party (we may or do provide)
|
||||
from unipath import Path
|
||||
|
||||
# now we can import lumberyards PySide2
|
||||
import PySide2.QtCore as QtCore
|
||||
import PySide2.QtWidgets as QtWidgets
|
||||
import PySide2.QtGui as QtGui
|
||||
from PySide2.QtWidgets import QApplication, QSizePolicy
|
||||
import PySide2.QtUiTools as QtUiTools
|
||||
|
||||
# special case for import pyside2uic
|
||||
site.addsitedir(settings.DCCSI_PYSIDE2_TOOLS)
|
||||
import pyside2uic
|
||||
|
||||
# azpy
|
||||
import azpy.shared.ui.qt_settings as qt_settings
|
||||
import azpy.shared.ui.help_menu as help_menu
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# global space debug flag
|
||||
_G_DEBUG = settings.DCCSI_GDEBUG
|
||||
|
||||
# global space debug flag
|
||||
_DCCSI_DEV_MODE = settings.DCCSI_DEV_MODE
|
||||
|
||||
_MODULE_PATH = Path(__file__)
|
||||
|
||||
_ORG_TAG = 'Amazon_Lumberyard'
|
||||
_APP_TAG = 'DCCsi'
|
||||
_TOOL_TAG = 'azpy.shared.ui.pyside2_ui_utils'
|
||||
_TYPE_TAG = 'test'
|
||||
|
||||
_MODULENAME = _TOOL_TAG
|
||||
_LOGGER = _logging.getLogger(_MODULENAME)
|
||||
_LOGGER.debug('Something invoked :: {0}.'.format(_MODULENAME))
|
||||
|
||||
_UI_FILE = Path(_MODULE_PATH.parent, 'resources', 'example.ui')
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
class UiLoader(QtUiTools.QUiLoader):
|
||||
def __init__(self, base_instance):
|
||||
super(UiLoader, self).__init__(base_instance)
|
||||
self._base_instance = base_instance
|
||||
|
||||
def createWidget(self, classname, parent=None, name=""):
|
||||
widget = super(UiLoader, self).createWidget(
|
||||
classname, parent, name)
|
||||
|
||||
if parent is None:
|
||||
return self._base_instance
|
||||
else:
|
||||
setattr(self._base_instance, name, widget)
|
||||
return widget
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
class UiWidget(QtWidgets.QWidget):
|
||||
def __init__(self, ui_file=_UI_FILE, parent=None):
|
||||
super().__init__(parent)
|
||||
loader = UiLoader(parent)
|
||||
file = QFile(ui_file)
|
||||
file.open(QFile.ReadOnly)
|
||||
loader.load(file, self)
|
||||
file.close()
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
def from_ui_generate_form_and_base_class(filename, return_output=False):
|
||||
"""Parse a Qt Designer .ui file and return Pyside2 Form and Base Class
|
||||
Usage:
|
||||
import azpy.shared.ui as azpyui
|
||||
form_class, base_class = azpyui.from_ui_generate_form_and_class(r'C:\my\filepath\tool.ui')
|
||||
"""
|
||||
ui_file = Path(filename)
|
||||
output = ''
|
||||
parsed_xml = None
|
||||
try:
|
||||
ui_file.exists()
|
||||
except FileNotFoundError as error:
|
||||
output += 'File does not exist: {0}/r'.format(error)
|
||||
if _G_DEBUG:
|
||||
print(error)
|
||||
if return_output:
|
||||
return False, output
|
||||
else:
|
||||
return False
|
||||
|
||||
try:
|
||||
ui_file.ext == 'ui'
|
||||
except IOError as error:
|
||||
output += 'Not a Qt Designer .ui file: {0}/r'.format(error)
|
||||
if return_output:
|
||||
return False, output
|
||||
else:
|
||||
return False
|
||||
|
||||
parsed_xml = xml.parse(ui_file)
|
||||
form_class = parsed_xml.find('class').text
|
||||
widget_class = parsed_xml.find('widget').get('class')
|
||||
|
||||
with open(ui_file, 'r') as ui_file:
|
||||
stream = StringIO() # create a file io stream
|
||||
frame = {}
|
||||
|
||||
_uic_compiler_path = Path(settings.DCCSI_PYSIDE2_TOOLS)
|
||||
site.addsitedir(_uic_compiler_path)
|
||||
|
||||
import pyside2uic
|
||||
|
||||
# compile the .ui file as a .pyc represented in steam
|
||||
pyside2uic.compileUi(ui_file, stream, indent=4)
|
||||
# compile the .pyc bytecode from stream
|
||||
pyc = compile(stream.getvalue(), '', 'exec')
|
||||
# execute the .pyc bytecode
|
||||
exec (pyc, frame)
|
||||
|
||||
# Retreive the form_class and base_class based on type in designer .ui (xml)
|
||||
form_class = frame['Ui_{0}'.format(form_class)]
|
||||
base_class = eval('QtWidgets.{0}'.format(widget_class))
|
||||
|
||||
ui_file.close()
|
||||
|
||||
if return_output:
|
||||
return form_class, base_class, output
|
||||
else:
|
||||
return form_class, base_class
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
"""Run this file as main"""
|
||||
import sys
|
||||
|
||||
_LOGGER = azpy.initialize_logger('{0}-TEST'.format(_TOOL_TAG), log_to_file=True)
|
||||
_LOGGER.debug('Something invoked :: {0}.'.format({_MODULENAME}))
|
||||
|
||||
_LOGGER.info("{0} :: if __name__ == '__main__':".format(_TOOL_TAG))
|
||||
_LOGGER.info("Starting App:{0} TEST ...".format(_TOOL_TAG))
|
||||
|
||||
_FORM_CLASS, _BASE_CLASS = from_ui_generate_form_and_base_class(_UI_FILE)
|
||||
|
||||
_LOGGER.info(_FORM_CLASS)
|
||||
_LOGGER.info(_BASE_CLASS)
|
||||
|
||||
from azpy.shared.ui.templates import TemplateMainWindow
|
||||
|
||||
_MAIN_WINDOW = TemplateMainWindow(logger=_LOGGER)
|
||||
_MAIN_WINDOW.show()
|
||||
|
||||
del _LOGGER
|
||||
sys.exit(_MAIN_WINDOW.qapp.exec_())
|
||||
# -------------------------------------------------------------------------
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
"""qt_settings.py: Manages a QSettings for a tool"""
|
||||
|
||||
# built in's
|
||||
import os
|
||||
import logging as _logging
|
||||
|
||||
# 3rd Party (we may provide)
|
||||
from unipath import Path
|
||||
from dynaconf import settings
|
||||
|
||||
# azpy extensions
|
||||
import azpy.config_utils
|
||||
_config = azpy.config_utils.get_dccsi_config()
|
||||
# ^ this is effectively an import and retreive of <dccsi>\config.py
|
||||
# init lumberyard Qy/PySide2 access
|
||||
_config.init_ly_pyside(settings.LY_DEV)
|
||||
|
||||
# now we can import lumberyards PySide2
|
||||
import PySide2.QtCore as QtCore
|
||||
import PySide2.QtWidgets as QtWidgets
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# global space debug flag
|
||||
_G_DEBUG = settings.DCCSI_GDEBUG
|
||||
|
||||
# global space debug flag
|
||||
_DCCSI_DEV_MODE = settings.DCCSI_DEV_MODE
|
||||
|
||||
_MODULE_PATH = Path(__file__)
|
||||
|
||||
_ORG_TAG = 'Amazon_Lumberyard'
|
||||
_APP_TAG = 'DCCsi'
|
||||
_TOOL_TAG = 'azpy.shared.ui.qt_settings'
|
||||
_TYPE_TAG = 'test'
|
||||
|
||||
_MODULENAME = _TOOL_TAG
|
||||
_LOGGER = _logging.getLogger(_MODULENAME)
|
||||
_LOGGER.debug('Something invoked :: {0}.'.format(_MODULENAME))
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
def createSettings(org='Amazon_Lumberyard', app='DCCsi',
|
||||
tool='azpy', type='default'):
|
||||
"""Sets up a settings .ini
|
||||
|
||||
Returns a QSettings instance"""
|
||||
|
||||
settings_folder = '{org}//{app}'.format(org=org, app=app)
|
||||
settings_name = '{tool}-{type}'.format(tool=tool, type=type)
|
||||
|
||||
settings = QtCore.QSettings(QtCore.QSettings.IniFormat,
|
||||
QtCore.QSettings.UserScope,
|
||||
settings_folder, settings_name)
|
||||
|
||||
return settings
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
"""Run this file as main"""
|
||||
import sys
|
||||
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
app.setOrganizationName(_ORG_TAG)
|
||||
app.setApplicationName('{app}:{tool}'.format(app=_APP_TAG, tool=_TOOL_TAG))
|
||||
|
||||
test_esttings = createSettings(_ORG_TAG, _APP_TAG, _TOOL_TAG, _TYPE_TAG)
|
||||
_LOGGER.info(test_esttings)
|
||||
_LOGGER.info(test_esttings.fileName())
|
||||
+680
@@ -0,0 +1,680 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# from builtins import str
|
||||
|
||||
# built in's
|
||||
import os
|
||||
import sys
|
||||
import logging as _logging
|
||||
import uuid
|
||||
import xml.etree.ElementTree as xml # Qt .ui files are xml
|
||||
from io import StringIO # for handling unicode strings
|
||||
|
||||
# 3rd Party (we may or do provide)
|
||||
from unipath import Path
|
||||
|
||||
# azpy extensions
|
||||
import azpy.config_utils
|
||||
_config = azpy.config_utils.get_dccsi_config()
|
||||
# ^ this is effectively an import and retreive of <dccsi>\config.py
|
||||
# and init's access to Qt/Pyside2
|
||||
# init lumberyard Qy/PySide2 access
|
||||
|
||||
# now default settings are extended with PySide2
|
||||
# this is an alternative to "from dynaconf import settings" with Qt
|
||||
settings = _config.get_config_settings(setup_ly_pyside=True)
|
||||
|
||||
# now we can import lumberyards PySide2
|
||||
import azpy.shared.ui.qt_settings as qt_settings
|
||||
import azpy.shared.ui.help_menu as help_menu
|
||||
import azpy.shared.ui.pyside2_ui_utils as ui_utils
|
||||
|
||||
import pyside2uic
|
||||
import PySide2.QtCore as QtCore
|
||||
import PySide2.QtWidgets as QtWidgets
|
||||
import PySide2.QtGui as QtGui
|
||||
import PySide2.QtUiTools as QtUiTools
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# global space debug flag
|
||||
_G_DEBUG = settings.DCCSI_GDEBUG
|
||||
|
||||
# global space debug flag
|
||||
_DCCSI_DEV_MODE = settings.DCCSI_DEV_MODE
|
||||
|
||||
_MODULE_PATH = Path(__file__)
|
||||
|
||||
_MODULENAME = 'azpy.shared.ui.teamplates'
|
||||
_LOGGER = _logging.getLogger(_MODULENAME)
|
||||
_LOGGER.debug('Something invoked :: {0}.'.format(_MODULENAME))
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# example .ui used as default (for tests, etc.)
|
||||
_UI_FILE = Path(_MODULE_PATH.parent, 'resources', 'example.ui')
|
||||
# Hmmm.... should be a better way to handle this?
|
||||
_FORM_CLASS, _BASE_CLASS = ui_utils.from_ui_generate_form_and_base_class(_UI_FILE)
|
||||
# looks like either we aren't compiling it or it's not provided in the current
|
||||
# version of Qt we use (check mack Qt5.15)
|
||||
# https://doc-snapshots.qt.io/qtforpython-5.15/PySide2/QtUiTools/ls.loadUiType.html)
|
||||
#_FORM_CLASS, _BASE_CLASS = QtUiTools.loadUiType(_UI_FILE)
|
||||
# print(QtUiTools.QUiLoader) <-- this one works differently but maybe that pattern is better?
|
||||
|
||||
# default dark styling for standalone apps
|
||||
_DARK_STYLE = Path(_MODULE_PATH.parent, 'resources', 'qdarkstyle', 'style.qss')
|
||||
# ^ lumberyard style doesn't work for all widgets, so this can be direcly applied
|
||||
# to sidgets that look funny, they won't be a perfect match but also won't look odd
|
||||
# To Do: make optional and/or force only when standalone
|
||||
# adopt the Qt app style by default (use lumberyards style when it's the parent)
|
||||
# include a standlaone lumberyard-like styling also
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# https://doc.qt.io/qt-5/designer-using-a-ui-file-python.html
|
||||
# pattern #1
|
||||
|
||||
# pyside2-uic.exe form.ui > form.py
|
||||
# results might be something like this:
|
||||
|
||||
#from ui_form import Ui_Form
|
||||
# class UicWidget(QtWidgets.QWidget):
|
||||
#def __init__(self, parent=None):
|
||||
#super(Window, self).__init__(parent)
|
||||
#self.m_ui = Ui_Form()
|
||||
#self.m_ui.setupUi(self)
|
||||
|
||||
# pattern #2
|
||||
# that could also be represented like?
|
||||
|
||||
# class SomeWidget(Ui_Form, QtWidgets.QWidget):
|
||||
#def __init__(self, parent=None):
|
||||
#super(Window, self).__init__(parent)
|
||||
# self.setupUi(self)
|
||||
|
||||
# pattern 3, use QUiLoader
|
||||
# you need to know the main widget class (QtWidgets.QWidget), load .ui form within class
|
||||
#from PySide2.QtUiTools import QUiLoader
|
||||
#from PySide2 import QtWidgets
|
||||
#from PySide2.QtCore import QFile
|
||||
|
||||
#class MyForm(QtWidgets.QWidget):
|
||||
#def __init__(self, parent=None):
|
||||
#QtWidgets.QWidget.__init__(self, parent)
|
||||
|
||||
## read/load my .ui file
|
||||
#file = QFile("form.ui")
|
||||
#file.open(QFile.ReadOnly)
|
||||
#self.loader = QUiLoader()
|
||||
#self.my_widget = self.loader.load(file, self)
|
||||
#file.close()
|
||||
|
||||
## setup my own layout
|
||||
#layout = QtWidgets.QVBoxLayout()
|
||||
#layout.addWidget(self.my_widget)
|
||||
#self.setLayout(layout)
|
||||
|
||||
#if __name__ == '__main__':
|
||||
#app = QtWidgets.QApplication(sys.argv)
|
||||
#myapp = MyForm()
|
||||
#myapp.show()
|
||||
#sys.exit(app.exec_())
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# pattern 4 (I like this)
|
||||
#_UI_FILE = Path(_MODULE_PATH.parent, 'resources', 'example.ui')
|
||||
#_FORM_CLASS, _BASE_CLASS = ui_utils.from_ui_generate_form_and_base_class(_UI_FILE)
|
||||
|
||||
# here is basically what that returns ...
|
||||
#parsed_xml = xml.parse(ui_file)
|
||||
# form_class = parsed_xml.find('class').text # --> <class 'Ui_Form'>
|
||||
# widget_class = parsed_xml.find('widget').get('class') # --> <class 'PySide2.QtWidgets.QWidget'>
|
||||
|
||||
#class MyToolWidget(TemplateToolWidget):
|
||||
#def __init__(self, parent, *args, **kwargs):
|
||||
#super().__init__(parent, *args, **kwargs)
|
||||
|
||||
#my_tool = MyToolWidget()
|
||||
|
||||
|
||||
class TemplateToolWidget(_FORM_CLASS, _BASE_CLASS):
|
||||
def __init__(self, parent, logger=None, *args, **kwargs):
|
||||
'''A custom tool window with a demo set of template ui functionality'''
|
||||
|
||||
super().__init__(parent, *args, **kwargs)
|
||||
|
||||
self._logger = logger
|
||||
if not self._logger:
|
||||
try:
|
||||
self._logger = self.parent().logger
|
||||
except:
|
||||
self._logger = azpy.initialize_logger(self.objectName())
|
||||
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, '__init__'))
|
||||
|
||||
# lets hope the parent is a mainwindow?
|
||||
self.mainwindow = parent
|
||||
|
||||
self._project_directory = Path('C:\Lumberyard', 'Dev', 'Gems',
|
||||
'DccScriptingInterface', 'MockProject')
|
||||
|
||||
# uic adds a function to our class called setupUi,
|
||||
# calling this creates all the widgets from the .ui file
|
||||
self.setupUi(self)
|
||||
|
||||
# this one is local to this class
|
||||
self.setup_ui()
|
||||
|
||||
# Connect the interface controls
|
||||
self.connect_interface()
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# -- properties --------------------------------------------------------
|
||||
@property
|
||||
def logger(self):
|
||||
return self._logger
|
||||
|
||||
@logger.setter
|
||||
def logger(self, logger):
|
||||
self._logger = logger
|
||||
return self._logger
|
||||
|
||||
@logger.getter
|
||||
def logger(self):
|
||||
return self._logger
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def setup_ui(self):
|
||||
"""TODO: Doc String"""
|
||||
# override this method to inject your own ui widgets amd layout
|
||||
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'setup_ui'))
|
||||
|
||||
self.helpMenu = help_menu.HelpMenu(self.mainwindow, 'TemplateToolTool Help...', 'http://dccSI.com/NewTool')
|
||||
|
||||
_DARK_STYLE = Path(_MODULE_PATH.parent, 'resources', 'qdarkstyle', 'style.qss')
|
||||
|
||||
try:
|
||||
self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||
except Exception as e:
|
||||
self.logger.warning('warning! : {}'.format(e))
|
||||
|
||||
# override some of widgets to a better dark style
|
||||
self.WatchdogList_treeView.setStyleSheet(_DARK_STYLE.read_file())
|
||||
self.WatchdogList_treeView.setMinimumHeight(250)
|
||||
self.output_console_textEdit.setStyleSheet(_DARK_STYLE.read_file())
|
||||
self.output_console_textEdit.setMinimumHeight(250)
|
||||
pass
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def set_defaults(self):
|
||||
"""TODO: Doc String"""
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'set_defaults'))
|
||||
pass
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def connect_interface(self):
|
||||
"""TODO: Doc String"""
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'connect_interface'))
|
||||
# Connect widgets to methods
|
||||
# QtCore.QObject.connect(self.renameButton, QtCore.SIGNAL("clicked()"), self.NewCommand)
|
||||
pass
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def new_command(self):
|
||||
"""TODO: Doc String"""
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'new_command'))
|
||||
pass
|
||||
# ----------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
class TemplateMainWindow(QtWidgets.QMainWindow):
|
||||
"""TODO"""
|
||||
|
||||
_ORG_TAG = 'Amazon_Lumberyard'
|
||||
_APP_TAG = 'DCCsi'
|
||||
|
||||
def __init__(self,
|
||||
parent=None,
|
||||
logger=None,
|
||||
app=None,
|
||||
custom_tool_widget=None,
|
||||
window_title='TemplateToolWidget',
|
||||
app_icon="icon.png",
|
||||
*args, **kwargs):
|
||||
"""TODO"""
|
||||
|
||||
# secret demo
|
||||
demo = kwargs.pop('demo', False)
|
||||
|
||||
self._logger = logger
|
||||
self._qapp = None
|
||||
self._name_uuid = '{0}_{1}'.format(self.__class__.__name__, uuid.uuid4())
|
||||
|
||||
if not self._logger:
|
||||
self._logger = azpy.initialize_logger(self._name_uuid)
|
||||
# self._logger = initialize_logger()
|
||||
|
||||
self._qapp = app or QtWidgets.QApplication.instance()
|
||||
if self._qapp is not None:
|
||||
pass
|
||||
else:
|
||||
# self.logger.debug('No QApplication has been instantiated')
|
||||
self._qapp = self._make_standalone_app(window_title)
|
||||
|
||||
super(TemplateMainWindow, self).__init__(parent=parent, *args, **kwargs)
|
||||
|
||||
# camel case because this is a Qt|Pyside2 widget method
|
||||
if self.objectName() == '':
|
||||
# Set a unique object name string so Maya can easily look it up
|
||||
self.setObjectName(self._name_uuid)
|
||||
|
||||
self.window_title = window_title
|
||||
if self.window_title == '':
|
||||
self.window_title = self.objectName()
|
||||
self.setWindowTitle(self.window_title)
|
||||
|
||||
self._style_sheet = None
|
||||
if not self._style_sheet:
|
||||
self._style_sheet = Path(_MODULE_PATH.parent, 'resources',
|
||||
'stylesheets', 'LYstyle.qss')
|
||||
self.setStyleSheet(self._style_sheet.read_file())
|
||||
|
||||
self.app_icon = app_icon
|
||||
|
||||
self._custom_widget = custom_tool_widget
|
||||
if self._custom_widget:
|
||||
self._custom_widget.parent(self)
|
||||
|
||||
self.setup_ui()
|
||||
if demo:
|
||||
custom_tool_widget = TemplateToolWidget(self)
|
||||
|
||||
self.add_custom_widget(custom_tool_widget)
|
||||
|
||||
# Setup the settings .ini
|
||||
_TYPE_TAG = 'TEMPLATE'
|
||||
self.settings = qt_settings.createSettings(TemplateMainWindow._ORG_TAG,
|
||||
TemplateMainWindow._APP_TAG,
|
||||
self.window_title, _TYPE_TAG)
|
||||
|
||||
# Read the saved settings
|
||||
self.read_settings()
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
def _make_standalone_app(self, name):
|
||||
useGUI = not '-no-gui' in sys.argv
|
||||
self.qapp = QtWidgets.QApplication(sys.argv) if useGUI else QtWidgets.QCoreApplication(sys.argv)
|
||||
self.qapp.setOrganizationName(TemplateMainWindow._ORG_TAG)
|
||||
self.qapp.setApplicationName('{app}:{tool}'.format(app=TemplateMainWindow._APP_TAG,
|
||||
tool=name))
|
||||
return self.qapp
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# -- properties --------------------------------------------------------
|
||||
@property
|
||||
def logger(self):
|
||||
return self._logger
|
||||
|
||||
@logger.setter
|
||||
def logger(self, logger):
|
||||
self._logger = logger
|
||||
return self._logger
|
||||
|
||||
@logger.getter
|
||||
def logger(self):
|
||||
return self._logger
|
||||
|
||||
@property
|
||||
def custom_widget(self):
|
||||
return self._lcustom_widget
|
||||
|
||||
@custom_widget.setter
|
||||
def custom_widget(self, custom_widget):
|
||||
self._custom_widget = custom_widget
|
||||
return self._custom_widget
|
||||
|
||||
@custom_widget.getter
|
||||
def custom_widget(self):
|
||||
return self._custom_widget
|
||||
|
||||
@property
|
||||
def qapp(self):
|
||||
return self._qapp
|
||||
|
||||
@qapp.setter
|
||||
def qapp(self, qapp):
|
||||
self._qapp = qapp
|
||||
return self._qapp
|
||||
|
||||
@qapp.getter
|
||||
def qapp(self):
|
||||
return self._qapp
|
||||
|
||||
@property
|
||||
def app_icon(self):
|
||||
return self._app_icon
|
||||
|
||||
@app_icon.setter
|
||||
def app_icon(self, icon):
|
||||
self._app_icon = QtGui.QIcon(icon)
|
||||
self.setWindowIcon(self._app_icon)
|
||||
return self._app_icon
|
||||
|
||||
@app_icon.getter
|
||||
def app_icon(self):
|
||||
return self._app_icon
|
||||
|
||||
def setIcon(self, icon):
|
||||
self.app_icon = icon
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def setup_ui(self, *args, **kwargs):
|
||||
# self.toolbar = QtWidgets.QToolBar()
|
||||
# self.addToolBar(self.toolbar)
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'setup_ui'))
|
||||
self.setIcon = self.app_icon
|
||||
|
||||
# Exit QAction on hotkey
|
||||
exit_tag = "Exit"
|
||||
exit_action = QtWidgets.QAction(exit_tag, self)
|
||||
exit_action.setShortcut("Ctrl+Q")
|
||||
exit_action.triggered.connect(self.close)
|
||||
|
||||
# basic menubar File > Exit event
|
||||
self.menu_bar = self.menuBar() # type: QMenuBar
|
||||
file_menu = self.menu_bar.addMenu("File") # type: QMenu
|
||||
file_menu.addAction(exit_tag, self.close)
|
||||
|
||||
# main widget
|
||||
self.central_widget = QtWidgets.QWidget(self)
|
||||
self.setCentralWidget(self.central_widget)
|
||||
|
||||
# layout initialize
|
||||
self.global_layout = QtWidgets.QVBoxLayout(self.central_widget)
|
||||
self.global_layout.setContentsMargins(8, 8, 8, 8)
|
||||
self.central_widget.setLayout(self.global_layout)
|
||||
|
||||
self.createStatusBar()
|
||||
|
||||
# TODO: create a progress bar
|
||||
# https://codeloop.org/how-to-create-progressbar-in-pyside2/amp/
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def add_custom_widget(self, custom_tool_widget=None):
|
||||
# Add our TemplateToolWidget
|
||||
if custom_tool_widget:
|
||||
self.custom_widget = custom_tool_widget
|
||||
self.custom_widget.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||
layout = QtWidgets.QFormLayout()
|
||||
self.global_layout.addLayout(layout)
|
||||
self.global_layout.addWidget(self.custom_widget)
|
||||
# else: # demo test tool
|
||||
# self.custom_widget = TemplateToolWidget(self)
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def createStatusBar(self):
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'createStatusBar'))
|
||||
self.myStatus = QtWidgets.QStatusBar()
|
||||
self.myStatus.showMessage("{0}: Ready".format(self.window_title), 3000)
|
||||
self.setStatusBar(self.myStatus)
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
@QtCore.Slot()
|
||||
def closeEvent(self, event=None, *args, **kwargs):
|
||||
"""Event which is run when window closes"""
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'closeEvent'))
|
||||
|
||||
close = QtWidgets.QMessageBox()
|
||||
result = close.question(self,
|
||||
"Confirm Exit...",
|
||||
"Are you sure you want to exit ?",
|
||||
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
|
||||
|
||||
if result == QtWidgets.QMessageBox.Yes:
|
||||
if event:
|
||||
event.accept()
|
||||
self.logger.debug("Closing: {0}".format(self.objectName()))
|
||||
self.write_settings()
|
||||
self.qapp.instance().quit
|
||||
self.qapp.exit()
|
||||
else:
|
||||
if event:
|
||||
event.ignore()
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def write_settings(self):
|
||||
"""Writes out the windows settings"""
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'write_settings'))
|
||||
# main window
|
||||
# saves window size and position
|
||||
self.settings.setValue("geometry", self.saveGeometry())
|
||||
# saves the state of window's toolbars and dockWidgets
|
||||
self.settings.setValue("windowState", self.saveState())
|
||||
# widgets, save a setting to persist
|
||||
# self.settings.setValue("textFilePath", self.textFileLineEdit.text())
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def read_settings(self):
|
||||
"""Reads in the windows settings"""
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'read_settings'))
|
||||
# main window
|
||||
self.restoreGeometry(self.settings.value("geometry")) # restores window size and position
|
||||
self.restoreState(self.settings.value("windowState")) # restores the state of window's toolbars and dockWidgets
|
||||
# widgets, restore something from settings
|
||||
# if self.settings.value("textFilePath"):
|
||||
# textFile = self.qt_settings.value("textFilePath",).toString()
|
||||
# self.textFileLineEdit.setText(textFile)
|
||||
# ----------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
class TestToolWidget(TemplateToolWidget):
|
||||
def __init__(self, parent, *args, **kwargs):
|
||||
'''A custom window with a demo set of ui widgets'''
|
||||
|
||||
super(TestToolWidget, self).__init__(parent=parent, *args, **kwargs)
|
||||
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, '__init__'))
|
||||
|
||||
# this one is local to this class
|
||||
self.extend_ui()
|
||||
|
||||
self._test_property = 'Property Not set'
|
||||
self.logger.debug("self._test_property: {0}".format(self._test_property))
|
||||
|
||||
self.class_tests()
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# -- properties --------------------------------------------------------
|
||||
@property
|
||||
def test_property(self):
|
||||
return self._test_property
|
||||
|
||||
@test_property.setter
|
||||
def test_property(self, test_property):
|
||||
self._test_property = test_property
|
||||
return self._test_property
|
||||
|
||||
@test_property.getter
|
||||
def test_property(self):
|
||||
return self._test_property
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def class_tests(self):
|
||||
"""TODO: Doc String"""
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'class_tests'))
|
||||
self.test_property = 'TEST PROPERTY'
|
||||
self.logger.debug("self._test_property: {0}".format(self.test_property))
|
||||
return
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def setup_ui(self):
|
||||
"""TODO: Doc String"""
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'setup_ui'))
|
||||
return
|
||||
|
||||
def extend_ui(self):
|
||||
"""TODO: Doc String"""
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'extend_ui'))
|
||||
|
||||
# this would be local to this class, runs outside _init__
|
||||
#
|
||||
# self.setup_ui()
|
||||
|
||||
# Connect the interface controls
|
||||
# self.connect_interface()
|
||||
|
||||
self._watchdog_list = QtGui.QStandardItemModel(parent=self)
|
||||
|
||||
self._project_directory = Path('C:\Lumberyard', 'Dev', 'Gems',
|
||||
'DccScriptingInterface', 'MockProject')
|
||||
|
||||
# we want 2 columns
|
||||
self._watchdog_list.setColumnCount(2)
|
||||
|
||||
# set up a temp watch dog folder watch list (as a model)
|
||||
self._watchdog_list.setHorizontalHeaderLabels(['Path', 'State'])
|
||||
|
||||
_DARK_STYLE = Path(_MODULE_PATH.parent, 'resources', 'qdarkstyle', 'style.qss')
|
||||
|
||||
# override some of widgets to a better dark style
|
||||
self.WatchdogList_treeView.setStyleSheet(_DARK_STYLE.read_file())
|
||||
self.WatchdogList_treeView.setMinimumHeight(250)
|
||||
self.WatchdogList_treeView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
|
||||
self.WatchdogList_treeView.setModel(self._watchdog_list)
|
||||
self.WatchdogList_treeView.setUniformRowHeights(True)
|
||||
|
||||
# populate treeView data
|
||||
parent_item = self._watchdog_list.invisibleRootItem()
|
||||
first_row = QtGui.QStandardItem(self._project_directory)
|
||||
self._watchdog_list.appendRow(first_row)
|
||||
# span container columns
|
||||
self.WatchdogList_treeView.setFirstColumnSpanned(0, self.WatchdogList_treeView.rootIndex(), True)
|
||||
|
||||
TemplateMainWindow = QtGui.QStandardItem('\\Assets\\some\\path')
|
||||
self._watchdog_list.appendRow(TemplateMainWindow)
|
||||
first_row_state = QtGui.QStandardItem('{0}'.format('Active'))
|
||||
# TemplateMainWindow.appendRow(first_row_state)
|
||||
|
||||
second_row = QtGui.QStandardItem('\\Assets\\another\\path')
|
||||
self._watchdog_list.appendRow(second_row)
|
||||
second_row_state = QtGui.QStandardItem('{0}'.format('Active'))
|
||||
# second_row.appendRow(second_row_state)
|
||||
|
||||
first_row.appendRow([TemplateMainWindow, second_row])
|
||||
# span container columns
|
||||
self.WatchdogList_treeView.setFirstColumnSpanned(0, self.WatchdogList_treeView.rootIndex(), True)
|
||||
|
||||
self.output_console_textEdit.setStyleSheet(_DARK_STYLE.read_file())
|
||||
self.output_console_textEdit.setMinimumHeight(250)
|
||||
|
||||
# TODO: create a progress bar
|
||||
# https://codeloop.org/how-to-create-progressbar-in-pyside2/amp/
|
||||
pass
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def set_defaults(self):
|
||||
"""TODO: Doc String"""
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'extend_ui'))
|
||||
pass
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def connect_interface(self):
|
||||
"""TODO: Doc String"""
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'connect_interface'))
|
||||
# Connect widgets to methods
|
||||
# QtCore.QObject.connect(self.renameButton, QtCore.SIGNAL("clicked()"), self.NewCommand)
|
||||
pass
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def new_command(self):
|
||||
"""TODO: Doc String"""
|
||||
self.logger.debug("Method: {0}.{1}".format(__class__, 'new_command'))
|
||||
pass
|
||||
# ----------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
"""Run this file as main"""
|
||||
import sys
|
||||
|
||||
_TEST_APP_NAME = '{0}-{1}'.format(_MODULENAME, 'TEST')
|
||||
|
||||
_LOGGER = azpy.initialize_logger(_TEST_APP_NAME,
|
||||
log_to_file=True,
|
||||
default_log_level=_logging.DEBUG)
|
||||
|
||||
from azpy.constants import STR_CROSSBAR
|
||||
_LOGGER.info(STR_CROSSBAR)
|
||||
_LOGGER.info("{0} :: if __name__ == '__main__':".format(_MODULENAME))
|
||||
_LOGGER.info(STR_CROSSBAR)
|
||||
|
||||
# test from_ui_generate_form_and_base_class
|
||||
_FORM_CLASS, _BASE_CLASS = ui_utils.from_ui_generate_form_and_base_class(_UI_FILE)
|
||||
|
||||
_LOGGER.info(_FORM_CLASS)
|
||||
_LOGGER.info(_BASE_CLASS)
|
||||
|
||||
_LOGGER.info("Starting App: {0} ...".format(_TEST_APP_NAME))
|
||||
|
||||
while 0:
|
||||
# Test 1, MainWindow with no widget (just the frame)
|
||||
_MAINWINDOW = TemplateMainWindow(logger=_LOGGER)
|
||||
_LOGGER.info(_MAINWINDOW.objectName())
|
||||
_LOGGER.info(_MAINWINDOW.settings)
|
||||
_LOGGER.info(_MAINWINDOW.settings.fileName())
|
||||
_MAINWINDOW.setWindowTitle(_TEST_APP_NAME)
|
||||
_MAINWINDOW.show()
|
||||
break
|
||||
|
||||
while 0:
|
||||
# test 2, demo forces a template widget to be created internally
|
||||
_MAINWINDOW = TemplateMainWindow(logger=_LOGGER,
|
||||
demo=True) #<-- template demo
|
||||
_LOGGER.info(_MAINWINDOW.objectName())
|
||||
_LOGGER.info(_MAINWINDOW.settings)
|
||||
_LOGGER.info(_MAINWINDOW.settings.fileName())
|
||||
_MAINWINDOW.setWindowTitle(_TEST_APP_NAME)
|
||||
_MAINWINDOW.show()
|
||||
break
|
||||
|
||||
while 1:
|
||||
# test 3, add a custom tool widget
|
||||
_MAINWINDOW = TemplateMainWindow(logger=_LOGGER)
|
||||
_CUSTOM_WIDGET = TemplateToolWidget(parent=_MAINWINDOW)
|
||||
_MAINWINDOW.add_custom_widget(_CUSTOM_WIDGET)
|
||||
_LOGGER.info(_MAINWINDOW.objectName())
|
||||
_LOGGER.info(_MAINWINDOW.settings)
|
||||
_LOGGER.info(_MAINWINDOW.settings.fileName())
|
||||
_MAINWINDOW.setWindowTitle(_TEST_APP_NAME)
|
||||
_MAINWINDOW.show()
|
||||
_MAINWINDOW.close() # test the close function
|
||||
break
|
||||
|
||||
del _LOGGER
|
||||
sys.exit(_MAINWINDOW.qapp.exec_())
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user