# -*- coding: utf-8 -*-
"""
This module provides utilities for general QT functions and classes to be used as widgets or templates.
Classes
---------
- :class:`ARTv2Message <artv2_utilities.interface_utilities.ARTv2Message>`
- :class:`ARTv2Window <artv2_utilities.interface_utilities.ARTv2Window>`
- :class:`ErrorWidget <artv2_utilities.interface_utilities.ErrorWidget>`
- :class:`InfoWidget <artv2_utilities.interface_utilities.InfoWidget>`
Functions
---------
- :func:`create_style_sheet <artv2_utilities.interface_utilities.create_style_sheet>`
- :func:`get_maya_window <artv2_utilities.interface_utilities.get_maya_window>`
- :func:`get_style_sheet <artv2_utilities.interface_utilities.get_style_sheet>`
- :func:`scale_by_resolution <artv2_utilities.interface_utilities.scale_by_resolution>`
"""
import os
import maya.OpenMayaUI as mui
import maya.cmds as cmds
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin
from third_party.Qt import QtWidgets, QtGui, QtCore
import general_utilities as utils
try:
import shiboken as shiboken
except ImportError:
import shiboken2 as shiboken
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
[docs]def get_maya_window():
""" Return Maya's main window as a QWidget"""
pointer = mui.MQtUtil.mainWindow()
return shiboken.wrapInstance(long(pointer), QtWidgets.QWidget)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
[docs]def scale_by_resolution(width, height, widget):
"""
Find the screen resolution and adjust the incoming width and height to accomodate.
:param width: desired widget width
:param height: desired widget height
:param widget: widget used to query which monitor to query
:return: modified width and height based on screen resolution
"""
screen = QtWidgets.QDesktopWidget()
resolution = screen.availableGeometry(widget)
screen_width = float(resolution.width())
screen_height = float(resolution.height())
scale_factor_width = float(screen_width/1920)
scale_factor_height = float(screen_height/1080)
return [width * scale_factor_width, height * scale_factor_height]
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
[docs]def get_style_sheet(file_path):
""" Read the style sheet data, and then replace any urls with proper file paths on the user's drive."""
settings = utils.return_settings()
style_sheet_file = utils.path_join(settings[0], "resources/_styleSheets/" + file_path + ".qss")
f = open(style_sheet_file, "r")
data = f.readlines()
style = create_style_sheet(data)
f.close()
return style
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
[docs]def create_style_sheet(data):
""" Take in a read stylesheet, and replace any urls with actual file paths, then return the altered data."""
settings = utils.return_settings()
new_lines = []
# todo: could be simplified
for line in data:
if line.find("url(") != -1:
if line.find("resources/icons/backgrounds") != -1:
old_path = line.partition("(")[2].rpartition("/")[0]
replace_path = utils.path_join(settings[2], "backgrounds")
new_line = line.replace(old_path, replace_path)
new_lines.append(new_line)
if line.find("resources/icons/backgrounds") == -1:
old_path = line.partition("(")[2].rpartition("/")[0]
replace_path = settings[2]
new_line = line.replace(old_path, replace_path)
new_lines.append(new_line)
else:
new_lines.append(line)
user_dir = utils.path_unify(os.path.join(settings[0], "user"))
if not os.path.exists(user_dir):
os.makedirs(user_dir)
full_path = (utils.path_join(user_dir, "style.qss"))
f = open(full_path, 'w')
f.writelines(new_lines)
f.close()
f = open(full_path, 'r')
style = f.read()
f.close()
os.remove(full_path)
return style
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
class ARTv2Message(MayaQWidgetBaseMixin, QtWidgets.QMessageBox):
"""
Abstract class that adds extra functionality onto QMessageBox. Depending on the message type (warning, error, etc),
different buttons and icons will be shown. This class is not meant to be instantiated on its own.
"""
def __init__(self, width, height, title, critical=False, warning=False, info=False, question=False, parent=None):
super(ARTv2Message, self).__init__(parent)
if cmds.window(self.WINDOW_NAME, exists=True):
cmds.deleteUI(self.WINDOW_NAME)
self.setObjectName(self.WINDOW_NAME)
self.settings = utils.return_settings()
self.tools_path = self.settings[0]
self.script_path = self.settings[1]
self.icon_path = self.settings[2]
self.project_path = self.settings[3]
w, h = scale_by_resolution(width, height, self)
self.setMinimumSize(QtCore.QSize(w, h))
self.setMaximumSize(QtCore.QSize(w, h))
self.setWindowTitle(title)
if critical:
self.setIcon(QtWidgets.QMessageBox.Critical)
elif warning:
self.setIcon(QtWidgets.QMessageBox.Warning)
elif info:
self.setIcon(QtWidgets.QMessageBox.Information)
elif question:
self.setIcon(QtWidgets.QMessageBox.Question)
else:
self.setIcon(QtWidgets.QMessageBox.NoIcon)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
class ARTv2Window(MayaQWidgetBaseMixin, QtWidgets.QMainWindow):
"""
Abstract class that adds some extra default functionality for things like grabbing settings, dealing with
different screen resolutions, styling the UI, and saving screen position. This class is not meant to be
instantiated on its own.
"""
def __init__(self, width, height, window_title, parent=None):
super(ARTv2Window, self).__init__(parent)
if cmds.window(self.WINDOW_NAME, exists=True):
cmds.deleteUI(self.WINDOW_NAME)
self.setObjectName(self.WINDOW_NAME)
self.settings = utils.return_settings()
self.tools_path = self.settings[0]
self.script_path = self.settings[1]
self.icon_path = self.settings[2]
self.project_path = self.settings[3]
w, h = scale_by_resolution(width, height, self)
self.setMinimumSize(QtCore.QSize(w, h))
self.setMaximumSize(QtCore.QSize(w, h))
style_sheet = get_style_sheet("artv2_style")
self.setStyleSheet(style_sheet)
self.setWindowTitle(window_title)
window_icon = QtGui.QIcon(os.path.join(self.icon_path, "general/logo.png"))
self.setWindowIcon(window_icon)
self.restoreGeometry(self.settings[4].value(self.SETTINGS_NAME))
# noinspection PyPep8Naming
def closeEvent(self, event):
""" Override QMainWindow's close event to remember window position."""
self.settings[4].setValue(self.SETTINGS_NAME, self.saveGeometry())
QtWidgets.QMainWindow.closeEvent(self, event)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #