Qt API | Qtopia API | Qtopia Documentation | ![]() |
Plugins are implemented in Qtopia via a COM-like layer. The basic steps to writing any Qtopia plugin are:
There are also some basic rules to follow when writing a plugin:
Consider the following fictious plugin interface:
// {05E0A4AB-DDC5-4449-85A9-828100DE00A9} #ifndef IID_WidgetPlugin #define IID_WidgetPlugin QUuid( 0x05e0a4ab, 0xddc5, 0x4449, 0x85, 0xa9, 0x82, 0x81, 0x00, 0xde, 0x00, 0xa9) #endif struct WidgetPluginInterface : public QUnknownInterface { virtual QWidget *widget( QWidget *parent ) = 0; virtual QString name() const = 0; };
This is a simple interface that provides a plugin name and a widget that is created with the supplied parent.
IID_WidgetPlugin defines a unique ID for this interface.
The plugin that we are writing provides a widget that draws an ellipse in its center. The code below implements the functionality that this plugin provides.
class EllipseWidget : public QWidget { Q_OBJECT public: EllipseWidget( QWidget *parent=0 ) : QWidget( parent, "Ellipse" ) { } protected: void paintEvent( QPaintEvent * ) { QPainter p( this ); p.drawEllipse( rect() ); } };
Now you can subclass the WidgetPluginInterface:
struct CirclePlugin : public WidgetPluginInterface { public: virtual QWidget *widget( QWidget *parent ); virtual QString name() const; QRESULT queryInterface( const QUuid&, QUnknownInterface** ); Q_REFCOUNT protected: CircleWidget *w; ulong ref; };
There are two things to note in the CirclePlugin struct:
The constructor an destructor are straight-forward. The most important point is that ref must be initialised with 0.
CirclePlugin::CirclePlugin() : w(0), ref(0) { } CirclePlugin::~CirclePlugin() { delete w; }
The queryInterface() function can be implemented using the following boilerplate code:
QRESULT CirclePlugin::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) { *iface = 0; if ( uuid == IID_QUnknown ) *iface = this; else if ( uuid == IID_WidgetPlugin ) *iface = this; else return QS_FALSE; (*iface)->addRef(); return QS_OK; }
A plugin can provide several interfaces. At the very least QUnknownInterface is provided by all plugins.
The widget() function returns the widget.
QWidget *CirclePlugin::widget( QWidget *parent ) { if ( !w ) w = new CircleWidget( parent ); return w; }
The name() function returns the name of the plugin.
QString CirclePlugin::name() { return qApp->translate( "WidgetPlugin", "Circle" ); }
You must also create an instance of the widget plugin using the following boilerplate code:
Q_EXPORT_INTERFACE() { Q_CREATE_INSTANCE( CirclePlugin ) }
The recommended method for loading plugins is to use the PluginLoader class. The PluginLoader class provides simplified enumeration and loading of plugins and provides safety in cases where the system has been booted in Safe Mode.
PluginLoader loader( "Widgets" ); QStringList list = pluginLoader.list(); QStringList::Iterator it; QValueList<WidgetPluginInterface*> widgetsList; for ( it = list.begin(); it != list.end(); ++it ) { WidgetPluginInterface *iface = 0; if ( pluginLoader.queryInterface( *it, IID_WidgetPlugin, (QUnknownInterface**)&iface ) == QS_OK && iface ) { widgetsList.append( iface ); } }
The PluginLoader class expects the plugins to be installed in the $QPEDIR/plugins/type directory.
Copyright © 2001-2002 Trolltech | Trademarks | Qtopia version 1.7.1
|