pipelineツールなどを作っていると、Maya専用っというよりは、スタンドアローンなアプリケーションにしたいなっと思いませんか!?
しかし、スタンドアローンなアプリケーションだと、、、
どうやって外部から
Mayaを操作するんだ!
と思う方もいらっしゃるかもしれません。
そんな時に便利なのが、Mayaコマンド「commandPort」を使って、TCPで通信してしまうっという方法です!なんだか難しそうに聞こえるかもしれませんが、、、意外と簡単にできてしまいます!(*´ω`*)
必要なimport
今回は、Qt(PySide/PyQt)を主軸に作っていきたいと思います!Pythonには「socket」というモジュールがあってTCPで通信できちゃいますが、あえて使いません!(*´ω`*)
import sys from PySide import QtCore, QtGui, QtNetwork
クラスの骨格
まずは、QWidgetを継承して、ウインドウを作りたいと思います!MELコマンドが入力できるように「QTextEdit」と、送信するための「QPushButton」も合わせて用意しておきます(`・ω・´)ゞ
import sys from PySide import QtCore, QtGui, QtNetwork class Client(QtGui.QWidget): def __init__(self, *args, **kwargs): super(Client, self).__init__(*args, **kwargs) mainLayout = QtGui.QVBoxLayout(self) self.__editor = QtGui.QTextEdit(self) self.__editor.setEnabled(False) mainLayout.addWidget(self.__editor) button = QtGui.QPushButton('Send', self) mainLayout.addWidget(button)
TCPで通信するための準備
TCPで通信するために使うのが「QTcpSocket」です!そのまんまの名前!笑
「QTcpSocket」のインスタンスを作成したら、直打ちになりますが「自分自身と、8888番のポートを使って通信」できるようにコネクションしちゃいます!
import sys from PySide import QtCore, QtGui, QtNetwork class Client(QtGui.QWidget): def __init__(self, *args, **kwargs): super(Client, self).__init__(*args, **kwargs) mainLayout = QtGui.QVBoxLayout(self) self.__editor = QtGui.QTextEdit(self) self.__editor.setEnabled(False) mainLayout.addWidget(self.__editor) button = QtGui.QPushButton('Send', self) mainLayout.addWidget(button) self.__tcpSocket = QtNetwork.QTcpSocket(self) self.__tcpSocket.connectToHost('127.0.0.1', 8888)
通信状況に応じたSignal & Slotの設定
「サーバー(Maya)」に接続できた場合は「QTextEdit」を使えるようし、何らかのエラーが発生した時にエラーメッセージを出す「Signal & Slot」の設定をします!
import sys from PySide import QtCore, QtGui, QtNetwork class Client(QtGui.QWidget): def __init__(self, *args, **kwargs): super(Client, self).__init__(*args, **kwargs) mainLayout = QtGui.QVBoxLayout(self) self.__editor = QtGui.QTextEdit(self) self.__editor.setEnabled(False) mainLayout.addWidget(self.__editor) button = QtGui.QPushButton('Send', self) button.clicked.connect(self.send) mainLayout.addWidget(button) self.__tcpSocket = QtNetwork.QTcpSocket(self) self.__tcpSocket.error.connect(self.displayError) self.__tcpSocket.connected.connect(self.connected) self.__tcpSocket.connectToHost('127.0.0.1', 8888) def connected(self): self.__editor.setEnabled(True) def displayError(self, socketError): QtGui.QMessageBox.information(self, 'Client', self.__tcpSocket.errorString())
送信する処理
ボタンをクリックされたら、「QTextEdit」に書かれた内容を送信するようにしていきます。データを送信するためには「QTcpSocket」の「write」を使えばOKですが、データを「QByteArray」にしておく必要があります!
import sys from PySide import QtCore, QtGui, QtNetwork class Client(QtGui.QWidget): def __init__(self, *args, **kwargs): super(Client, self).__init__(*args, **kwargs) mainLayout = QtGui.QVBoxLayout(self) self.__editor = QtGui.QTextEdit(self) self.__editor.setEnabled(False) mainLayout.addWidget(self.__editor) button = QtGui.QPushButton('Send', self) button.clicked.connect(self.send) mainLayout.addWidget(button) self.__tcpSocket = QtNetwork.QTcpSocket(self) self.__tcpSocket.error.connect(self.displayError) self.__tcpSocket.connected.connect(self.connected) self.__tcpSocket.connectToHost('127.0.0.1', 8888) def connected(self): self.__editor.setEnabled(True) def displayError(self, socketError): QtGui.QMessageBox.information(self, 'Client', self.__tcpSocket.errorString()) def send(self): command = self.__editor.toPlainText() data = QtCore.QByteArray(command) self.__tcpSocket.write(data)
起動時の処理
Pythonファイルが直接実行された時に、ウインドウを表示するようにします!これは、よく見かけるパターンですね!(*´ω`*)
import sys from PySide import QtCore, QtGui, QtNetwork class Client(QtGui.QWidget): def __init__(self, *args, **kwargs): super(Client, self).__init__(*args, **kwargs) mainLayout = QtGui.QVBoxLayout(self) self.__editor = QtGui.QTextEdit(self) self.__editor.setEnabled(False) mainLayout.addWidget(self.__editor) button = QtGui.QPushButton('Send', self) button.clicked.connect(self.send) mainLayout.addWidget(button) self.__tcpSocket = QtNetwork.QTcpSocket(self) self.__tcpSocket.error.connect(self.displayError) self.__tcpSocket.connected.connect(self.connected) self.__tcpSocket.connectToHost('127.0.0.1', 8888) def connected(self): self.__editor.setEnabled(True) def displayError(self, socketError): QtGui.QMessageBox.information(self, 'Client', self.__tcpSocket.errorString()) def send(self): command = self.__editor.toPlainText() data = QtCore.QByteArray(command) self.__tcpSocket.write(data) if __name__ == '__main__': app = QtGui.QApplication(sys.argv) window = Client() window.show() sys.exit(app.exec_())
実験!
拡張子を「pyw」で保存しておき余計なコンソールウインドウが出ない状態で実験してみました!