Ajout du GUI
This commit is contained in:
300
kivy/modules/__init__.py
Normal file
300
kivy/modules/__init__.py
Normal file
@@ -0,0 +1,300 @@
|
||||
'''
|
||||
Modules
|
||||
=======
|
||||
|
||||
Modules are classes that can be loaded when a Kivy application is starting. The
|
||||
loading of modules is managed by the config file. Currently, we include:
|
||||
|
||||
* :class:`~kivy.modules.touchring`: Draw a circle around each touch.
|
||||
* :class:`~kivy.modules.monitor`: Add a red topbar that indicates the FPS
|
||||
and a small graph indicating input activity.
|
||||
* :class:`~kivy.modules.keybinding`: Bind some keys to actions, such as a
|
||||
screenshot.
|
||||
* :class:`~kivy.modules.recorder`: Record and playback a sequence of
|
||||
events.
|
||||
* :class:`~kivy.modules.screen`: Emulate the characteristics (dpi/density/
|
||||
resolution) of different screens.
|
||||
* :class:`~kivy.modules.inspector`: Examines your widget hierarchy and
|
||||
widget properties.
|
||||
* :class:`~kivy.modules.webdebugger`: Realtime examination of your app
|
||||
internals via a web browser.
|
||||
* :class:`~kivy.modules.joycursor`: Navigate in your app with a joystick.
|
||||
* :class:`~kivy.modules.showborder`: Show widget's border.
|
||||
|
||||
Modules are automatically loaded from the Kivy path and User path:
|
||||
|
||||
* `PATH_TO_KIVY/kivy/modules`
|
||||
* `HOME/.kivy/mods`
|
||||
|
||||
Activating a module
|
||||
-------------------
|
||||
|
||||
There are various ways in which you can activate a kivy module.
|
||||
|
||||
Activate a module in the config
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To activate a module this way, you can edit your configuration file (in your
|
||||
`HOME/.kivy/config.ini`)::
|
||||
|
||||
[modules]
|
||||
# uncomment to activate
|
||||
touchring =
|
||||
# monitor =
|
||||
# keybinding =
|
||||
|
||||
Only the name of the module followed by "=" is sufficient to activate the
|
||||
module.
|
||||
|
||||
Activate a module in Python
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Before starting your application, preferably at the start of your import, you
|
||||
can do something like this::
|
||||
|
||||
import kivy
|
||||
kivy.require('1.0.8')
|
||||
|
||||
# Activate the touchring module
|
||||
from kivy.config import Config
|
||||
Config.set('modules', 'touchring', '')
|
||||
|
||||
Activate a module via the commandline
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When starting your application from the commandline, you can add a
|
||||
*-m <modulename>* to the arguments. For example::
|
||||
|
||||
python main.py -m webdebugger
|
||||
|
||||
.. note::
|
||||
Some modules, such as the screen, may require additional parameters. They
|
||||
will, however, print these parameters to the console when launched without
|
||||
them.
|
||||
|
||||
|
||||
Create your own module
|
||||
----------------------
|
||||
|
||||
Create a file in your `HOME/.kivy/mods`, and create 2 functions::
|
||||
|
||||
def start(win, ctx):
|
||||
pass
|
||||
|
||||
def stop(win, ctx):
|
||||
pass
|
||||
|
||||
Start/stop are functions that will be called for every window opened in
|
||||
Kivy. When you are starting a module, you can use these to store and
|
||||
manage the module state. Use the `ctx` variable as a dictionary. This
|
||||
context is unique for each instance/start() call of the module, and will
|
||||
be passed to stop() too.
|
||||
|
||||
'''
|
||||
|
||||
__all__ = ('Modules', )
|
||||
|
||||
from kivy.config import Config
|
||||
from kivy.logger import Logger
|
||||
import kivy
|
||||
import importlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
class ModuleContext:
|
||||
'''Context of a module
|
||||
|
||||
You can access to the config with self.config.
|
||||
'''
|
||||
|
||||
def __init__(self):
|
||||
self.config = {}
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.config)
|
||||
|
||||
|
||||
class ModuleBase:
|
||||
'''Handle Kivy modules. It will automatically load and instantiate the
|
||||
module for the general window.'''
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.mods = {}
|
||||
self.wins = []
|
||||
|
||||
def add_path(self, path):
|
||||
'''Add a path to search for modules in'''
|
||||
if not os.path.exists(path):
|
||||
return
|
||||
if path not in sys.path:
|
||||
sys.path.append(path)
|
||||
dirs = os.listdir(path)
|
||||
for module in dirs:
|
||||
name, ext = os.path.splitext(module)
|
||||
# accept only python extensions
|
||||
if ext not in ('.py', '.pyo', '.pyc') or name == '__init__':
|
||||
continue
|
||||
self.mods[name] = {
|
||||
'name': name,
|
||||
'activated': False,
|
||||
'context': ModuleContext()}
|
||||
|
||||
def list(self):
|
||||
'''Return the list of available modules'''
|
||||
return self.mods
|
||||
|
||||
def import_module(self, name):
|
||||
try:
|
||||
modname = 'kivy.modules.{0}'.format(name)
|
||||
module = importlib.__import__(name=modname)
|
||||
module = sys.modules[modname]
|
||||
except ImportError:
|
||||
try:
|
||||
module = importlib.__import__(name=name)
|
||||
module = sys.modules[name]
|
||||
except ImportError:
|
||||
Logger.exception('Modules: unable to import <%s>' % name)
|
||||
# protect against missing module dependency crash
|
||||
self.mods[name]['module'] = None
|
||||
return
|
||||
# basic check on module
|
||||
if not hasattr(module, 'start'):
|
||||
Logger.warning('Modules: Module <%s> missing start() function' %
|
||||
name)
|
||||
return
|
||||
if not hasattr(module, 'stop'):
|
||||
err = 'Modules: Module <%s> missing stop() function' % name
|
||||
Logger.warning(err)
|
||||
return
|
||||
self.mods[name]['module'] = module
|
||||
|
||||
def activate_module(self, name, win):
|
||||
'''Activate a module on a window'''
|
||||
if name not in self.mods:
|
||||
Logger.warning('Modules: Module <%s> not found' % name)
|
||||
return
|
||||
|
||||
mod = self.mods[name]
|
||||
|
||||
# ensure the module has been configured
|
||||
if 'module' not in mod:
|
||||
self._configure_module(name)
|
||||
|
||||
pymod = mod['module']
|
||||
if not mod['activated']:
|
||||
context = mod['context']
|
||||
msg = 'Modules: Start <{0}> with config {1}'.format(
|
||||
name, context)
|
||||
Logger.debug(msg)
|
||||
pymod.start(win, context)
|
||||
mod['activated'] = True
|
||||
|
||||
def deactivate_module(self, name, win):
|
||||
'''Deactivate a module from a window'''
|
||||
if name not in self.mods:
|
||||
Logger.warning('Modules: Module <%s> not found' % name)
|
||||
return
|
||||
if 'module' not in self.mods[name]:
|
||||
return
|
||||
|
||||
module = self.mods[name]['module']
|
||||
if self.mods[name]['activated']:
|
||||
module.stop(win, self.mods[name]['context'])
|
||||
self.mods[name]['activated'] = False
|
||||
|
||||
def register_window(self, win):
|
||||
'''Add the window to the window list'''
|
||||
if win not in self.wins:
|
||||
self.wins.append(win)
|
||||
self.update()
|
||||
|
||||
def unregister_window(self, win):
|
||||
'''Remove the window from the window list'''
|
||||
if win in self.wins:
|
||||
self.wins.remove(win)
|
||||
self.update()
|
||||
|
||||
def update(self):
|
||||
'''Update the status of the module for each window'''
|
||||
modules_to_activate = [x[0] for x in Config.items('modules')]
|
||||
for win in self.wins:
|
||||
for name in self.mods:
|
||||
if name not in modules_to_activate:
|
||||
self.deactivate_module(name, win)
|
||||
for name in modules_to_activate:
|
||||
try:
|
||||
self.activate_module(name, win)
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
raise
|
||||
|
||||
def configure(self):
|
||||
'''(internal) Configure all the modules before using them.
|
||||
'''
|
||||
modules_to_configure = [x[0] for x in Config.items('modules')]
|
||||
for name in modules_to_configure:
|
||||
if name not in self.mods:
|
||||
Logger.warning('Modules: Module <%s> not found' % name)
|
||||
continue
|
||||
self._configure_module(name)
|
||||
|
||||
def _configure_module(self, name):
|
||||
if 'module' not in self.mods[name]:
|
||||
try:
|
||||
self.import_module(name)
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
# convert configuration like:
|
||||
# -m mjpegserver:port=8080,fps=8
|
||||
# and pass it in context.config token
|
||||
config = dict()
|
||||
|
||||
args = Config.get('modules', name)
|
||||
if args != '':
|
||||
values = Config.get('modules', name).split(',')
|
||||
for value in values:
|
||||
x = value.split('=', 1)
|
||||
if len(x) == 1:
|
||||
config[x[0]] = True
|
||||
else:
|
||||
config[x[0]] = x[1]
|
||||
|
||||
self.mods[name]['context'].config = config
|
||||
|
||||
# call configure if module have one
|
||||
if hasattr(self.mods[name]['module'], 'configure'):
|
||||
self.mods[name]['module'].configure(config)
|
||||
|
||||
def usage_list(self):
|
||||
print('Available modules')
|
||||
print('=================')
|
||||
for module in sorted(self.list()):
|
||||
if 'module' not in self.mods[module]:
|
||||
self.import_module(module)
|
||||
|
||||
# ignore modules without docstring
|
||||
if not self.mods[module]['module'].__doc__:
|
||||
continue
|
||||
|
||||
text = self.mods[module]['module'].__doc__.strip("\n ")
|
||||
text = text.split('\n')
|
||||
# make sure we don't get IndexError along the way
|
||||
# then pretty format the header
|
||||
if len(text) > 2:
|
||||
if text[1].startswith('='):
|
||||
# '\n%-12s: %s' -> 12 spaces + ": "
|
||||
text[1] = '=' * (14 + len(text[1]))
|
||||
text = '\n'.join(text)
|
||||
print('\n%-12s: %s' % (module, text))
|
||||
|
||||
|
||||
Modules = ModuleBase()
|
||||
Modules.add_path(kivy.kivy_modules_dir)
|
||||
if 'KIVY_DOC' not in os.environ:
|
||||
Modules.add_path(kivy.kivy_usermodules_dir)
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(Modules.list())
|
||||
Reference in New Issue
Block a user