[Kde-bindings] Qt4 embedded scripting
Sebastian Sauer
mail at dipe.org
Sat Sep 10 16:17:24 UTC 2005
Hi dear devel,
following lines try to deal with the question how kdebindings could be
extended to be usuable for application embedding, where I see problems with
the current implementation and how I tried to address them in my own
interpreter independend scripting framework named Kross and located at
koffice/kexi/scripting{core|plugins}.
This mail _is_not_ any kind of proposal or something like that. It's all about
publishing the goals _me_ would like to archive with embedded scripting and
how I tried to solve them. As always I am pretty happy about any kind of
constructive feedback, opinions and funny flamewars :-)
1. Intro
Something like a year ago I jumped into the great Kexi-project and business as
usual, I wasn't that happy that Kexi still missed scripting functionality to
access the KexiDB framework, manipulate forms or just extend the
functionality with own little scripts to e.g. have a simple export
Table/Query to HTML functionality.
Kexi itself had a strange walk through already existing solutions. QSA was
used, KJS was and I even wrote initialy a python KexiDB module. As you may
imagine replacing one scripting interpreter with another isn't that
constructive and supporting x interpreters with different subsets of
functionality and a lot of duplicated code to archive each time the same
effect (wrap C++/Qt to the scriptlanguage and the other way around).
Another problem was, that neither Kexi nor whole KOffice should depend on the
used interpreter(s) and to let it be a compiletime decission just moves the
"problem" up to the packager. Therefore it was very clear, that each
interpreter-binding should become an own dynamic loadable plugin (KDE_MODUL)
and Kexi just needs to link against some "manager-code" that handles loading
of the interpreter plugins. So, those manager-code doesn't introduce any
dependencies beside Qt/KDE and provides an abstraction layer to the used
interpreter(s). Kexi just doesn't know anything about the used interpreter(s),
the scriptinglanguage itself or other implementation-details.
2. Implementation
2.1 API
This is what I named above as "manager-code" and it's the common codebase Kexi
have to deal with and link to. It's very similar to the kjsembed codebase
that provides functionality to e.g. publish QObject's, handle signals, slots,
Q_PROPERTY/Q_CLASSINFO and values like QVariant, QMap-dictonaries, lists,
etc.
At the Kexi-level we mainly deal with following 3 classes;
// The Manager-class is a singelton instance that provides access to
// interpreter-implementations (KDE_MODULE, loaded on demand),
// scriptcontainers used to represent a single scriptfile like
// container and some code to load external modules (used to
// wrap e.g. KexiDB).
class Manager {
ScriptContainer* getScriptContainer(const QString& scriptname) {}
Interpreter* getInterpreter(const QString& interpretername) {}
const QStringList getSupportedInterpreters() {}
QObject* loadModule(const QString& modulename) {}
};
// Think of a scriptcontainer as single scriptfile that provides
// a simple common API to a interpreter independend script. For
// sure there are more functions to e.g. work with class-instances,
// add QObject/KAction/etc. instances, connect a QObject signal with
// a scriptfunction, handle exceptions, etc.
class ScriptContainer {
const QString& getScriptingCode() {}
void setScriptingCode(const QString&) {}
const QString& getInterpreterName() {}
void setInterpreterName(const QString&) {}
QObject* execute() {}
const QStringList getFunctionNames();
QObject* callFunction(const QString& functionname, List arguments);
};
// Interface for interpreter implementations. e.g. the python plugin
// implements PythonInterpreter. I included this class here only to
// outline, that the interpreter bindings itself are just
// implementationdetails we don't need to know about from the view of
// an application.
class Interpreter {
};
For sure it isn't really needed to wrap whole Qt/KDE again at this level.
Access to all the widgets, etc. are better done as wrapper-plugins (see
section 2.3) cause
a) it's not needed to recompile all apps if some new widget, new
functionality or whatever got added and
b) not every app that uses embedded scripting may use all those
bindings (think of QCoreApplication/KCoreApplication's) and
c) for sure those plugins should still be usuable as "standalone-
modules" (e.g. python extensions rather then python embedding)
2.2 Interpreter plugins
Each interpreter implementation then just implements the API functionality to
the scripting language it provides access to. There is for sure more under
the hood then only those from class Interpreter inherited class.
2.3 Wrapper-plugins to provide application functionality
The wrapper-plugins are very similar to what Smoke does; wrap some Qt-code and
make it accessible (as standalone-modules) to scripting languages.
3. Ideas
In fact kjsembed has all the functionality in place I described above at the
"2.1 API" section. Would it be an idea to try to extend kjsembed to support
something like the at the "2.2 Interpreter plugins" section described
functionality? If not, what are alternates to get such a common framework for
embedding scriptinglanguages done?
p.s. yes, extending my english is on my TODO as well :)
More information about the Kde-bindings
mailing list