さて!
pythonでUIを作るのはだいぶこなれてきた。
ちょっとした応用としてすでに起動したツールの関数を実行してみる。
まずは適当なUIと関数を準備する。
# Copyright (C) # Author: # Contact: r"""test window """ from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals import MaxPlus # この書き方は乱暴すぎる try: from PySide2.QtWidgets import * from PySide2.QtGui import * from PySide2.QtCore import * UNICODE = -1 except ImportError: from PySide.QtGui import * from PySide.QtCore import * UNICODE = QApplication.UnicodeUTF8 class MyWindow(QMainWindow): # QDockWidgetとするとドッキング可能になる QMainWindow def __init__(self, *args, **kw): QMainWindow.__init__(self, *args, **kw) self.setObjectName("MyWindow") self.setWindowTitle("MyWindow") # セントラルを作成 self.centralwidget = QWidget(self) self.centralwidget.setObjectName("centralwidget") # たてレイアウト追加 self.verticalLayout = QVBoxLayout(self.centralwidget) self.verticalLayout.setObjectName("verticalLayout") self.pybt = QPushButton(self) self.pybt.setGeometry(QRect(4, 24, 120, 24)) self.pybt.setObjectName("Run_Python_Func") self.pybt.setText("Run_Python_Func") self.pybt.clicked.connect(self.test_func) self.verticalLayout.addWidget(self.pybt) # たてレイアウトに追加 self.setCentralWidget(self.centralwidget) # セントラルを最後に追加 self.resize(240, 260) QMetaObject.connectSlotsByName(self) def test_func(self): r"""python func""" print("python関数実行") def closeEvent(self, event): r"""close event override""" # 閉じたあとで破棄 self.deleteLater() class _GCProtector(object): r"""maxの場合は必要""" widgets = [] def close_tool_window(wname): widgets = QApplication.allWidgets() for w in widgets: if w.objectName() == wname: print("Closed : {}".format(w.objectName())) w.close() def get_parent_window(): r"""親となるウィンドウを取得する Max2018の場合はMaxPlus.GetQMaxMainWindow()で取得 """ ver = MaxPlus.Core.GetMaxVersion() if ver < 1300000000: parent_window = MaxPlus.GetQMaxWindow() else: parent_window = MaxPlus.GetQMaxMainWindow() return parent_window def main(): r"""main""" app = QApplication.instance() if not app: app = QApplication([]) close_tool_window("MyWindow") win = MyWindow(get_parent_window()) _GCProtector.widgets.append(win) # MaxPlus.MakeQWidgetDockable(win, 4) # Maxではこれでドッキング可能になる # win.setFloating(True) # dockingwidgetの場合はfloatをtrueにすると切り離しが出来る win.show() if __name__ == '__main__': main()
今回はこれで作ったUI上(pythonオブジェクト)にある関数を実行してみる。
まず上のソースを実行すると結果がこうなる。
で、このボタンで実行する内容を
スクリプトで呼び出してみる。
ツールで実行している内容をスクリプトで実行出来れば、
AツールからBツールの関数を呼び出したり、その逆もできる。
こうすれば色んな応用ができるからツール作っている側としてはありがたい。
方法はクッソ簡単。
# この書き方は乱暴すぎる try: from PySide2.QtWidgets import * from PySide2.QtGui import * from PySide2.QtCore import * except ImportError: from PySide.QtGui import * from PySide.QtCore import * def run_tool_window_func(wname): widgets = QApplication.allWidgets() for w in widgets: if w.objectName() == wname: # 味噌はここ、MyWindowにぶら下がってる関数を使う w.test_func() run_tool_window_func("MyWindow")
結局方法はwindowを事前に閉じる方法と同じで
まずQApplication.allWidgets()の中から特定の名前のウィジットを見つけてきて
そのウィジット内の関数を呼び出すだけ。
実行結果は・・・
ウィジットと言えどオブジェクトの一つなので、こんな振る舞いが出来る。
というか、こうするとウィジットを作るソースで読まれているモジュールなら
何でも使う事が出来る。
というか・・・もうちょっと基本に戻れば
結局はメソッドをもったクラスオブジェクトを生成しているにすぎないので・・・
# あくまでsysにパスを通した状態で実行 import test_tool test_tool.MyWindow().test_func()
これと同意語と言っても問題ない。
この辺が理解出来るとpythonがより一層便利に感じて来る。
なにせpythonが動かせる環境なら同じ手法が取り入れられるから。
ということで、今日のメモでした~~~