【Maya2018 – Bug】setWindowFlagsがうまく機能しない

PySide,PySide2,Python,Qt,Maya,Bug

調べてみるとMaya2017update4以降うまく機能しないようです。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Qt.QtGui import*
from Qt.QtCore import*
from Qt.QtWidgets import*

import maya.OpenMayaUI as OpenMayaUI
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin

class GUI(MayaQWidgetBaseMixin, QMainWindow):
    def __init__(self):
        super(GUI, self).__init__()
        self.setCentralWidget(widget())
        self.setWindowFlags(Qt.Window|Qt.FramelessWindowHint)

class widget(QWidget):
    def __init__(self, parent=None):
        super(widget, self).__init__(parent)
        Button = QPushButton(button, self)
        Button.clicked.connect(self.close)

        VBox = QVBoxLayout()
        VBox.setObjectName(VLayout)
        VBox.addWidget(Button)

        self.setLayout(VBox)

def main():
    app = QApplication.instance()
    ex = GUI()
    ex.show()
    sys.exit()
    app.exec_()

上のコードを使うとフレームレスでwindowが表示されるはずですが、試しにMaya2018で実行してみると下の画像のようにsetWindowFlagsが機能していません。

C:\Program Files\Autodesk\Maya2018\Python\Lib\site-packages\maya\app\general\mayaMixin.py
上のpathのコードの中身を見てみました。

確認するのはMayaQWidgetBaseMixinクラスです
このクラスは初期化中に Maya Qt ウィジェットの一般的なアクションを行う際に使用します
詳しく見ていくと
MayaのMainWindowの子供にしてStandalone Windowを作成する_makeMayaStandaloneWindow()が読み込まれていません
MayaのMainWindowで子供のプロセスは、インスタンス変数が有効範囲外になったときにQWidgetが自動的に破棄されないようにします
この変数を読み込まれてないのでうまく機能していないようです。

if parent is None:
    self._makeMayaStandaloneWindow()

mayaMixin.pyの98行目あたりに上のコードを記述します。
記述したコードはC:\Program Files\Autodesk\Maya2018\Python\Lib\site-packages\maya\app\general\mayaMixin.pyに保存するのではなくドキュメントのscriptフォルダや任意のフォルダに保存し上書きして実行できるようにすることをおすすめします
次に任意のドキュメントから読み込めるようコードを書き換えます。

今回はドキュメントのscriptフォルダに入れた過程でコードを組んでいます。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Qt.QtGui import*
from Qt.QtCore import*
from Qt.QtWidgets import*

import maya.OpenMayaUI as OpenMayaUI
# from maya.app.general.mayaMixin import MayaQWidgetBaseMixin
from mayaMixin import MayaQWidgetBaseMixin

class GUI(MayaQWidgetBaseMixin, QMainWindow):
    def __init__(self):
        super(GUI, self).__init__()
        self.setCentralWidget(widget())
        self.setWindowFlags(Qt.Window|Qt.FramelessWindowHint)

class widget(QWidget):
    def __init__(self, parent=None):
        super(widget, self).__init__(parent)
        Button = QPushButton(button, self)
        Button.clicked.connect(self.close)
        VBox = QVBoxLayout()
        VBox.setObjectName(VLayout)
        VBox.addWidget(Button)
        self.setLayout(VBox)

def main():
    app = QApplication.instance()
    ex = GUI()
    ex.show()
    sys.exit()
    app.exec_()
main()

下の画像のようにうまく実行できていればbugの修正ができています

個人的な意見ですがMayaQWidgetBaseMixinはバージョンごとに更新が入っているためバージョンに互換性を持たせることを考えるのであればshibokenを使う従来の方法が無難かなーと思います