Maya PySide2 / PySide チュートリアル 初学編 ② – コピペでうまくいかない!?

python,qt,PySide,PySide2,Tutorial

このチュートリアルは、サンプルコードをコピペして、Maya上で実行したのにうまくいかないときの基本的な回避方法を学んでいきます

Qt(キュート)の公式ページにHello Worldを参考にして進めていきます

基本的にUnPySideではMayaをベースに使用するPySideを紹介いるのでOSや他のプラットフォームでは当てはまらないことがあるかもしれません
その時は公式のドキュメントなども読むことをお勧めします


MayaユーザーのPySide初学者やPython初心者でよく陥ることはサンプルコードを実行するとMayaが突然クラッシュするやコードは通ったがエラーが出る、エラーは出ないがWindowが表示しない
Windowが表示したけど突然後ろに回ってしまうというところになると思います
今回はそういった問題のコピペでうまくいかないときの回避方法を学びつつ、PySideのコードを実行してみましょう

import sys
from PySide2.QtWidgets import QApplication, QLabel

app = QApplication(sys.argv)
#label = QLabel("Hello World!")
label = QLabel("<font color=red size=40>Hello World!</font>")
label.show()
app.exec_()

出典元: Qt for Python Tutorial HelloWorld

上のコードは公式ドキュメントQt for Python Tutorial HelloWorldにあるサンプルコードになりますが、Maya上で上のコードを実行するとMayaが突然クラッシュしたり、Mayaのバージョンによってはエラーが出たりします
20210811_01
この問題はapp = QApplication(sys.argv)にあります。
デスクトップアプリケーションの場合はQt(キュート)アプリケーションのメインとなるQApplicationを作成するのですが
Mayaの場合すでにアプリケーションが実行されているため、新たにメインアプリケーション実行できませんそのため QApplication(sys.argv)QApplication.instance()に書き換えることでコードを実行できるようになります

import sys
from PySide2.QtWidgets import QApplication, QLabel

app = QApplication.instance()
#label = QLabel("Hello World!")
label = QLabel("<font color=red size=40>Hello World!</font>")
label.show()
app.exec_()

※もしくはQApplicationをimportしている部分を削除して実行することもできます

from PySide2.QtWidgets import QLabel
label = QLabel("<font color=red size=40>Hello World!</font>")
label.show()

QLabelはテキスト(htmlのようなシンプルなものやリッチなもの)や画像を提示することができるウィジェット(Widget)です。

ウィジェットとは何か

PySideのUIを構成するパーツの1単位のことで、PySideでユーザーインターフェイスを作成するための主要な要素となります
PySideではこのウィジェットに変化を加えたり、ウィジェットを組み合わせてUIを構築していきます

実行の記述がサイトによって変わり、実行できない

上では公式のページに記載されていたものを例に記述していきましたがPySideに関していろいろな書き方で実行しているサイトがあります
その中でよくある描き方が下のような書き方です

def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

この書き方のサンプルコードを実行するとMayaがクラッシュします
上の例でQApplication(sys.argv)QApplication.instance()に書き換えると記述した通り、ここはその通り書き換えてください
肝となる部分はsys.exit(app.exec_())になります
これも書き方を変える必要があります。詳しくはあえて説明しませんが下のように記述すれば実行できるようになります(最初は知らなくてもこういうものなんだーで大丈夫かと思います 気になる方は調べてみてください)

def main():
    app = QtGui.QApplication.instance()
    ex = Example()
    sys.exit()
    app.exec_()


if __name__ == '__main__':
    main()

PySideやPyQt4などで実行したい場合

Maya 2017からPySideが廃止されPySide2になっています
なので今からPySideを使用するということは今後少なくなっていることが多いかもしれませんがPySideを使用したい場合やPySideのコードをPySide2で実行したい場合は一部コードを変更する必要があります

今回のコードではfrom PySide2.QtWidgetsが変更する必要のある部分になります
from PySide2.QtWidgetsfrom PySide.QtGuiにすることで実行できるようになります
これはPySideからPySide2がリリースされた際にPySide.QtGuiに含まれていたウィジェット群が、別のQtWidgetsというモジュールに移動したからです
ちなみにPyQt4はPySide、PyQt5はPySide2にそれぞれ互換性があります
ですのでPySide2のコードをPyQt4に対応したい場合はfrom PySide2.QtWidgetsからfrom PyQt4.QtGuiになりますし
PySideのコードをPyQt5に対応したい場合はfrom PySide.QtGuiからfrom PySide5.QtWidgetsにするといいです

今回のコードの場合は下のようになります

from PySide.QtGui import QLabel
from PyQt4.QtGui import QLabel
from PySide2.QtWidgets import QLabel
from PyQt5.QtWidgets import QLabel

このほかにもtry except文を使ったり、Qt.Pyというものを使った方法もあります
やりやすい方法はQt.py を使った PySide / PyQt4とPySide2 / PyQt5開発のためのセットアップ – Maya PySide / PySide2に書いていますので参考にしてみてください

まとめ
'QApplication(sys.argv)'と記述していたら'QApplication.instance()'に書き換えるなどサンプルコードを実行するときは書き換えが必要な場合がある
ウィジェットとはPySideのUIを構成するパーツの1単位のこと

Maya PySide2 / PySide チュートリアルのこのパートでは、サンプルコードをコピペして、Maya上で実行したのにうまくいかないときの基本的な回避方法を扱いました

次はMaya PySide2 / PySide チュートリアル 初学編 ③
前はMaya PySide2 / PySide チュートリアル 初学編 ①