Files
2026-08-03 18:42:47 +08:00

169 lines
4.6 KiB
Python

'''
PyMOL Plugins Engine, Legacy Support
This module overloads PyMOLs PMGApp class which so far handles plugin support.
It also provides a get_pmgapp() function that either returns the actual PMGApp
instance, or a fake instance with "root" and "menuBar" properties which can be
used if PMGApp has retired.
(c) 2011-2012 Thomas Holder, PyMOL OS Fellow
License: BSD-2-Clause
'''
import sys
import os
import pymol
from pmg_tk import startup
__all__ = [
'startup',
'get_pmgapp',
'get_tk_root',
'get_tk_focused',
]
def get_pmgapp():
'''
Returns the PMGApp instance.
'''
import pymol.gui
return pymol.gui.get_pmgapp()
def get_tk_root():
'''
Returns the Tk master instance.
'''
return get_pmgapp().root
def get_tk_focused():
'''
Return the Tk widget which has currently the focus.
'''
if 'pmg_qt.mimic_tk' in sys.modules:
return None
root = get_tk_root()
focused = root.focus_get()
if focused is None:
return root.focus_lastfor()
return focused
def installPlugin(self):
'''
Overloaded version of pmg_tk.PMGApp.installPlugin
Open dialog to install plugin
'''
from .installation import zip_extensions, installPluginFromFile
# ask for file; to install a directory, point to its __init__.py file
filetypes = [('Python Files', '*.py')] + \
[('Archives', '*.' + ext) for ext in zip_extensions]
filetypes = [('All Files', pattern) for (_, pattern) in filetypes] + filetypes
ofile = tkFileDialog.askopenfilename(title='Install Plugin',
initialdir=os.getcwd(),
filetypes=filetypes)
if len(ofile):
installPluginFromFile(ofile)
plugin_manager_panel = None
def addPluginManagerMenuItem():
def plugin_manager():
global plugin_manager_panel
from pymol.gui import get_qtwindow as getPyMOLWindow
window = getPyMOLWindow()
if window:
if not plugin_manager_panel:
from .managergui_qt import PluginManager
plugin_manager_panel = PluginManager(None)
plugin_manager_panel.show()
else:
from . import managergui
managergui.manager_dialog()
pymol.plugins.addmenuitem('Plugin Manager', plugin_manager)
pymol.plugins.addmenuitem('-', None)
def initializePlugins(self):
'''
Overloaded version of pmg_tk.PMGApp.initializePlugins
Initializes already loaded plugins.
'''
from pymol.invocation import options
from . import plugins, addmenuitem
if not options.plugins:
return
# Load plugin manager independent of other plugins
addPluginManagerMenuItem()
if options.plugins == 2:
from . import initialize
return initialize(self)
for info in plugins.values():
if info.loaded:
info.legacyinit(self)
def createlegacypmgapp():
'''
Start a Tk app in separate thread.
Returns a "fake" PMGApp instance for legacy support
'''
app = pymol.Scratch_Storage()
app.root = None
app.menuBar = pymol.Scratch_Storage()
app.menuBar.addmenuitem = \
app.menuBar.deletemenuitems = \
app.menuBar.addcascademenu = lambda *x, **y: None
app.execute = lambda c: eval(c) if isinstance(c, str) else c()
return app
# wrappers for tkMessageBox and tkFileDialog that always use the current
# focused widget as parent
class _tkMessageBox(object):
def __getattr__(self, name):
try:
# pmg_qt.mimic_tk provides this for all Python versions
import tkMessageBox as module
except ImportError:
import tkinter.messagebox as module
from . import pref_get
wrapped = getattr(module, name)
def dialog(title, message, parent=None, **kwargs):
if parent is None:
parent = get_tk_focused()
if pref_get('verbose'):
print(' ' + title + ': ' + message)
return wrapped(title, message, parent=parent, **kwargs)
setattr(self, name, dialog)
return dialog
class _tkFileDialog(object):
def __getattr__(self, name):
try:
# pmg_qt.mimic_tk provides this for all Python versions
import tkFileDialog as module
except ImportError:
import tkinter.filedialog as module
wrapped = getattr(module, name)
def dialog(parent=None, *args, **kwargs):
if parent is None:
parent = get_tk_focused()
return wrapped(*args, parent=parent, **kwargs)
setattr(self, name, dialog)
return dialog
tkMessageBox = _tkMessageBox()
tkFileDialog = _tkFileDialog()
# vi:expandtab:smarttab:sw=4