MayaのツールをPythonで作る際、QtDesignerを使ってみたかったので学習してみました。
その時の備忘録を残します。
今回は、デスクトップに作ったUIを表示させる、をゴールにします。
用意したファイル
mittsuUI_test.uimittsuUI_test.pymittsuUI_show.py
今回使うファイルは上記の3つです。
作業の流れは、
- QtDesignerでGUIを作る。
 - 作ったGUIをPython(PySide2)に変換する
 - 2を表示するファイルを作る
 - 3をターミナルで実行して完了
 
このような流れです。
※PythonとPySide2はインストール済みとします。
使用ファイルの内容
mittsuUI_test.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>494</width>
    <height>305</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <widget class="QWidget" name="layoutWidget">
   <property name="geometry">
    <rect>
     <x>61</x>
     <y>101</y>
     <width>326</width>
     <height>68</height>
    </rect>
   </property>
   <layout class="QHBoxLayout" name="horizontalLayout">
    <item>
     <widget class="QLabel" name="label">
      <property name="minimumSize">
       <size>
        <width>100</width>
        <height>0</height>
       </size>
      </property>
      <property name="text">
       <string>mittsu</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QLineEdit" name="lineEdit">
      <property name="minimumSize">
       <size>
        <width>100</width>
        <height>0</height>
       </size>
      </property>
     </widget>
    </item>
    <item>
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <widget class="QPushButton" name="pushButton">
        <property name="text">
         <string>OK</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="pushButton_2">
        <property name="text">
         <string>Cancel</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>pushButton</sender>
   <signal>clicked()</signal>
   <receiver>Dialog</receiver>
   <slot>accept()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>344</x>
     <y>113</y>
    </hint>
    <hint type="destinationlabel">
     <x>351</x>
     <y>50</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>pushButton_2</sender>
   <signal>clicked()</signal>
   <receiver>Dialog</receiver>
   <slot>reject()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>367</x>
     <y>151</y>
    </hint>
    <hint type="destinationlabel">
     <x>395</x>
     <y>201</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>lineEdit</sender>
   <signal>textChanged(QString)</signal>
   <receiver>label</receiver>
   <slot>setText(QString)</slot>
   <hints>
    <hint type="sourcelabel">
     <x>197</x>
     <y>129</y>
    </hint>
    <hint type="destinationlabel">
     <x>101</x>
     <y>137</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>
mittsuUI_test.py の内容
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'mittsuUI-test.ui'
##
## Created by: Qt User Interface Compiler version 5.15.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
class Ui_Dialog(object):
    def setupUi(self, Dialog):
        if not Dialog.objectName():
            Dialog.setObjectName(u"Dialog")
        Dialog.resize(494, 305)
        self.layoutWidget = QWidget(Dialog)
        self.layoutWidget.setObjectName(u"layoutWidget")
        self.layoutWidget.setGeometry(QRect(61, 101, 326, 68))
        self.horizontalLayout = QHBoxLayout(self.layoutWidget)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.label = QLabel(self.layoutWidget)
        self.label.setObjectName(u"label")
        self.label.setMinimumSize(QSize(100, 0))
        self.horizontalLayout.addWidget(self.label)
        self.lineEdit = QLineEdit(self.layoutWidget)
        self.lineEdit.setObjectName(u"lineEdit")
        self.lineEdit.setMinimumSize(QSize(100, 0))
        self.horizontalLayout.addWidget(self.lineEdit)
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.pushButton = QPushButton(self.layoutWidget)
        self.pushButton.setObjectName(u"pushButton")
        self.verticalLayout.addWidget(self.pushButton)
        self.pushButton_2 = QPushButton(self.layoutWidget)
        self.pushButton_2.setObjectName(u"pushButton_2")
        self.verticalLayout.addWidget(self.pushButton_2)
        self.horizontalLayout.addLayout(self.verticalLayout)
        self.retranslateUi(Dialog)
        self.pushButton.clicked.connect(Dialog.accept)
        self.pushButton_2.clicked.connect(Dialog.reject)
        self.lineEdit.textChanged.connect(self.label.setText)
        QMetaObject.connectSlotsByName(Dialog)
    # setupUi
    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Dialog", None))
        self.label.setText(QCoreApplication.translate("Dialog", u"mittsu", None))
        self.pushButton.setText(QCoreApplication.translate("Dialog", u"OK", None))
        self.pushButton_2.setText(QCoreApplication.translate("Dialog", u"Cancel", None))
    # retranslateUi
mittsuUI_show.py の内容
# -*- coding: utf-8 -*-
import sys
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from mittsuUI_test import Ui_Dialog
class Test(QDialog):
    def __init__(self,parent=None):
        super(Test, self).__init__(parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Test()
    window.show()
    sys.exit(app.exec_())
QtDesignerの使い方はこちらの『QtDesignerでUIを作る』記事を参考にしました。
QtDesignerの使い方が気になる人は上記を参考にして下さい。
.uiファイルを.pyファイルに変換する
QtDesignerでGUIを作り終えたら、.uiファイルで保存されます。
そのままでは使えないので、pyside2-uic というコマンドを使って、Pythonファイルに変換していきます。
『pyside2-uic』を使ってのファイル変換
ターミナルで、
pyside2-uic -o ****.py ****.ui
って感じで、Pythonファイルの名前を書いて、その後に置き換えたい.ui ファイルの名前を指定します。
今回の場合なら、
pyside2-uic -o mittsuUI_test.py mittsuUI_test.ui
みたいな感じです。
ターミナルでの実行は、カレントフォルダにいることを確認してください。
これってマジで重要です。
私はいつも忘れます。
GUIを表示する処理を書く
上記で変換したPythonファイルは、GUIの情報が書かれてるだけなので、GUIを表示させるって処理を書いていきます。
# -*- coding: utf-8 -*-
import sys
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from mittsuUI_test import Ui_Dialog
class Test(QDialog):
    def __init__(self,parent=None):
        super(Test, self).__init__(parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Test()
    window.show()
    sys.exit(app.exec_())
mittsuUI_show.pyの中身はこんな感じです。
先程作ったmittsuUI_test.py の中のクラスをインポートし、そのクラスを継承して〜
って処理ですが、、、。
正直、まだ100%理解できてないんですよね...。
具体的には、
if __name__ == '__main__':app = QApplication(sys.argv)sys.exit(app.exec_())
この3つが、まだよくわかってない。
実行したら表示される。
されるんだが、なぜ表示されるかは理解できてない。
まぁとりあえず、こういうものなんだなくらいの認識で進めます。
止まってても仕方ないですしね...。
ターミナルでPythonファイルを実行しGUIを表示させる
上記で作ったPythonファイル、mittsuUI_show.py をターミナルで実行し、GUIを表示させます。
ターミナルで実行するコマンド
今回はデスクトップに work ってフォルダを作り、その中に 20210321-PySide2 ってフォルダを作って作業してます。
パスでいうと、
desktop/work/20210321-PySide2
です。
なので cd コマンドを使い、そこに移動します。
カレントフォルダが20210321-PySide2 になってることを確認して、
python3 mittsuUI_show.py
を実行します。
Mayaでも表示してみる
Mayaではこんな感じです。
Mayaのスクリプトエディタで実行する場合は、ちょっと改変する必要がありますが、この記事は一旦ここで終わります。
一応スクリプトエディタに書くコードだけ載せておきます。
何かの参考にしてくれると幸いです。
mayaのスクリプトエディタに書くコード
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'mittsuUI-test.ui'
##
## Created by: Qt User Interface Compiler version 5.15.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
# from mittsuUI_test import Ui_Dialog ここはコメントアウト
class Ui_Dialog(object):
    def setupUi(self, Dialog):
        if not Dialog.objectName():
            Dialog.setObjectName(u"Dialog")
        Dialog.resize(494, 305)
        self.layoutWidget = QWidget(Dialog)
        self.layoutWidget.setObjectName(u"layoutWidget")
        self.layoutWidget.setGeometry(QRect(61, 101, 326, 68))
        self.horizontalLayout = QHBoxLayout(self.layoutWidget)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.label = QLabel(self.layoutWidget)
        self.label.setObjectName(u"label")
        self.label.setMinimumSize(QSize(100, 0))
        self.horizontalLayout.addWidget(self.label)
        self.lineEdit = QLineEdit(self.layoutWidget)
        self.lineEdit.setObjectName(u"lineEdit")
        self.lineEdit.setMinimumSize(QSize(100, 0))
        self.horizontalLayout.addWidget(self.lineEdit)
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.pushButton = QPushButton(self.layoutWidget)
        self.pushButton.setObjectName(u"pushButton")
        self.verticalLayout.addWidget(self.pushButton)
        self.pushButton_2 = QPushButton(self.layoutWidget)
        self.pushButton_2.setObjectName(u"pushButton_2")
        self.verticalLayout.addWidget(self.pushButton_2)
        self.horizontalLayout.addLayout(self.verticalLayout)
        self.retranslateUi(Dialog)
        self.pushButton.clicked.connect(Dialog.accept)
        self.pushButton_2.clicked.connect(Dialog.reject)
        self.lineEdit.textChanged.connect(self.label.setText)
        QMetaObject.connectSlotsByName(Dialog)
    # setupUi
    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Dialog", None))
        self.label.setText(QCoreApplication.translate("Dialog", u"mittsu", None))
        self.pushButton.setText(QCoreApplication.translate("Dialog", u"OK", None))
        self.pushButton_2.setText(QCoreApplication.translate("Dialog", u"Cancel", None))
    # retranslateUi
class Test(QDialog):
    def __init__(self,parent=None):
        super(Test, self).__init__(parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
if __name__ == '__main__':
    #app = QApplication(sys.argv)
    window = Test()
    window.show()
    #sys.exit(app.exec_())
所感
- QtDesignerでGUIを作る
 - それをMayaで表示させる
 
このたった2行をやるためだけに、どれだけの地雷を踏んだことやら、、、。
とりあえずクラスの概要を掴むことはできた。
フレームワーク、モジュール、クラス、メソッド、、、。
この辺も大体理解しかけてる。
あとは特殊メソッドって呼ばれるやつの把握や、MayaでPythonを扱う上でのお作法。
この辺を理解できたら、およそのツールは作れるんじゃなかろうか…。
って感じましたね。
まぁとりあえずは、
アルファベットの羅列を、インターフェースっていう、目に見える形に変換出来ただけでも進歩したと思いましょう。
ここからやな、楽しいのは。


