![]() Qtopia Home - Classes - Hierachy - Annotated - Functions - Licenses - Reference |
![]() |
Plug-ins are implemented in Qtopia via a COM-like layer. The basic steps to writing any Qtopia plug-in are:
There are also some basic rules to follow when writing a plug-in:
Consider the following fictitious plug-in 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 plug-in name and a widget that is created with the supplied parent.
IID_WidgetPlugin defines a unique ID for this interface.
The plug-in that we are writing provides a widget that draws an ellipse in its center. The code below implements the functionality that this plug-in 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 plug-in can provide several interfaces. At the very least QUnknownInterface is provided by all plug-ins.
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 plug-in.
QString CirclePlugin::name() { return qApp->translate( "WidgetPlugin", "Circle" ); }
You must also create an instance of the widget plug-in using the following boilerplate code:
Q_EXPORT_INTERFACE() { Q_CREATE_INSTANCE( CirclePlugin ) }
The recommended method for loading plug-ins is to use the PluginLoader class. The PluginLoader class provides simplified enumeration and loading of plug-ins and provides safety in cases where the system has been booted in Safe Mode.
PluginLoader pluginLoader( "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 plug-ins to be installed in the $QPEDIR/plugins/type directory.
Copyright © 2005 Trolltech | Trademarks | Qtopia version 2.2.0
|