회원 로그인
정보기억 정보기억에 체크할 경우 다음접속시 아이디와 패스워드를 입력하지 않으셔도 됩니다.
그러나, 개인PC가 아닐 경우 타인이 로그인할 수 있습니다.
PC를 여러사람이 사용하는 공공장소에서는 체크하지 마세요.
소셜네트워크 서비스를 통해서 로그인하시면 별도의 로그인 절차없이 회원서비스를 이용하실 수 있습니다.


최근 게시물

1.노션에서 작성 중

1.노션에서 작성 중

개편하기 전까지 노션에서 작성 중

2024.04.04//read more

2.ChatGPT

2.ChatGPT

OpenAI로 대규모 언어 모델대화형...

2023.03.16//read more

3.노코딩 게임 엔진 - 빌..

3.노코딩 게임 엔진 - 빌..

빌드 지원안드로이드iOS윈도우즈특이사...

2023.03.14//read more

4.(완료) 미접속 회원 정..

4.(완료) 미접속 회원 정..

[완료] 36명의 회원을 정리하였습니...

2023.02.16//read more

5.매뉴얼 플러스 - 전자제..



안정적인 DNS 서비스 DNSEver
DNS Powered by DNSEver.com


[펌] Maya 2017 PySide2 Docking Qt QMainWindow

푸딩뱃살 | 2017.07.05 14:54 | 조회 4398
Maya 2017 PySide2 Docking Qt QMainWindow
:PySide2를 이용한 마야 메인 윈도우에 도킹 스크립트

Qt.py를 이용한 윈도우 클래스

윈도우(QMainWindow) 형
#MayaDockingClass.py
"""
This is what you need to do in order to get a qt window to dock next to maya channel box,
In all maya versions, including 2017 with PySide2
"""
__author__ = "liorbenhorin@gmail.com"

import sys
import os
import logging
import xml.etree.ElementTree as xml
from cStringIO import StringIO

# Qt is a project by Marcus Ottosson ---> https://github.com/mottosso/Qt.py
from Qt import QtGui, QtWidgets, QtCore, QtCompat

try:
    import pysideuic
    from shiboken import wrapInstance

    logging.Logger.manager.loggerDict["pysideuic.uiparser"].setLevel(logging.CRITICAL)
    logging.Logger.manager.loggerDict["pysideuic.properties"].setLevel(logging.CRITICAL)
except ImportError:
    import pyside2uic as pysideuic
    from shiboken2 import wrapInstance

    logging.Logger.manager.loggerDict["pyside2uic.uiparser"].setLevel(logging.CRITICAL)
    logging.Logger.manager.loggerDict["pyside2uic.properties"].setLevel(logging.CRITICAL)

import maya.OpenMayaUI as omui
from maya.app.general.mayaMixin import MayaQWidgetDockableMixin
import maya.cmds as cmds


def loadUiType(uiFile):
    """
    :author: Jason Parks
    Pyside lacks the "loadUiType" command, so we have to convert the ui file to py code in-memory first
    and then execute it in a special frame to retrieve the form_class.
    """
    parsed = xml.parse(uiFile)
    widget_class = parsed.find('widget').get('class')
    form_class = parsed.find('class').text

    with open(uiFile, 'r') as f:
        o = StringIO()
        frame = {}

        pysideuic.compileUi(f, o, indent=0)
        pyc = compile(o.getvalue(), '<string>', 'exec')
        exec pyc in frame

        # Fetch the base_class and form class based on their type in the xml from designer
        form_class = frame['Ui_%s' % form_class]
        base_class = getattr(QtWidgets, widget_class)
    return form_class, base_class

def maya_main_window():
    main_window_ptr = omui.MQtUtil.mainWindow()
    return wrapInstance(long(main_window_ptr), QtWidgets.QWidget)

def maya_api_version():
    return int(cmds.about(api=True))

class MyDockingWindow(MayaQWidgetDockableMixin, QtWidgets.QMainWindow):
    MAYA2014 = 201400
    MAYA2015 = 201500
    MAYA2016 = 201600
    MAYA2016_5 = 201650
    MAYA2017 = 201700

    def __init__(self, parent=None):
        self.deleteInstances() # remove any instance of this window before starting
        super(MyDockingWindow, self).__init__(parent)
        self.setWindowFlags(QtCore.Qt.Tool)
        """
        compile the .ui file on loadUiType(), a function that uses pysideuic / pyside2uic to compile .ui files
        """
        uiFile = os.path.join(os.path.dirname(__file__), 'MyDockingWindow_ui.ui')
        form_class, base_class = loadUiType(uiFile)
        self.ui = form_class()
        self.ui.setupUi(self)

        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

    def dockCloseEventTriggered(self):
        self.deleteInstances()

    # Delete any instances of this class
    def deleteInstances(self):

        def delete2016():
            # Go through main window's children to find any previous instances
            for obj in maya_main_window().children():
                if str(type(obj)) == "<class 'maya.app.general.mayaMixin.MayaQDockWidget'>": # ""<class 'maya.app.general.mayaMixin.MayaQDockWidget'>":
                    if obj.widget().__class__.__name__ == "MyDockingWindow": # Compare object names
                        obj.setParent(None)
                        obj.deleteLater()

        def delete2017():
            '''
            Look like on 2017 this needs to be a little diffrents, like in this function,
            However, i might be missing something since ive done this very late at night :)
            '''

            for obj in maya_main_window().children():
                if str(type(obj)) == "<class '{}.MyDockingWindow'>".format(os.path.splitext(os.path.basename(__file__)[0])): # ""<class 'moduleName.mayaMixin.MyDockingWindow'>":
                    if obj.__class__.__name__ == "MyDockingWindow": # Compare object names
                        obj.setParent(None)
                        obj.deleteLater()

        if maya_api_version() < MyDockingWindow.MAYA2017:
            delete2016()
        else:
            delete2017()

    def deleteControl(self, control):
        if cmds.workspaceControl(control, q=True, exists=True):
            cmds.workspaceControl(control, e=True, close=True)
            cmds.deleteUI(control, control=True)

    # Show window with docking ability
    def run(self):
        '''
        2017 docking is a little different...
        '''

        def run2017():
            self.setObjectName("MyMainDockingWindow")

            # The deleteInstances() dose not remove the workspace control, and we need to remove it manually
            workspaceControlName = self.objectName() + 'WorkspaceControl'
            self.deleteControl(workspaceControlName)

            # this class is inheriting MayaQWidgetDockableMixin.show(), which will eventually call maya.cmds.workspaceControl.
            # I'm calling it again, since the MayaQWidgetDockableMixin dose not have the option to use the "tabToControl" flag,
            # which was the only way i found i can dock my window next to the channel controls, attributes editor and modelling toolkit.
            self.show(dockable=True, area='right', floating=False)
            cmds.workspaceControl(workspaceControlName, e=True, ttc=["AttributeEditor", -1], wp="preferred", mw=420)
            self.raise_()

            # size can be adjusted, of course
            self.setDockableParameters(width=420)

        def run2016():
            self.setObjectName("MyMainDockingWindow")
            # on maya < 2017, the MayaQWidgetDockableMixin.show() magiclly docks the window next
            # to the channel controls, attributes editor and modelling toolkit.
            self.show(dockable=True, area='right', floating=False)
            self.raise_()
            # size can be adjusted, of course
            self.setDockableParameters(width=420)
            self.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
            self.setMinimumWidth(420)
            self.setMaximumWidth(600)

        if maya_api_version() < MyDockingWindow.MAYA2017:
            run2016()
        else:
            run2017()


def show():
    '''
    this is the funciton that start things up
    '''
    global MyDockingWindow
    MyDockingWindow = MyDockingWindow(parent=maya_main_window())
    MyDockingWindow.run()
    return MyDockingWindow

출처
https://gist.github.com/liorbenhorin/217bfb7e54c6f75b9b1b2b3d73a1a43a

Tab(QDockWidget) 형
'''
Template class for docking a Qt widget to maya 2017+.
Author: Lior ben horin
12-1-2017
'''

import weakref

import maya.cmds as cmds
import maya.OpenMayaUI as omui
from shiboken2 import wrapInstance

from Qt import QtGui, QtWidgets, QtCore # https://github.com/mottosso/Qt.py by Marcus Ottosson 


def dock_window(dialog_class):
    try:
        cmds.deleteUI(dialog_class.CONTROL_NAME)
        logger.info('removed workspace {}'.format(dialog_class.CONTROL_NAME))

    except:
        pass

    # building the workspace control with maya.cmds
    main_control = cmds.workspaceControl(dialog_class.CONTROL_NAME, ttc=["AttributeEditor", -1],iw=300, mw=True, wp='preferred', label = dialog_class.DOCK_LABEL_NAME)
    
    # now lets get a C++ pointer to it using OpenMaya
    control_widget = omui.MQtUtil.findControl(dialog_class.CONTROL_NAME)
    # conver the C++ pointer to Qt object we can use
    control_wrap = wrapInstance(long(control_widget), QtWidgets.QWidget)
    
    # control_wrap is the widget of the docking window and now we can start working with it:
    control_wrap.setAttribute(QtCore.Qt.WA_DeleteOnClose)
    win = dialog_class(control_wrap)
    
    # after maya is ready we should restore the window since it may not be visible
    cmds.evalDeferred(lambda *args: cmds.workspaceControl(main_control, e=True, rs=True))

    # will return the class of the dock content.
    return win.run()


class MyDockingUI(QtWidgets.QWidget):

    instances = list()
    CONTROL_NAME = 'my_workspcae_control'
    DOCK_LABEL_NAME = 'my workspcae control'

    def __init__(self, parent=None):
        super(MyDockingUI, self).__init__(parent)

        # let's keep track of our docks so we only have one at a time.    
        MyDockingUI.delete_instances()
        self.__class__.instances.append(weakref.proxy(self))

        self.window_name = self.CONTROL_NAME
        self.ui = parent
        self.main_layout = parent.layout()
        self.main_layout.setContentsMargins(2, 2, 2, 2)

        # here we can start coding our UI
        self.my_label = QtWidgets.QLabel('hello world!')
        self.main_layout.addWidget(self.my_label)    

    @staticmethod
    def delete_instances():
        for ins in MyDockingUI.instances:
            logger.info('Delete {}'.format(ins))
            try:
                ins.setParent(None)
                ins.deleteLater()
            except:
                # ignore the fact that the actual parent has already been deleted by Maya...
                pass

            MyDockingUI.instances.remove(ins)
            del ins

    def run(self):
        return self

# this is where we call the window
my_dock = dock_window(MyDockingUI)

출처
https://gist.github.com/liorbenhorin/69da10ec6f22c6d7b92deefdb4a4f475
466개(1/24페이지)
마야
번호 제목 글쓴이 조회 날짜
공지 마야 뷰포트 네비게이션 팁 푸딩뱃살 41834 2020.04.06 17:22
공지 Maya 버전 별 Python 버전 푸딩뱃살 63239 2014.01.08 17:59
464 [Dev] Autodesk Maya Devkit 다운로드 첨부파일 푸딩뱃살 672 2023.01.28 14:28
463 [Base] (해결 중) modules 환경설정 중 푸딩뱃살 599 2022.11.09 11:47
462 [Script] pymel 딕셔너리형 사용 시 KeyError 푸딩뱃살 801 2022.11.07 12:08
461 [오류] Building Numpy for Maya Python 2.7.x 푸딩뱃살 570 2022.10.23 14:38
460 [Base] 뷰포트에서 조절자가 안 보일때 첨부파일 푸딩뱃살 731 2022.10.13 15:47
459 [Rigging] mirror joints 사용 시 유의 사항 푸딩뱃살 734 2022.10.04 10:46
458 [Script] 2022에서 enum34 모듈 설치 금지 첨부파일 푸딩뱃살 584 2022.08.17 18:08
457 [Script] pymel 예제 푸딩뱃살 605 2022.07.05 19:20
456 [Script] 인코드 / 디코드 - 2.7 한글 사용 푸딩뱃살 868 2022.03.08 17:52
455 [Dev] ui 없이 mayapy로 자동화 첨부파일 푸딩뱃살 673 2022.02.17 13:56
454 [Dev] mayapy로 ui파일 py로 푸딩뱃살 512 2022.02.15 18:20
453 [오류] Error : MayaBonusTools 푸딩뱃살 879 2022.01.21 17:52
452 [오류] Error: ModuleNotFoundError 푸딩뱃살 742 2022.01.21 16:24
451 [Dev] mayapy 첨부파일 푸딩뱃살 619 2022.01.19 20:08
450 [Base] function selCom at 0x7f29c5c04aa0 첨부파일 푸딩뱃살 585 2022.01.19 17:24
449 [Base] wireframe on shaded 단축키 만들기 첨부파일 푸딩뱃살 869 2022.01.04 10:55
448 [오류] OpenCL Error 푸딩뱃살 505 2021.12.28 01:40
447 [Script] Easily Translate MEL Commands to Python 첨부파일 푸딩뱃살 792 2021.12.02 11:22
446 [Base] output window 띄우지 않기 첨부파일 푸딩뱃살 771 2021.11.24 21:44
445 [Rigging] shapeEditorManager 삭제 안됨 푸딩뱃살 846 2021.11.12 23:30