Writing extensions using PyGimp

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Historically I've had some considerable trouble understanding how to implement an extension using PyGimp.
The (hopefully still attached) file is a fairly minimal extension with extensive comments.

Currently there is one bug: the extension name does not show up when gimp says 'Starting extensions' -- instead an empty string is shown. Anyone know why this is? Is it a bug in my extension or a bug in PyGimp?
#!/usr/bin/python
import gimp, gimpplugin
from gimpfu import EXTENSION, TEMPORARY, PF_INT, PF_IMAGE, PF_DRAWABLE

class Fooify (gimpplugin.plugin):
    """Simple example of making extensions with PyGimp.
    
       This extension is about as minimal as possible.
       It includes some debugging messages, and one bug (its name 'extension-fooify' does
       not show up when GIMP is starting extensions; instead a blank string is shown)
    """
    def query (self):
	d = ''	
	# first: register the extension.
	# BUG: its name does not show up in the 'starting extensions' part of gimp start up.
	# How do I fix this?
	gimp.install_procedure ('extension_fooify', 
	    'extension-fooify','EXTENSION-FOOIFY','David Gowers <00ai99@xxxxxxxxx>', 'David Gowers <00ai99@xxxxxxxxx>, 2006','WHAT IS THIS','this is ignored', '*', EXTENSION, [], [])
	# is this needed?
	gimp.extension_enable()

    def extension_fooify(self):
	# This function will be called exactly once, when GIMP starts up.
	# It will return when GIMP exits.
	#
	# You should be aware, sys.stdout will not point to the console.
	# That means print will not operate normally.
	# Is it possible to circumvent this by reassigning sys.stdout,
	# or will that break the extension system?
    	self.i = 1
	# install some procedures
	# typically, an extension registers a number of temp_procs
	# which are functions that it provides.
	#
	# in the case of PyGimp, the functions must be an attribute of the 
	# class (or instance) which implements the extension. 
	# That is, if you register a function 'foo_ufo',
	# you must implement a method in the class called 'foo_ufo'
	# 
	# For ideas like script-fu, where the temporary procs are dynamic, 
	# you would need to make assignments like
	# 
	# setattr(self, funcname, scriptRunner('/home/ai/.gimp-2.0/macros/tileoffset.py'))
	# 
	# Just like ordinary PyGimp plugins, the temp proc functions must match normal 
	# instance-call convention; they accept 'self' as first parameter, then 
	# the parameters they were registered with.
	#
	#
	#
	# You can also uninstall temp procs at (any?) time. (uninstall_temp_proc (proc_name))
	# The script-fu extension uses this uninstall facility when refreshing the scripts
	#  -- first it removes all its
	# temp_procs, then adds them back as it rediscovers them from the scripts on disk.
	#
	gimp.install_temp_proc ('foo_ufo',
	    'ufo', 'a','b','c','d', '<Image>/_Quick!/UFO', '*', TEMPORARY, [(PF_INT, 'run_mode', "run mode"),(PF_IMAGE, 'image', 'Image'), (PF_DRAWABLE, 'drawable', 'Drawable')],[])
	
	# Open the debug log -- I know, this is not collision-safe.
	self.f = open('/tmp/ufolog','a')
	
	# acknowledge we're ready to enter the main extension loop
	gimp.extension_ack()
	# The following is typically written just as :
	#
	# while True:
	#     gimp.extension_process(0);
	#
	# which makes the extension wait forever for messages, and also takes care of actually running the
	# temp_procs.
	# I've just added a debug message here for my own information.
	#
	# as far as I know, anything that occurs after that loop will never execute.
	# I close the file here, but probably it is Python that automatically closes the file when 
	# GIMP shuts down and my extension finishes running, rather than my explicit command.
	
	while True:
	    self.f.write('processing\n')
	    self.f.flush()
	    gimp.extension_process(0);	
	self.f.close()
	
    def foo_ufo (self, run_mode, image, drawable):
	"""Keeps track of how many times the UFO has landed.
	
	Note that the state of self.i and self.f are preserved. This is one reason 
	for implementing an extension rather than plugin -- if your startup is expensive.
	If you need to be very responsive, that's another reason to prefer implementation 
	via extension.
	"""
	self.f.write('landing %r\n' % self.i)
	self.i += 1
	
    def start (self):
	gimpplugin.plugin.start (self)
	
if __name__ == '__main__':
    Fooify ().start ()
_______________________________________________
Gimp-developer mailing list
Gimp-developer@xxxxxxxxxxxxxxxxxxxxxx
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer

[Index of Archives]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [GIMP for Windows]     [KDE]     [GEGL]     [Gimp's Home]     [Gimp on GUI]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux