Python catalog to support python widgets at runtime

View: New views
3 Messages — Rating Filter:   Alert me  

Python catalog to support python widgets at runtime

by Juan Pablo Ugarte-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello people.
As you probably know the BINDINGS branch have been inactive for a long
time.
Coming up with a framework to support multiples languages in glade and
actually implementing the full gladeui API for such languages is a big
job.
That said, it does not mean we cant have python widget at runtime!

The idea is simple, i have ported the old branch code into a regular
glade plugin.

So all you have to do is add gladepython as your catalog library
and set the init function to glade_python_init()
glade_python_init() will run a python interpreter and import your python library
using the catalog name.

btw , the patch is against trunk, but it should work in stable

enjoy

Juan Pablo

[pythonplugin.py]

import gobject
import gtk

class MyBox(gtk.HBox):
        __gtype_name__ = 'MyBox'
       
        def __init__(self):
                gtk.HBox.__init__(self)



[gladepython.patch]

Index: m4/python.m4
===================================================================
--- m4/python.m4 (revision 1832)
+++ m4/python.m4 (working copy)
@@ -1,7 +1,7 @@
 ## this one is commonly used with AM_PATH_PYTHONDIR ...
 dnl AM_CHECK_PYMOD(MODNAME [,SYMBOL [,ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]]])
 dnl Check if a module containing a given symbol is visible to python.
-AC_DEFUN([AM_CHECK_PYMOD],
+AC_DEFUN(AM_CHECK_PYMOD,
 [AC_REQUIRE([AM_PATH_PYTHON])
 py_mod_var=`echo $1['_']$2 | sed 'y%./+-%__p_%'`
 AC_MSG_CHECKING(for ifelse([$2],[],,[$2 in ])python module $1)
@@ -60,65 +60,29 @@
 $2])
 CPPFLAGS="$save_CPPFLAGS"
 ])
-## this one is commonly used with AM_PATH_PYTHONDIR ...
-dnl AM_CHECK_PYMOD(MODNAME [,SYMBOL [,ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]]])
-dnl Check if a module containing a given symbol is visible to python.
-AC_DEFUN([AM_CHECK_PYMOD],
-[AC_REQUIRE([AM_PATH_PYTHON])
-py_mod_var=`echo $1['_']$2 | sed 'y%./+-%__p_%'`
-AC_MSG_CHECKING(for ifelse([$2],[],,[$2 in ])python module $1)
-AC_CACHE_VAL(py_cv_mod_$py_mod_var, [
-ifelse([$2],[], [prog="
-import sys
-try:
-        import $1
-except ImportError:
-        sys.exit(1)
-except:
-        sys.exit(0)
-sys.exit(0)"], [prog="
-import $1
-$1.$2"])
-if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC
-  then
-    eval "py_cv_mod_$py_mod_var=yes"
-  else
-    eval "py_cv_mod_$py_mod_var=no"
-  fi
-])
-py_val=`eval "echo \`echo '$py_cv_mod_'$py_mod_var\`"`
-if test "x$py_val" != xno; then
-  AC_MSG_RESULT(yes)
-  ifelse([$3], [],, [$3
-])dnl
-else
-  AC_MSG_RESULT(no)
-  ifelse([$4], [],, [$4
-])dnl
-fi
-])
 
-dnl a macro to check for ability to create python extensions
-dnl  AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE])
-dnl function also defines PYTHON_INCLUDES
-AC_DEFUN([AM_CHECK_PYTHON_HEADERS],
-[AC_REQUIRE([AM_PATH_PYTHON])
-AC_MSG_CHECKING(for headers required to compile python extensions)
-dnl deduce PYTHON_INCLUDES
-py_prefix=`$PYTHON -c "import sys; print sys.prefix"`
+dnl a macro to check for ability to embed python
+dnl  AM_CHECK_PYTHON_LIBS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE])
+dnl function also defines PYTHON_LIBS
+AC_DEFUN([AM_CHECK_PYTHON_LIBS],
+[AC_REQUIRE([AM_CHECK_PYTHON_HEADERS])
+AC_MSG_CHECKING(for libraries required to embed python)
+dnl deduce PYTHON_LIBS
 py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"`
-PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}"
-if test "$py_prefix" != "$py_exec_prefix"; then
-  PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}"
+if test "x$PYTHON_LIBS" == x; then
+ PYTHON_LIBS="-L${py_prefix}/lib -lpython${PYTHON_VERSION}"
 fi
-AC_SUBST(PYTHON_INCLUDES)
+if test "x$PYTHON_LIB_LOC" == x; then
+ PYTHON_LIB_LOC="${py_prefix}/lib"
+fi
+AC_SUBST(PYTHON_LIBS)
+AC_SUBST(PYTHON_LIB_LOC)
 dnl check if the headers exist:
-save_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES"
-AC_TRY_CPP([#include <Python.h>],dnl
-[AC_MSG_RESULT(found)
-$1],dnl
-[AC_MSG_RESULT(not found)
-$2])
-CPPFLAGS="$save_CPPFLAGS"
+save_LIBS="$LIBS"
+LIBS="$LIBS $PYTHON_LIBS"
+AC_TRY_LINK_FUNC(Py_Initialize, dnl
+         [LIBS="$save_LIBS"; AC_MSG_RESULT(yes); $1], dnl
+         [LIBS="$save_LIBS"; AC_MSG_RESULT(no); $2])
+
 ])
+
Index: plugins/python/Makefile.am
===================================================================
--- plugins/python/Makefile.am (revision 0)
+++ plugins/python/Makefile.am (revision 0)
@@ -0,0 +1,28 @@
+## Process this file with automake to produce Makefile.in
+
+libgladeui = $(top_builddir)/gladeui/libgladeui-1.la
+
+
+# libgladepython
+
+gladepython_LTLIBRARIES = libgladepython.la
+gladepythondir = $(pkglibdir)/modules
+
+libgladepython_la_SOURCES = glade-python.c
+libgladepython_la_CPPFLAGS = $(AM_CPPFLAGS)
+libgladepython_la_CFLAGS = \
+        -DG_LOG_DOMAIN=\"GladeUI-PYTHON\" \
+ -I$(top_srcdir)                  \
+ -I$(top_builddir)                \
+ $(PYTHON_INCLUDES)      \
+ $(PYGTK_CFLAGS)            \
+ $(GTK_CFLAGS)                    \
+ $(PLUGINS_WARN_CFLAGS)           \
+ $(AM_CPPFLAGS)
+libgladepython_la_LDFLAGS = -module -avoid-version $(PYTHON_LIBS) $(AM_LDFLAGS)
+libgladepython_la_LIBADD = $(libgladeui) $(PYTHON_LIBS)
+
+if PLATFORM_WIN32
+libgladepython_la_LDFLAGS += -no-undefined
+endif
+
Index: plugins/python/glade-python.c
===================================================================
--- plugins/python/glade-python.c (revision 0)
+++ plugins/python/glade-python.c (revision 0)
@@ -0,0 +1,127 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006-2008 Juan Pablo Ugarte.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ *   Juan Pablo Ugarte <juanpablougarte@...>
+ */
+
+#include <config.h>
+
+#include <gladeui/glade.h>
+
+#include <Python.h>
+#include <pygobject.h>
+
+static void
+python_init (void)
+{
+ char *argv[1];
+
+ if (Py_IsInitialized ()) return;
+
+ Py_InitializeEx (0);
+
+ argv[0] = g_get_prgname ();
+
+ PySys_SetArgv (1, argv);
+}
+
+static void
+glade_python_init_pygtk_check (gint req_major, gint req_minor, gint req_micro)
+{
+ PyObject *gobject, *mdict, *version;
+ int found_major, found_minor, found_micro;
+
+ init_pygobject();
+
+ gobject = PyImport_ImportModule("gobject");
+ mdict = PyModule_GetDict(gobject);
+        version = PyDict_GetItemString(mdict, "pygtk_version");
+ if (!version)
+ {
+ PyErr_SetString(PyExc_ImportError, "PyGObject version too old");
+ return;
+ }
+ if (!PyArg_ParseTuple(version, "iii", &found_major, &found_minor, &found_micro))
+ return;
+ if (req_major != found_major || req_minor >  found_minor ||
+    (req_minor == found_minor && req_micro > found_micro))
+ {
+ PyErr_Format(PyExc_ImportError,
+                     "PyGObject version mismatch, %d.%d.%d is required, "
+                     "found %d.%d.%d.", req_major, req_minor, req_micro,
+                     found_major, found_minor, found_micro);
+ return;
+ }
+}
+
+static void
+glade_python_setup ()
+{
+ gchar *command;
+
+     Py_SetProgramName (PACKAGE_NAME);
+
+ /* Initialize the Python interpreter */
+ python_init ();
+
+ /* Check and init pygobject >= 2.12.0 */
+ PyErr_Clear ();
+ glade_python_init_pygtk_check (PYGTK_REQUIRED_MAJOR, PYGTK_REQUIRED_MINOR, PYGTK_REQUIRED_MICRO);
+ if (PyErr_Occurred ())
+ {
+ PyObject *ptype, *pvalue, *ptraceback;
+ PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+ g_warning ("Unable to load pygobject module >= %d.%d.%d, "
+   "please make sure it is in python's path (sys.path). "
+   "(use PYTHONPATH env variable to specify non default paths)\n%s",
+   PYGTK_REQUIRED_MAJOR, PYGTK_REQUIRED_MINOR, PYGTK_REQUIRED_MICRO,
+   PyString_AsString (pvalue));
+ PyErr_Clear ();
+ Py_Finalize ();
+ return;
+ }
+
+ pyg_disable_warning_redirections ();
+
+ /* Set path */
+ command = g_strdup_printf ("import sys; sys.path+=['.', '%s', '%s'];\n",
+   g_getenv (GLADE_ENV_CATALOG_PATH),
+   glade_app_get_modules_dir ());
+ PyRun_SimpleString (command);
+ g_free (command);
+}
+
+
+void
+glade_python_init (const gchar *name)
+{
+ static gboolean init = TRUE;
+ gchar *import_sentence;
+
+ if (init)
+ {
+ glade_python_setup ();
+ init = FALSE;
+ }
+
+ /* Yeah, we use the catalog name as the library */
+ import_sentence = g_strdup_printf ("import %s;", name);
+ PyRun_SimpleString (import_sentence);
+ g_free (import_sentence);
+}
Index: plugins/gnome/glade-gnome.c
===================================================================
--- plugins/gnome/glade-gnome.c (revision 1832)
+++ plugins/gnome/glade-gnome.c (working copy)
@@ -41,7 +41,7 @@
 
 /* Catalog init function */
 void
-glade_gnomeui_init (void)
+glade_gnomeui_init (const gchar *name)
 {
  gchar *argv[2] = {"glade-3", NULL};
  GtkStockItem items [] = {
Index: plugins/Makefile.am
===================================================================
--- plugins/Makefile.am (revision 1832)
+++ plugins/Makefile.am (working copy)
@@ -5,3 +5,7 @@
 if BUILD_GNOME
 SUBDIRS += gnome
 endif
+
+if BUILD_PYTHON
+SUBDIRS += python
+endif
Index: configure.ac
===================================================================
--- configure.ac (revision 1832)
+++ configure.ac (working copy)
@@ -145,6 +145,33 @@
 
 AM_CONDITIONAL(BUILD_GNOME, test x"$have_gnome" = "xyes")
 
+dnl ================================================================
+dnl Python for optional python dev libs
+dnl ================================================================
+AC_ARG_ENABLE(python,
+    AS_HELP_STRING([--disable-python], [disable python catalog]),
+    check_python=$enableval, check_python=yes)
+
+if test x"$check_python" = x"yes"; then
+  PYGTK_REQUIRED_MAJOR=2
+  PYGTK_REQUIRED_MINOR=10
+  PYGTK_REQUIRED_MICRO=0
+  AM_CHECK_PYTHON_HEADERS(, [AC_MSG_ERROR(could not find Python headers)])
+  AM_CHECK_PYTHON_LIBS(, [AC_MSG_ERROR(could not find Python lib)])
+  PKG_CHECK_MODULES(PYGTK, [pygtk-2.0 >= 2.10.0], [have_python=yes],[have_python=no])
+
+  AC_DEFINE_UNQUOTED(PYGTK_REQUIRED_MAJOR, $PYGTK_REQUIRED_MAJOR, Pygtk mayor version required)
+  AC_DEFINE_UNQUOTED(PYGTK_REQUIRED_MINOR, $PYGTK_REQUIRED_MINOR, Pygtk minor version required)
+  AC_DEFINE_UNQUOTED(PYGTK_REQUIRED_MICRO, $PYGTK_REQUIRED_MICRO, Pygtk micro version required)
+
+  AC_SUBST(PYGTK_LIBS)
+  AC_SUBST(PYGTK_CFLAGS)
+else
+  have_python=no
+fi
+
+AM_CONDITIONAL(BUILD_PYTHON, test x"$have_python" = "xyes")
+
 # ==================================================================
 # Glade User Manual (requires gnome-doc-utils)
 # ==================================================================
@@ -218,6 +245,7 @@
 plugins/gnome/icons/Makefile
 plugins/gnome/icons/16x16/Makefile
 plugins/gnome/icons/22x22/Makefile
+plugins/python/Makefile
 po/Makefile.in
 doc/Makefile
 doc/version.xml
@@ -234,4 +262,5 @@
  Compiler: ${CC}
  GTK+ UNIX Print Widgets: ${have_unix_print}
  GNOME UI Widgets: ${have_gnome}
+ PYTHON Widgets support: ${have_python}
 "
Index: gladeui/glade-catalog.c
===================================================================
--- gladeui/glade-catalog.c (revision 1832)
+++ gladeui/glade-catalog.c (working copy)
@@ -33,7 +33,7 @@
 #include <glib.h>
 #include <glib/gi18n-lib.h>
 
-typedef void   (*GladeCatalogInitFunc) (void);
+typedef void   (*GladeCatalogInitFunc) (const gchar *name);
 
 struct _GladeCatalog
 {
@@ -535,7 +535,7 @@
  {
  catalog = l->data;
  if (catalog->init_function)
- catalog->init_function ();
+ catalog->init_function (catalog->name);
  }
 
  for (l = catalogs; l; l = l->next)


_______________________________________________
Glade-devel maillist  -  Glade-devel@...
http://lists.ximian.com/mailman/listinfo/glade-devel

pythonplugin.xml (456 bytes) Download Attachment

Re: Python catalog to support python widgets at runtime

by MORGANTINI ALESSANDRO :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thank you very much for your patch: it is the thing I was looking for.

A question about adaptors: in the old BINDINGS there was the ability to
write adaptors in Python. Is it possible with your patch too? Or do I
have to write adaptors in C (maybe inserting them into the
plugins/python/glade-python.c file)?

Another question, but I don't know if it is correct (note that I don't
know very well autotools... :-)). Why are there some files (e.g.
m4/python.m4) which are in the SVN repository but not in the
corresponding .tar.gz archive and, on the other hand, are there some
other files (e.g. gtk-doc.make, m4/gtk-doc.m4) which are in the tar.gz
archive but not in the repository? This prevents autoreconf from
successfully running, without some hacks.

Cheers, Alessandro

_______________________________________________
Glade-devel maillist  -  Glade-devel@...
http://lists.ximian.com/mailman/listinfo/glade-devel

Re: Python catalog to support python widgets at runtime

by Juan Pablo Ugarte-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



Sent from my iPhone

On Jun 12, 2008, at 9:49, MORGANTINI ALESSANDRO  
<a.morgantini@...> wrote:

> Thank you very much for your patch: it is the thing I was looking for.
>
> A question about adaptors: in the old BINDINGS there was the ability  
> to
> write adaptors in Python. Is it possible with your patch too?

No, you can not and that was the whole point why we took out Bindings  
from the core.
It is too much work finish the gladeui binding and even more maintain it

> Or do I
> have to write adaptors in C (maybe inserting them into the
> plugins/python/glade-python.c file)

I recomend to fix your library if posible.

>
> Another question, but I don't know if it is correct (note that I don't
> know very well autotools... :-)). Why are there some files (e.g.
> m4/python.m4) which are in the SVN repository but not in the
> corresponding .tar.gz archive and, on

Seems like I missed that in the patch, I will include it when the  
patch is applied in trunk


> the other hand, are there some
> other files (e.g. gtk-doc.make, m4/gtk-doc.m4) which are in the tar.gz
> archive but not in the repository? This prevents autoreconf from
> successfully running, without some hacks.
>
> Cheers, Alessandro
>
> _______________________________________________
> Glade-devel maillist  -  Glade-devel@...
> http://lists.ximian.com/mailman/listinfo/glade-devel
_______________________________________________
Glade-devel maillist  -  Glade-devel@...
http://lists.ximian.com/mailman/listinfo/glade-devel