以下の Python スクリプトを丸ごとペーストして Python Source Editor で実行すると問題なく実行できるが、Python Shell で実行するとフリースするかクラッシュする。この問題の原因と対処を紹介する。
from PySide2.QtCore import QUrl
from PySide2.QtWidgets import QMainWindow
from PySide2.QtWebEngineWidgets import QWebEngineView
import os
import sys
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.browser = QWebEngineView()
self.setCentralWidget(self.browser)
window = MainWindow()
window.show()
使用したビルド:
- Houdini 19.5.534/569 (Py3.9)
Python Shell
上のスクリプトを Python Shell にそのままペーストし、Enter キーで実行すると、エラーが出てクラッシュするか、エラーなしでフリーズするなど、好ましくない結果になる。
Python Source Editor
上のスクリプトを Python Source Editor の上段にペーストして Apply ボタンをクリックすると、まっさらなウィンドウが現れる。クラッシュもせず、エラーも現れない。
原因と解決策
Python Shell からの実行時にクラッシュ・フリーズの原因となっているのは、PySide2/Qt が、その仕様上、 Houdini のメインスレッド上で実行されなければならないから。スクリプトを Houdini のメインスレッドで実行するには hdefereval という関数を使い、以下のように書き換える。
import hdefereval
def showMainWindow():
from PySide2.QtCore import QUrl
from PySide2.QtWidgets import QMainWindow
from PySide2.QtWebEngineWidgets import QWebEngineView
import os
import sys
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.browser = QWebEngineView()
self.setCentralWidget(self.browser)
window = MainWindow()
window.show()
# Assign the new window object to a persistent attribute in the hou.session module to keep the window alive.
hou.session.window = window
hdefereval.executeDeferred(showMainWindow)
このスクリプトであれば、Python Source Editor にペーストして Apply を押しても、例えば、このファイルを C:/tmp/open_window.py として配置し、Python Shell で以下のように実行してもウィンドウが作成できる。
with open("C:/tmp/open_window.py","r") as f:
exec(f.read())
なお、hdefereval の詳細は $HHP/hdefereval.py にある。
0 件のコメント:
コメントを投稿