Article source: yleesun.blog.163.com/blog/static…

Mobile.51cto.com/symbian-273… \

Introduction to the QT Plugin

The ****Qt Plugin, like other types of plug-ins, is a computer application that interacts with the host application to provide specific functionality. Plugins are supported by applications for a number of reasons, some of the main ones being: giving third-party developers the ability to extend applications to provide features not previously anticipated; Reduce the size of the application; Share source code with applications due to software copyright incompatibilities. Qt Plugin is divided into dynamic plug-ins and static plug-ins.

Two: Qt plugin creation and use method

Qt has two plugin-related apis. A feature that extends Qt itself, such as custom database drivers, image formats, text codecs, custom lattices, and so on, is called the Higher-level API. Another kind of functionality extension for applications is called lower-level API. The former builds on the latter. The latter is discussed here, the lower-level API used to extend applications.

Steps to make your application support plug-in extensions:

1. Define a set of interfaces (classes that have only pure virtual functions) to communicate with plug-ins.

2. Use the macro Q_DECLARE_INTERFACE() to tell the Qt meta-object system about this interface.

Q_DECLARE_INTERFACE (BrushInterface, “com. Trolltech. PlugAndPaint. BrushInterface / 1.0”)

3. The application uses QPluginLoader to load plug-ins.

4. Use the qobject_cast() macro to determine if a plug-in implements an interface.

 QObject *obj = new QTimer; 

 QTimer *timer = qobject_cast<QTimer *>(obj);

Steps for writing a plug-in:

1. Declare the plug-in class, which inherits from the QObject and the interface that the plug-in wants to implement.

2. Tell the Qt meta-object system about this interface using the macro Q_INTERFACES().

   class BasicToolsPlugin : public QObject,

                            public BrushInterface,

                            public ShapeInterface,

                            public FilterInterface

   {

       Q_OBJECT

       Q_INTERFACES(BrushInterface ShapeInterface FilterInterface)

   public:

.

   };

3. Export the plug-in using the macro Q_EXPORT_PLUGIN2().

  Q_EXPORT_PLUGIN2 ( PluginName, ClassName )

4. Build the plug-in with the appropriate.pro files.

The following code declares an interface class:

 

class FilterInterface

 {

 public:

        virtual ~FilterInterface() {}

        virtual QStringList filters() const = 0;

        virtual QImage filterImage(const QString &filter, const QImage &image, QWidget* parent)=0;

  };

Q_DECLARE_INTERFACE (FilterInterface, “com. Trolltech. PlugAndPaint. FilterInterface / 1.0”)

Here is the definition of the plug-in class that implements this interface:

 

 #include <QObject>

 #include <QStringList>

 #include <QImage>

 #include <plugandpaint/interfaces.h>

 class ExtraFiltersPlugin : public QObject, public FilterInterface

 {

 Q_OBJECT

 Q_INTERFACES(FilterInterface)

 public:

     QStringList filters() const;

     QImage filterImage(const QString &filter, const QImage &image,

     QWidget *parent);

 };

Depending on the type of plug-in, the configuration in the Pro file varies. Here is the pro file analysis:

TEMPLATE = lib // declared as lib, same as dynamic and static plug-ins.

CONFIG += plugin static // Declare plugin static, otherwise dynamic.

INCLUDEPATH += .. /..

HEADERS       = basictoolsplugin.h

SOURCES       = basictoolsplugin.cpp

TARGET = $$qtLibraryTarget(pnP_basicTools) // Specify the name of the plug-in

DESTDIR = .. /.. /plugandpaint/plugins

By default, the main application that loads plug-ins looks for available plugins in the plugins folder in the current directory. For dynamic plug-ins, it simply places them in the plugins folder. For static plug-ins, you need macros at the beginning of the main application’s main function: Q_IMPORT_PLUGIN(pluginname(same as declared in the pro file)) declares the plug-in to be loaded and specifies the lib location of the plug-in in the project configuration.

Three: The framework structure assumption based on QT Plugin technology

1. The vision

Because our current system has many functions and modules, it lacks the integrity of the system. We want to use Qt Plugin technology to realize each independent function module as a plug-in, unified in the main framework, and can load different function modules in the main framework according to the different needs of users in different places, in order to realize the function concentration of the whole system, reflect the integrity of the system.

2. The plugin interface

Through technical verification, at present we use dynamic plug-in, plug-in of each function to achieve a unified interface defined, specific functions are realized in the plug-in interface, this part is like the development of independent applications, only need to pay attention to the following:

① the main interface of the function part needs to inherit to the base class of the plug-in interface: PluginWidget, the plug-in interface uses the specific implementation class pointer to assign value to the base class pointer of the plug-in interface, in the main framework of loading the plug-in through the base class pointer defined in the plug-in interface unified call, using C++ dynamic technology to dynamically identify the specific implementation class.

② Plug-in interface classes must implement the base class’s virtual function: CreateActions() for creating actions

(3) Create an Action by using the newAction method of the base class.

The plug-in interface is defined as follows:

class QPluginInterface

{

public:

// destructor

    virtual ~QPluginInterface() {}

   

// Plug-in name

    virtual    QString    PluginName() = 0;

   

// The plugin is displayed in the main frame icon file path

    virtual    QString PluginIconurl() = 0;

   

// Set of external operation interfaces provided by the plug-in

    virtual QList<QAction*>* Actions() = 0;

 

// Create the actions provided by the plug-in

    virtual    void CreateActions()=0;

 

// The main interface of the plugin

    virtual QWidget* Widget() = 0;

protected:

// The plugin’s main interface base class

    PluginWidget *pluginWidget;

};

The plug-in interface base class is defined as follows:

class PluginWidget :public QMainWindow

{

    Q_OBJECT

public:

    PluginWidget(QWidget*parent=0);

    ~PluginWidget();

    QList<QAction*>*  Actions();

    virtual void      CreateActions(){}

    QAction *  newAction(const QIcon &icon,const QString&text,QObject*parent);

    QAction *         newAction(const QString &text,QObject*parent);

    void       AppendAction(QAction*act);

protected:

/ / the action list

    QList<QAction*> *m_actlist;

};

The following is a diagram of the relationships between classes in an implementation case:

\

3. Plug-in call

Plug-ins are dynamically loaded in the main frame. At present, considering that the basic structure of the main frame is inherited to QMainWindow, the toolbar shows the function keys of the plug-in currently loaded, and there is a return key to go back to the previous level. The main workspace is a QStackWidget that saves the interface of the plug-in and maps the plug-in serial number to the corresponding interface in QMap<int,QWidget>. Switch the interface from the serial number to the QStackWidget.

The following is the runtime interface of the main frame loaded with DBManager as a plug-in:

\

Here is a simple drawing program as a plug-in, loaded into the main frame interface:

Four:

At present, **** only runs in the main framework by implementing two dynamic plug-ins, which is basically a functional verification. There are still a lot of work to be further studied before the concrete implementation, such as the style of the main framework, the management of plug-ins and so on. Due to my limited ability, there may be a lot of insufficient understanding of the place, please correct.

\