[PYTHON] Think about plug-in system-like things-dynamic import-

There is a "plug-in" system for adding functions in Maya and Photoshop, It is a memo that I can provide such a thing in my own tool.

importlib

Specifically, use the "importlib" module.

-** importlib — Convenient wrapper for import () ** (Python documentation-standard library) http://docs.python.jp/2/library/importlib.html

By passing ** module name ** as a string to the "import_module" function of this module,

import hogehoge

You can import modules regardless of how they are written. Since it receives a character string, it seems that you can import the module you found while entering it at any time.

Only ** import_module ** is used, so import and use it like this.

from importlib import import_module

(The frequency of appearance of the character string import ...)

Hooking point

1: Try to pass with an absolute pass

I misunderstood that I was passing a Python file, so I wrote it like this.

pluginPath = 'path/to/plugin'

for plugin in os.listdir(pluginPath):
    mod_path = os.path.join(pluginPath,plugin)
    mod = import_module(mod_path,)

It was bad. Pass in the module name. Also, for that, the location where the Python file for the plugin is placed Must be added to sys.path.append. In addition, the extension of the found Python file must be removed. Only the module name is passed.

pluginPath = 'path/to/plugin'
sys.path.append(pluginPath)

for plugin in os.listdir(pluginPath):
    mod_name = os.path.splitext(plugin)[0]
    mod = import_module(mod_name,)

Now you can add the Python file to your plugins folder and it will be imported.

2: pyc gets in the way

Now it imports, If you can import it, you can make pyc. I don't want you to read it.

#Omission

for plugin in os.listdir(pluginPath):
    split_name = os.path.splitext(plugin)
    if split_name[1] == '.pyc':
        continue
    mod = import_module(split_name[0],)

Increase the number of buttons by the number of plugins found

After that, arrange as many buttons as you find.

plugin.py spec

It's not a specification, but We promise in advance the function to use the function of the plug-in. You can think of ʻexec, doIt, or run`.

Also, make sure that the module has a label on the button.

plugin.py



LABEL = 'create poly sphere'

"""
some your scripts...
"""

def exec():
    pass

# or

def doIt():
    pass

# or

def run():
    pass

#-----------------------------------------------------------------------------
# EOF
#-----------------------------------------------------------------------------

Connect module_name.exec (etc.) to the button

Connect to button

Create a QPushButton and pass the execution function you decided earlier to .clicked.connect.

btn = QtGui.QPushButton( mod.LABEL )
btn.clicked.connect(mod.exec)

Add this to the module reading for statement.

Summary

import os
import sys

from PySide import QtCore, QtGui
from importlib import import_module

pluginPath = 'path/to/plugin'
sys.path.append(pluginPath)

for plugin in os.listdir(pluginPath):
    split_name = os.path.splitext(plugin)
    if split_name[1] == '.pyc':
        continue
    mod = import_module(split_name[0],)

    btn = QtGui.QPushButton( mod.LABEL )
    btn.clicked.connect(mod.exec)

You can put something like this somewhere in the script that makes the GUI.

After all, it took the longest When I tried to pass the absolute path to import_module, I was groaning "I can't pass" It was around when I typed ~~ and plugin as ** pluing ** ...

Read the documentation carefully!


See also here for the GUI part

-[Complement] [PySide] Let's play with Qt Designer http://qiita.com/it_ks/items/449b7418e83956ecdc8c

reference?

--First Maya Python plug-in http://help.autodesk.com/view/MAYAUL/2017/JPN/?guid=__files_GUID_B968733D_B288_4DAF_9685_4676DC3E4E94_1_htm

Recommended Posts

Think about plug-in system-like things-dynamic import-
About import
Think about architecture in python
Think about dropouts with MNIST