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
|