ON-BLOG

CGのこと、あれこれ書いてます。

Pyside勉強 その九

前回の記事をベースに矩形選択で取得した
ボタンの挙動を実装してみます。
まずは、ここでコントローラーのセレクトをしたいので
こちらの
3dfiggins.com
スパイダーマンリグをお借りしました。
ありがとうございます。
ちなみにここのサイトでリグ何個か買いましたが
めちゃくちゃ勉強になりました…
その節もありがとうございました。。。。。

このリグを見るとこんな感じで
かなりシンプルです。
f:id:tommy_on:20190429010651p:plain

では、このリグのセレクターをつくっていきたいと思います。
まずは、MAYA上でキャプチャーして
QtDesignerにて、前回まで使っていたUIファイルに画像を読み込みます。
f:id:tommy_on:20190429010718p:plain

背面は色のついた板をおいただけです。
この状態で、各コントローラー位置に
PushButtonを配置していきます。
こんな感じ。
f:id:tommy_on:20190429010751p:plain

ボタンの表示名(text)はわかりやすい文字で大丈夫です。
各ボタンのオブジェクト名をMAYAでセレクトするときの名前に
書き換えます。
左手のコントローラーなら
f:id:tommy_on:20190429010806p:plain
【CTRL_L__Hand】となっているので
オブジェクトも同様に変えます。
全部変えるとこんな感じになりました。
f:id:tommy_on:20190429010831p:plain

これで準備は完了です。
このオブジェクト名を見て、MAYA上でセレクトします。
このとき、ダイナミックプロパティなどを併用すると
いろんな分岐も持てるので、オススメです。
※今回は割愛

次はMAYAへ
以下のコードを実行してください。

import os
import sys

from PySide import QtCore, QtGui
from PySide.QtUiTools import QUiLoader
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin

CURRENT_PATH = "D:/"

class GUI(MayaQWidgetBaseMixin, QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(GUI, self).__init__(parent)
        loader = QUiLoader()
        uiFilePath = os.path.join(CURRENT_PATH, 'UI.ui')
        self.UI = loader.load(uiFilePath)
        self.setCentralWidget(self.UI)
        self.UI.BackGound.setPixmap(QtGui.QPixmap("D:/Selector.png"))
        self._filter = Filter()
        self.UI.widget.installEventFilter(self._filter)
        self.setWindowTitle("UI_testWindow")
        self.resize(660, 840)
        
    def test(self):
        print "Push!"

class Filter(QtCore.QObject):
    def eventFilter(self, widget, event):
        if event.type() == QtCore.QEvent.MouseButtonPress:
            self.origin = event.pos()
            self.rubberBand = QtGui.QRubberBand(QtGui.QRubberBand.Rectangle,widget)
            self.origin.setX(self.origin.x())
            self.origin.setY(self.origin.y())
            self.rubberBand.setGeometry(QtCore.QRect(self.origin,QtCore.QSize()))
            self.rubberBand.show()
            print "Click"
            print self.origin.x()
            print self.origin.y()
            
        elif event.type() == QtCore.QEvent.MouseMove:
            if self.rubberBand.isVisible():
                self.movePos = event.pos()
                self.movePos.setX(self.movePos.x()+ widget.x())
                self.movePos.setY(self.movePos.y()+ widget.y())
                self.rubberBand.setGeometry(QtCore.QRect(self.origin,self.movePos).normalized())
                print "Move"
                print event.x()
                print event.y()
            
        elif event.type() == QtCore.QEvent.MouseButtonRelease:
            print "Release"
            print event.x()
            print event.y()
            self.rubberBand.hide()
            rect = self.rubberBand.geometry()
            rect.setX(rect.x()-widget.x())
            rect.setY(rect.y()-widget.y())
            rect.setWidth(rect.width()-widget.x())
            rect.setHeight(rect.height()-widget.y())
            selected = []
            #ウィンドウ内のQPushButtonをすべて取得
            for child in widget.findChildren(QtGui.QPushButton):
            	if rect.intersects(child.geometry()):
                    selected.append(child)
            if selected:
                self.rectSelection(selected)

        return False

    def rectSelection(self,sel):
        selectBox = []
        for i in sel:
            selectBox.append(i.objectName())

        cmds.select(selectBox)


def main():
    app = QtGui.QApplication.instance()
    ui = GUI()
    ui.show()

if __name__ == '__main__':
    main()


実行すると以下のウィンドウが表示されます。
f:id:tommy_on:20190429011344p:plain
UIがめちゃくちゃでかいですが、気にしないでくださいw
矩形選択でボタンを含めると、コントローラーが選択できているはずです。
f:id:tommy_on:20190429011056p:plain
↓↓↓↓↓↓↓↓
f:id:tommy_on:20190429011013p:plain

ではコードの説明を
実はほとんど前回から変わってないです。
以下の関数の箇所だけです。

    def rectSelection(self,sel):
        selectBox = []
        for i in sel:
            selectBox.append(i.objectName())

        cmds.select(selectBox)

内容はシンプルで
矩形内のボタンを取得して
それのForで回して、ボタンのオブジェクト名を
配列に格納し、最後に選択しています。
まぁ単純です。

が、これでおおよそ目的は達したと思います。
ただ今はボタンを押しても効かないので
最後にボタンのクリックなどを実装してみたいと思います。


以上です