一. 文件夹创建
模块化绑定系统,代码不能全放在一个文件中,会显得十分臃肿,后期也很难修改,所以分类管理自己的代码很有必要
在Globals中创建一些功能性的文件方便在系统中直接调用里面的一些方法
二、创建主窗口UI文件
在UI文件夹下创建名称为UI的文件
1.引入库
代码如下:
from __future__ import unicode_literals,print_function
from functools import partial
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from My_Rigging_Tool.Globals import aboutFile,aboutName
from maya.app.general.mayaMixin import MayaQWidgetDockableMixin
from . import Main_ui # 这个文件是使用QtDesigner编译的UI文件
from imp import reload #在maya中可以不用导入
import sys,os,time
import pymel.core as pm
import My_Rigging_Tool as Tool
reload(aboutName)
reload(aboutFile)
reload(Main_ui)
★main_ui文件如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '.\Main.ui',
# licensing of '.\Main.ui' applies.
#
# Created: Sun Jan 30 14:32:58 2022
# by: pyside2-uic running on PySide2 5.12.5
#
# WARNING! All changes made in this file will be lost!
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_Main(object):
def setupUi(self, Main):
Main.setObjectName("Main")
Main.resize(462, 591)
self.gridLayout = QtWidgets.QGridLayout(Main)
self.gridLayout.setObjectName("gridLayout")
self.main_tabWidget = QtWidgets.QTabWidget(Main)
self.main_tabWidget.setStyleSheet("")
self.main_tabWidget.setObjectName("main_tabWidget")
self.Modules_tab = QtWidgets.QWidget()
self.Modules_tab.setObjectName("Modules_tab")
self.gridLayout_2 = QtWidgets.QGridLayout(self.Modules_tab)
self.gridLayout_2.setObjectName("gridLayout_2")
self.mid_line = QtWidgets.QFrame(self.Modules_tab)
self.mid_line.setFrameShape(QtWidgets.QFrame.HLine)
self.mid_line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.mid_line.setObjectName("mid_line")
self.gridLayout_2.addWidget(self.mid_line, 0, 0, 2, 1)
self.Module_scrollArea = QtWidgets.QScrollArea(self.Modules_tab)
self.Module_scrollArea.setStyleSheet("QPushButton{\n"
"border-radius:5px;\n"
"color: rgb(0, 100, 170);\n"
"}")
self.Module_scrollArea.setWidgetResizable(True)
self.Module_scrollArea.setObjectName("Module_scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 395, 400))
self.scrollAreaWidgetContents.setMinimumSize(QtCore.QSize(0, 400))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.Scroll_main = QtWidgets.QVBoxLayout()
self.Scroll_main.setObjectName("Scroll_main")
self.verticalLayout_2.addLayout(self.Scroll_main)
self.Module_scrollArea.setWidget(self.scrollAreaWidgetContents)
self.gridLayout_2.addWidget(self.Module_scrollArea, 0, 1, 1, 2)
self.option_vlayout = QtWidgets.QVBoxLayout()
self.option_vlayout.setObjectName("option_vlayout")
self.name_hlayout = QtWidgets.QHBoxLayout()
self.name_hlayout.setSpacing(6)
self.name_hlayout.setObjectName("name_hlayout")
self.Name_lb = QtWidgets.QLabel(self.Modules_tab)
self.Name_lb.setMinimumSize(QtCore.QSize(100, 0))
self.Name_lb.setMaximumSize(QtCore.QSize(16777215, 10))
self.Name_lb.setAlignment(QtCore.Qt.AlignCenter)
self.Name_lb.setObjectName("Name_lb")
self.name_hlayout.addWidget(self.Name_lb)
self.Name_le = QtWidgets.QLineEdit(self.Modules_tab)
self.Name_le.setMinimumSize(QtCore.QSize(100, 0))
self.Name_le.setMaximumSize(QtCore.QSize(300, 20))
self.Name_le.setObjectName("Name_le")
self.name_hlayout.addWidget(self.Name_le)
self.option_vlayout.addLayout(self.name_hlayout)
self.option_button_grid = QtWidgets.QGridLayout()
self.option_button_grid.setContentsMargins(0, -1, -1, -1)
self.option_button_grid.setObjectName("option_button_grid")
self.Constrain_btn = QtWidgets.QPushButton(self.Modules_tab)
self.Constrain_btn.setEnabled(False)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.Constrain_btn.sizePolicy().hasHeightForWidth())
self.Constrain_btn.setSizePolicy(sizePolicy)
self.Constrain_btn.setMinimumSize(QtCore.QSize(0, 30))
self.Constrain_btn.setMaximumSize(QtCore.QSize(135, 16777215))
self.Constrain_btn.setStyleSheet("QPushButton{\n"
"border-radius:5px;\n"
"font: 9pt \"Slackey\";\n"
"background-color: rgb(0, 160, 170);\n"
"color: rgb(0, 0, 0);\n"
"}\n"
"QPushButton:hover{\n"
"background-color:rgb(0,92,157);\n"
"}\n"
"")
self.Constrain_btn.setObjectName("Constrain_btn")
self.option_button_grid.addWidget(self.Constrain_btn, 0, 2, 1, 1)
self.Snap_btn = QtWidgets.QPushButton(self.Modules_tab)
self.Snap_btn.setEnabled(False)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.Snap_btn.sizePolicy().hasHeightForWidth())
self.Snap_btn.setSizePolicy(sizePolicy)
self.Snap_btn.setMinimumSize(QtCore.QSize(135, 30))
self.Snap_btn.setMaximumSize(QtCore.QSize(135, 16777215))
self.Snap_btn.setStyleSheet("QPushButton{\n"
"border-radius:5px;\n"
"font: 9pt \"Slackey\";\n"
"background-color: rgb(0, 160, 170);\n"
"color: rgb(0, 0, 0);\n"
"}\n"
"QPushButton:hover{\n"
"background-color:rgb(0,92,157);\n"
"}\n"
"")
self.Snap_btn.setObjectName("Snap_btn")
self.option_button_grid.addWidget(self.Snap_btn, 0, 1, 1, 1)
self.Group_btn = QtWidgets.QPushButton(self.Modules_tab)
self.Group_btn.setMinimumSize(QtCore.QSize(135, 30))
self.Group_btn.setMaximumSize(QtCore.QSize(100, 16777215))
self.Group_btn.setStyleSheet("QPushButton{\n"
"border-radius:5px;\n"
"background-color: rgb(0, 160, 170);\n"
"color: rgb(0, 0, 0);\n"
"}\n"
"QPushButton:hover{\n"
"background-color:rgb(0,92,157);\n"
"}\n"
"")
self.Group_btn.setObjectName("Group_btn")
self.option_button_grid.addWidget(self.Group_btn, 1, 0, 1, 1)
self.Mirror_btn = QtWidgets.QPushButton(self.Modules_tab)
self.Mirror_btn.setEnabled(False)
self.Mirror_btn.setMinimumSize(QtCore.QSize(135, 30))
self.Mirror_btn.setMaximumSize(QtCore.QSize(100, 16777215))
self.Mirror_btn.setStyleSheet("QPushButton{\n"
"border-radius:5px;\n"
"font: 9pt \"Slackey\";\n"
"background-color: rgb(0, 160, 170);\n"
"color: rgb(0, 0, 0);\n"
"}\n"
"QPushButton:hover{\n"
"background-color:rgb(0,92,157);\n"
"}\n"
"")
self.Mirror_btn.setObjectName("Mirror_btn")
self.option_button_grid.addWidget(self.Mirror_btn, 1, 2, 1, 1)
self.UnGroup_btn = QtWidgets.QPushButton(self.Modules_tab)
self.UnGroup_btn.setEnabled(False)
self.UnGroup_btn.setMinimumSize(QtCore.QSize(135, 30))
self.UnGroup_btn.setMaximumSize(QtCore.QSize(100, 16777215))
self.UnGroup_btn.setStyleSheet("QPushButton{\n"
"border-radius:5px;\n"
"font: 9pt \"Slackey\";\n"
"background-color: rgb(0, 160, 170);\n"
"color: rgb(0, 0, 0);\n"
"}\n"
"QPushButton:hover{\n"
"background-color:rgb(0,92,157);\n"
"}\n"
"")
self.UnGroup_btn.setObjectName("UnGroup_btn")
self.option_button_grid.addWidget(self.UnGroup_btn, 1, 1, 1, 1)
self.Rehock_btn = QtWidgets.QPushButton(self.Modules_tab)
self.Rehock_btn.setEnabled(False)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.Rehock_btn.sizePolicy().hasHeightForWidth())
self.Rehock_btn.setSizePolicy(sizePolicy)
self.Rehock_btn.setMinimumSize(QtCore.QSize(135, 30))
self.Rehock_btn.setMaximumSize(QtCore.QSize(135, 16777215))
font = QtGui.QFont()
font.setFamily("Slackey")
font.setPointSize(9)
font.setWeight(50)
font.setItalic(False)
font.setUnderline(False)
font.setBold(False)
self.Rehock_btn.setFont(font)
self.Rehock_btn.setStyleSheet("QPushButton{\n"
"border-radius:5px;\n"
"font: 9pt \"Slackey\";\n"
"background-color: rgb(0, 160, 170);\n"
"color: rgb(0, 0, 0);\n"
"}\n"
"QPushButton:hover{\n"
"background-color:rgb(0,92,157);\n"
"}\n"
"")
self.Rehock_btn.setObjectName("Rehock_btn")
self.option_button_grid.addWidget(self.Rehock_btn, 0, 0, 1, 1)
self.Delete_btn = QtWidgets.QPushButton(self.Modules_tab)
self.Delete_btn.setEnabled(False)
self.Delete_btn.setMinimumSize(QtCore.QSize(135, 30))
self.Delete_btn.setMaximumSize(QtCore.QSize(100, 16777215))
self.Delete_btn.setStyleSheet("QPushButton{\n"
"border-radius:5px;\n"
"font: 9pt \"Slackey\";\n"
"background-color: rgb(0, 160, 170);\n"
"color: rgb(0, 0, 0);\n"
"}\n"
"QPushButton:hover{\n"
"background-color:rgb(0,92,157);\n"
"}\n"
"")
self.Delete_btn.setObjectName("Delete_btn")
self.option_button_grid.addWidget(self.Delete_btn, 2, 1, 1, 1)
self.Symetry_cb = QtWidgets.QCheckBox(self.Modules_tab)
self.Symetry_cb.setMinimumSize(QtCore.QSize(135, 0))
self.Symetry_cb.setMaximumSize(QtCore.QSize(100, 16777215))
self.Symetry_cb.setTristate(False)
self.Symetry_cb.setObjectName("Symetry_cb")
self.option_button_grid.addWidget(self.Symetry_cb, 2, 2, 1, 1)
self.option_vlayout.addLayout(self.option_button_grid)
self.line_3 = QtWidgets.QFrame(self.Modules_tab)
self.line_3.setFrameShape(QtWidgets.QFrame.HLine)
self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_3.setObjectName("line_3")
self.option_vlayout.addWidget(self.line_3)
self.publish_vlayout = QtWidgets.QVBoxLayout()
self.publish_vlayout.setObjectName("publish_vlayout")
self.Lock_btn = QtWidgets.QPushButton(self.Modules_tab)
self.Lock_btn.setMinimumSize(QtCore.QSize(0, 30))
self.Lock_btn.setStyleSheet("QPushButton:hover{\n"
"background-color:rgb(0, 160, 170);\n"
"}\n"
"QPushButton{\n"
"background-color: rgb(41, 120, 200);\n"
"color: rgb(0, 0, 0);}")
self.Lock_btn.setObjectName("Lock_btn")
self.publish_vlayout.addWidget(self.Lock_btn)
self.Publish_btn = QtWidgets.QPushButton(self.Modules_tab)
self.Publish_btn.setMinimumSize(QtCore.QSize(0, 30))
self.Publish_btn.setStyleSheet("\n"
"QPushButton:hover{\n"
"background-color:rgb(0, 160, 170);\n"
"}\n"
"QPushButton{\n"
"font: 9pt \"Slackey\";\n"
"background-color: rgb(41, 120, 200);\n"
"color: rgb(0, 0, 0);}")
self.Publish_btn.setObjectName("Publish_btn")
self.publish_vlayout.addWidget(self.Publish_btn)
self.option_vlayout.addLayout(self.publish_vlayout)
self.gridLayout_2.addLayout(self.option_vlayout, 1, 2, 1, 1)
self.bottom_line = QtWidgets.QFrame(self.Modules_tab)
self.bottom_line.setFrameShape(QtWidgets.QFrame.HLine)
self.bottom_line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.bottom_line.setObjectName("bottom_line")
self.gridLayout_2.addWidget(self.bottom_line, 2, 0, 1, 3)
self.main_tabWidget.addTab(self.Modules_tab, "")
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.main_tabWidget.addTab(self.tab_2, "")
self.gridLayout.addWidget(self.main_tabWidget, 0, 0, 1, 1)
self.retranslateUi(Main)
self.main_tabWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(Main)
def retranslateUi(self, Main):
Main.setWindowTitle(QtWidgets.QApplication.translate("Main", "Module Rigging", None, -1))
self.Name_lb.setText(QtWidgets.QApplication.translate("Main", "Module Name", None, -1))
self.Constrain_btn.setText(QtWidgets.QApplication.translate("Main", "Constrain Rock > Hock", None, -1))
self.Snap_btn.setText(QtWidgets.QApplication.translate("Main", "Snap Rock>hock", None, -1))
self.Group_btn.setText(QtWidgets.QApplication.translate("Main", "Group Selected", None, -1))
self.Mirror_btn.setText(QtWidgets.QApplication.translate("Main", "Mirror", None, -1))
self.UnGroup_btn.setText(QtWidgets.QApplication.translate("Main", "UnGroup", None, -1))
self.Rehock_btn.setText(QtWidgets.QApplication.translate("Main", "Rehook", None, -1))
self.Delete_btn.setText(QtWidgets.QApplication.translate("Main", "Delete", None, -1))
self.Symetry_cb.setText(QtWidgets.QApplication.translate("Main", "Symetry Move", None, -1))
self.Lock_btn.setText(QtWidgets.QApplication.translate("Main", "Lock", None, -1))
self.Publish_btn.setText(QtWidgets.QApplication.translate("Main", "Publish", None, -1))
self.main_tabWidget.setTabText(self.main_tabWidget.indexOf(self.Modules_tab), QtWidgets.QApplication.translate("Main", "Modules", None, -1))
self.main_tabWidget.setTabText(self.main_tabWidget.indexOf(self.tab_2), QtWidgets.QApplication.translate("Main", "Options", None, -1))
2.初始化UI
一些ui方面的代码不做过多的阐述
代码如下:
# 获取当前模块的文件路径
ROOT_PATH = Tool.__path__[0].replace('\\','/')
class UI(MayaQWidgetDockableMixin , QDialog):
DOCK_LABEL = "My_Module_Rigging v1.0.0"
def __init__(self):
super(UI, self).__init__()
try:
pm.deleteUI('MainuiWorkspaceControl')
except RuntimeError:
pass
self.setWindowTitle(self.DOCK_LABEL)
self.ui = Main_ui.Ui_Main()
self.ui.setupUi(self)
self.initUI()
self.create_connections()
self.setObjectName('Mainui')
3.批量创建PushButton
def initUI(self):
for module in aboutFile.findAllModules("/Modules"):
self.createInstallMoudle(module)
def createInstallMoudle(self , module):
mod = __import__("My_Rigging_Tool.Modules." + module ,{},{},[module])
reload(mod)
title = mod.TITLE
description = mod.DESCRIPTION
iconPath = mod.ICON_PATH
# Child Main QHBoxLayout
self.Module_HLayout = QHBoxLayout()
self.Module_HLayout.setAlignment(Qt.AlignTop)
self.Module_HLayout.setContentsMargins(0,0,0,0)
self.Module_HLayout.setSpacing(0)
self.ui.Scroll_main.addLayout(self.Module_HLayout)
# click icon button
self.button_vbox = QVBoxLayout()
self.button_vbox.setAlignment(Qt.AlignBottom)
self.Module_btn = QPushButton()
self.Module_btn.setMinimumSize(QSize(60, 60))
self.Module_btn.setIcon(QIcon(iconPath))
self.Module_btn.setIconSize(QSize(50,50))
self.Module_btn.clicked.connect(partial(self.installModule , module))
self.button_vbox.addWidget(self.Module_btn)
self.Module_HLayout.addLayout(self.button_vbox)
self.scroll_vbox = QVBoxLayout()
self.scroll_vbox.setAlignment(Qt.AlignHCenter)
self.Module_HLayout.addLayout(self.scroll_vbox)
# module Title label
self.Module_lb = QLabel()
sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
sizePolicy.setHeightForWidth(self.Module_lb.sizePolicy().hasHeightForWidth())
self.Module_lb.setSizePolicy(sizePolicy)
self.Module_lb.setMinimumSize(QSize(400, 10))
self.Module_lb.setMaximumSize(QSize(400, 20))
self.Module_lb.setLayoutDirection(Qt.LeftToRight)
self.Module_lb.setAlignment(Qt.AlignCenter)
self.Module_lb.setText(mod.TITLE)
self.scroll_vbox.addWidget(self.Module_lb)
# description_scroll area
self.A_description_scroll = QScrollArea()
self.A_description_scroll.setEnabled(True)
self.A_description_scroll.setMinimumSize(QSize(0, 60))
self.A_description_scroll.setMaximumSize(QSize(462, 60))
self.A_description_scroll.setWidgetResizable(True)
self.A_description_scroll_widget = QWidget()
self.A_description_scroll_widget.setGeometry(QRect(0, 0, 462, 200))
self.A_description_scroll_widget.setMinimumSize(QSize(0, 200))
self.scroll_vbox.addWidget(self.A_description_scroll)
# # description_lb
self.A_description_lb = QLabel(self.A_description_scroll_widget)
self.A_description_lb.setGeometry(QRect(0, 0, 400, 60))
self.A_description_lb.setText(mod.DESCRIPTION)
sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.A_description_lb.sizePolicy().hasHeightForWidth())
self.A_description_lb.setSizePolicy(sizePolicy)
self.A_description_lb.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter)
self.A_description_scroll.setWidget(self.A_description_scroll_widget)
def installModule(self,module):
basename = "instance_"
pm.namespace(setNamespace = ":")
nameSpaces = pm.namespaceInfo(":",listOnlyNamespaces = True)
for i in range(len(nameSpaces)):
if nameSpaces[i].find("__") != -1:
nameSpaces[i] = nameSpaces[i].partition("__")[2]
newSuffix = aboutName.findHighestTrailingNum(nameSpaces, basename) + 1
userSpecName = basename + str(newSuffix)
mod = __import__("My_Rigging_Tool.Modules." + module, {}, {}, [module])
reload(mod)
moduleClass = getattr(mod , mod.CLASS_NAME)
moduleInstance = moduleClass(userSpecName)
moduleInstance.install()
moduleTransform = (mod.CLASS_NAME + "__" + userSpecName + ":module_transform")
pm.select(moduleTransform , r = True)
pm.setToolTo("moveSuperContext")
def create_connections(self):
self.ui.Lock_btn.clicked.connect(self.lock)
def lock(self , *args):
result = pm.confirmDialog(messageAlign = "center" , title = "Locking Information" ,
message = "This action will convert modules to joints,\n"
"Are you sure continue ? " , button = ["Accept" , "Cancel"],
defaultButton = "Accept" , cancelButton = "Cancel",
dismissString = "Cancel")
if result != "Accept":
return
modulesInfo = []
pm.namespace(setNamespace = ":")
namespaces = pm.namespaceInfo(":" , listOnlyNamespaces = True)
moduleNamesInfo = aboutFile.findAllModuleNames("/Modules")
validModule = moduleNamesInfo[0]
validModuleNames = moduleNamesInfo[1]
for n in namespaces:
splitString = n.partition("__")
if splitString[1] != "":
module = splitString[0]
userSpecifiedName = splitString[2]
if module in validModuleNames:
index = validModuleNames.index(module)
modulesInfo.append([validModule[index] , userSpecifiedName])
print(modulesInfo)
if len(modulesInfo) == 0:
pm.confirmDialog(messageAlign = "center" , title = "Lock Information" ,
message = "There will be no modules in the scene",
button = ["OK" , "Cancel"],
defaultButton = "OK" , cancelButton = "Cancel",
dismissString = "Cancel")
return
module_Instance = []
for module in modulesInfo:
mod = __import__("My_Rigging_Tool.Modules." + module[0] ,
{} , {} , [module[0]])
reload(mod)
moduleClass = getattr(mod , mod.CLASS_NAME)
module_ins = moduleClass(module[1])
moduleInfo = module_ins.lock_pr()
module_Instance.append((module_ins , moduleInfo))
for module in module_Instance:
module[0].lock_pr2(module[1])
def run():
Win = UI()
Win.show(dockable=True)