1, an overview of the
Why should we learn about plugins, and how is it different from exporting DLLS for Windows?
- If the exported dynamic library is missing, the program will not run. But plug-ins do.
- The same set of code, you can generate plug-ins under Windows and Linux respectively.
QT itself provides two types of plug-in support, one called the high-level API and one called the low-level API.
- The advanced API is used to extend the QT program itself, which requires subclassing the plug-in base classes provided by QT, such as the existing QTSqlDriver, so you can also extend QT by writing your own QTStyle.
- The low-level API is used to extend your program in the form of a dynamic library, or DLL in Windows. At the same time, because high-level apis are built on low-level apis, it is not difficult to master low-level API usage without high-level API usage.
The QPluginloader class is used to load QT plugins. You can write plugins that support any function. How to create a plug-in and load the plug-in is described in QT Assist:
To create a plug-in that extends the application:
- Defines a set of interfaces (classes with only pure virtual functions) for talking to the plug-in. (Ports are reserved to facilitate communication).
- The Q_DECLARE_INTERFACE() macro is used inside the interface to tell qt’s meta-object system about the interface.
- Use QPluginLoader to load the plug-in.
- Qobject_cast is used to verify that the plug-in implements the specified interface (in case of external plug-in injection), and the transformation succeeds to get the plug-in instance.
Specific steps for plug-in writing (code writing) :
- Declare the plug-in class and inherit from QObject and implement the established interface mentioned above.
- Use Q_INTERFACES to tell the QT meta object system about this interface (virtual methods).
- Export the plug-in using Q_PLUGIN_METADATA. (Q_PLUGIN_METADATA is a macro for QT5, QT4 uses Q_EXPORT_PLUGIN2)
- Write appropriate.pro files.
2, the instance,
Create a subdirectory named PluginApp
Create a new QWidget project under PluginApp named Main
3. Right-click your PluginApp and create a new subproject
4. Project directory structure
Create a new header file interfaceplugin.h under Main
Interfaceplugin. h #ifndef INTERFACEPLUGIN_H #define INTERFACEPLUGIN_H #include <QString> #include <QtPlugin class InterfacePlugin { public: virtual ~InterfacePlugin() {} virtual QString output(const QString &message) = 0; }; # define InterfacePlugin_iid Test. The Plugin. "InterfacePlugin" / / unique identifier Q_DECLARE_INTERFACE (InterfacePlugin, InterfacePlugin_iid) #endifCopy the code
Load plug-ins
#main.cpp #include "widget.h" #include <QApplication> #include <QDir> #include <QPluginLoader> #include "interfaceplugin.h" #include <QObject> #include <QDebug> int main(int argc, char *argv[]) { QApplication a(argc, argv); // Widget w; // w.show(); QDir path = QDir(qApp->applicationDirPath()); path.cd(".. /plugins"); foreach (QFileInfo info, path.entryInfoList(QDir::Files | QDir::NoDotAndDotDot)) { QPluginLoader pluginLoader(info.absoluteFilePath()); QObject *plugin = pluginLoader.instance(); if (plugin) { InterfacePlugin *app = qobject_cast<InterfacePlugin*>(plugin); if (app) { app->output("i am a plugin"); } } } return a.exec(); }Copy the code
Seven, write plug-in. Pro file, header file, CPP file
# plugin. pro TEMPLATE = lib # makefile CONFIG += plugin # TARGET = pluginA # DESTDIR = . HEADERS += \ plugina.h SOURCES += \ plugina.cpp DISTFILES += \ programmerCopy the code
#this is pluginA.h #ifndef PLUGINA_H #define PLUGINA_H #include <QObject> #include <QtPlugin> #include ".. /Main/interfaceplugin.h" class PluginA : public QObject, Public InterfacePlugin {// Programmer. Json Q_OBJECT Q_PLUGIN_METADATA(IID InterfacePlugin_iid FILE // QT5.0 introduces Q_INTERFACES(InterfacePlugin) public: explicit PluginA(QObject *parent = 0); virtual QString output(const QString &message) Q_DECL_OVERRIDE; }; #endif // PLUGINA_HCopy the code
Json “programmer. Json “is a plug-in description file that is loaded into the plug-in as metadata and can be read manually if needed. It contains the basic information about the plug-in and, more importantly, the dependencies of the plug-in, which determine the order in which the plug-in is loaded.
{" author ":" QHT ", "date" : "2019/05/27", "name" : "pluginA", "version" : "1.0.0", "des" : "Dependencies" : []}Copy the code
#this is pluginA.cpp #include "pluginA.h" #include <QtDebug> PluginA::PluginA(QObject *parent) : QObject(parent) {} QString PluginA::output(const QString &message) {qDebug() << message + "PluginA loaded successfully "; return message; }Copy the code
Eight, run,
Note: 1. The Main project chose the QWidget GUI project for a reason, which will be explained in the next section. 2. The plug-in generated in Windows is the DLL suffix, and the plug-in generated in Linux is the so suffix (the next part is the Linux test results).
The Demo address: download.csdn.net/download/u0… Github.com/qht10030778…