2017年3月2日木曜日

PySide2 対応メモ

PySide で作成していたツールを Houdini 16 で動かすには?


2017 3/10 : pyqt4topyqt5.py 追記 & 全体の構成を編集



Qt.py


@_ShoHey_ さんに教えてもらいました m(_ _)m

/houdini/python2.7libs/hutil

Qt.py を使うことで PySide2 のコードを他のバインディング( PySide など )でも動作するようにできるみたいです
中身はこんな感じ
def _pyside():
    import PySide
    from PySide import QtGui, QtCore, QtUiTools

    _remap(PySide, "QtWidgets", QtGui)
    _remap(QtCore, "QSortFilterProxyModel", QtGui.QSortFilterProxyModel)
    _remap(QtCore, "QStringListModel", QtGui.QStringListModel)
    _remap(QtCore, "QItemSelection", QtGui.QItemSelection)
    _remap(QtCore, "QItemSelectionModel", QtGui.QItemSelectionModel)
    _remap(QtCore, "QAbstractProxyModel", QtGui.QAbstractProxyModel)

PySide2 のコードに移行しておけば下位互換できるってことかな?

_pyside() を見れば PySide2 でどこを変更すればOKか分かります!


詳しくはこちらを参照して下さい

Minimal Python 2 & 3 shim around all Qt bindings - PySide, PySide2, PyQt4 and PyQt5. 

Dealing with Maya 2017 and PySide2



というわけで、PySide2 へ変換するには?



pyqt4topyqt5.py


pyqt4topyqt5.py でさっくりできるのか・・・?

こんな感じで PyQt4 を使っていれば QtGui → QtWidgets などが変換できました!
from PyQt4 import QtCore, QtGui, uic

残念ながら PySide では変換出来ませんでした
from PySide import QtCore, QtGui, QtWebKit

pyqt4topyqt5.py 内でこんな感じに判定して処理してました
if line.lstrip().startswith(('import ', 'from ')) and 'PyQt4' in line:
    qt4 = True
    if '.Qt' in line:
        gui = True
        web = True
    if 'QtGui' in line:
        gui = True
    if 'QtWebKit' in line:
        web = True
    if all([sig, gui, web]):
        break


PyQt4 にしてから pyqt4topyqt5.py すれば動作しそうです

ただ、改行がたくさん追加 されたりしたので、ちょっと難あり かもしれません


この方法はうまくいけばラッキーくらいに考えたほうが良さそうですね・・・
こちらにも 運試しできるよ って書いてありました (^^)

Convert PyQt4 code into PyQt5 code
There’s a magical conversion script you can try your luck with...



置換する


というわけで、手動で置換してみる場合の注意点

モジュールを置き換えて、QtGui → QtWidgets でいける! と思いきや...

このへんは Gui のまま
QtGui.QPen
QtGui.QFont
QtGui.QIcon
QtGui.QColor
QtGui.QImage
QtGui.QCursor
QtGui.QPalette
QtGui.QStandardItemModel

このへんは Core
QtCore.QItemSelection
QtCore.QItemSelectionModel
QtCore.QStringListModel
QtCore.QAbstractProxyModel
QtCore.QSortFilterProxyModel
僕はそれほどツールを作ってなかったので手間ではありませんでしたが
便利な変換ツールがあったら教えて下さい!



pyside-uic.exe


 .ui を変換した .py 使っている場合は

retranslateUi() 内の QApplication.UnicodeUTF8 を削除

Qt5 で QApplication.UnicodeUTF8 は Obsolete members になっています
全てに UTF8 適用されるから必要なくなったそうです


ただ、Qt4 では正しく動作しなくなってしまうので
下位互換が必要な場合はダミーの関数を設定すればOK?
setattr( QtWidgets.QApplication, 'UnicodeUTF8', -1 )



Houdini 15 でも動かす


H15 では Qt.py が標準で入っていないので、とりあえずこれでも動く...?
try:

    # H16~
    from hutil.Qt import QtGui, QtCore, QtWidgets

except:

    from PySide import QtGui, QtCore
    from PySide import QtGui as QtWidgets


H15 で Qt.py を試したら、ここの処理がうまくいかないようでした...?
_add(PySide, "setSectionResizeMode", QtGui.QHeaderView.setResizeMode)

ひとまず setattr で対応しました
setattr( QtWidgets.QHeaderView, 'setSectionResizeMode', QtWidgets.QHeaderView.setResizeMode )



とりあえず動きました (^^)

H16~ は
from hutil.Qt import QtGui, QtCore, QtWidgets
を使うのが良さそうです


もっと良い方法あれば教えてください!



環境

windows 10
houdini-16.0.504.20-win64-vc14.exe

0 件のコメント:

コメントを投稿