| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the documentation of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:FDL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Free Documentation License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Free |
| ** Documentation License version 1.3 as published by the Free Software |
| ** Foundation and appearing in the file included in the packaging of |
| ** this file. Please review the following information to ensure |
| ** the GNU Free Documentation License version 1.3 requirements |
| ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \example tools/echoplugin |
| \title Echo Plugin Example |
| \ingroup examples-widgets-tools |
| \ingroup examples-layout |
| |
| \brief This example shows how to create a Qt plugin. |
| |
| \image echopluginexample.png |
| |
| There are two kinds of plugins in Qt: plugins that extend Qt |
| itself and plugins that extend applications written in Qt. In this |
| example, we show the procedure of implementing plugins that extend |
| applications. When you create a plugin you declare an interface, |
| which is a class with only pure virtual functions. This interface |
| is inherited by the class that implements the plugin. The class is |
| stored in a shared library and can therefore be loaded by |
| applications at run-time. When loaded, the plugin is dynamically |
| cast to the interface using Qt's \l{Meta-Object |
| System}{meta-object system}. The plugin \l{How to Create Qt |
| Plugins}{overview document} gives a high-level introduction to |
| plugins. |
| |
| We have implemented a plugin, the \c EchoPlugin, which implements |
| the \c EchoInterface. The interface consists of \c echo(), which |
| takes a QString as argument. The \c EchoPlugin returns the string |
| unaltered (i.e., it works as the familiar echo command found in |
| both Unix and Windows). |
| |
| We test the plugin in \c EchoWindow: when you push the QPushButton |
| (as seen in the image above), the application sends the text in |
| the QLineEdit to the plugin, which echoes it back to the |
| application. The answer from the plugin is displayed in the |
| QLabel. |
| |
| |
| \section1 EchoWindow Class Definition |
| |
| The \c EchoWindow class lets us test the \c EchoPlugin through a |
| GUI. |
| |
| \snippet tools/echoplugin/echowindow/echowindow.h 0 |
| |
| We load the plugin in \c loadPlugin() and cast it to \c |
| EchoInterface. When the user clicks the \c button we take the |
| text in \c lineEdit and call the interface's \c echo() with it. |
| |
| |
| \section1 EchoWindow Class Implementation |
| |
| We start with a look at the constructor: |
| |
| \snippet tools/echoplugin/echowindow/echowindow.cpp 0 |
| |
| We create the widgets and set a title for the window. We then load |
| the plugin. \c loadPlugin() returns false if the plugin could not |
| be loaded, in which case we disable the widgets. If you wish a |
| more detailed error message, you can use |
| \l{QPluginLoader::}{errorString()}; we will look more closely at |
| QPluginLoader later. |
| |
| Here is the implementation of \c sendEcho(): |
| |
| \snippet tools/echoplugin/echowindow/echowindow.cpp 1 |
| |
| This slot is called when the user pushes \c button or presses |
| enter in \c lineEdit. We call \c echo() of the echo interface. In |
| our example this is the \c EchoPlugin, but it could be any plugin |
| that inherit the \c EchoInterface. We take the QString returned |
| from \c echo() and display it in the \c label. |
| |
| Here is the implementation of \c createGUI(): |
| |
| \snippet tools/echoplugin/echowindow/echowindow.cpp 2 |
| |
| We create the widgets and lay them out in a grid layout. We |
| connect the label and line edit to our \c sendEcho() slot. |
| |
| Here is the \c loadPlugin() function: |
| |
| \snippet tools/echoplugin/echowindow/echowindow.cpp 3 |
| |
| Access to plugins at run-time is provided by QPluginLoader. You |
| supply it with the filename of the shared library the plugin is |
| stored in and call \l{QPluginLoader::}{instance()}, which loads |
| and returns the root component of the plugin (i.e., it resolves |
| the type of the plugin and creates a QObject instance of it). If |
| the plugin was not successfully loaded, it will be null, so we |
| return false. If it was loaded correctly, we can cast the plugin |
| to our \c EchoInterface and return true. In the case that the |
| plugin loaded does not implement the \c EchoInterface, \c |
| instance() will return null, but this cannot happen in our |
| example. Notice that the location of the plugin is not the same |
| for all platforms. |
| |
| |
| \section1 EchoInterface Class Definition |
| |
| The \c EchoInterface defines the functions that the plugin will |
| provide. An interface is a class that only consists of pure |
| virtual functions. If non virtual functions were present in the |
| class you would get misleading compile errors in the moc files. |
| |
| \snippet tools/echoplugin/echowindow/echointerface.h 0 |
| |
| We declare \c echo(). In our \c EchoPlugin we use this method to |
| return, or echo, \a message. |
| |
| We use the Q_DECLARE_INTERFACE macro to let \l{Meta-Object |
| System}{Qt's meta object system} aware of the interface. We do |
| this so that it will be possible to identify plugins that |
| implements the interface at run-time. The second argument is a |
| string that must identify the interface in a unique way. |
| |
| |
| \section1 EchoPlugin Class Definition |
| |
| We inherit both QObject and \c EchoInterface to make this class a |
| plugin. The Q_INTERFACES macro tells Qt which interfaces the class |
| implements. In our case we only implement the \c EchoInterface. |
| If a class implements more than one interface, they are given as |
| a space separated list. The Q_PLUGIN_METADATA macro is included next |
| to the Q_OBJECT macro. It contains the plugins IID and a filename |
| pointing to a json file containing the metadata for the plugin. |
| The json file is compiled into the plugin and does not need to be installed. |
| |
| \snippet tools/echoplugin/plugin/echoplugin.h 0 |
| |
| \section1 EchoPlugin Class Implementation |
| |
| Here is the implementation of \c echo(): |
| |
| \snippet tools/echoplugin/plugin/echoplugin.cpp 0 |
| |
| We simply return the functions parameter. |
| |
| \section1 The \c main() function |
| |
| \snippet tools/echoplugin/echowindow/main.cpp 0 |
| |
| We create an \c EchoWindow and display it as a top-level window. |
| |
| \section1 The Profiles |
| |
| When creating plugins the profiles need to be adjusted. |
| We show here what changes need to be done. |
| |
| The profile in the echoplugin directory uses the \c subdirs |
| template and simply includes includes to directories in which |
| the echo window and echo plugin lives: |
| |
| \snippet tools/echoplugin/echoplugin.pro 0 |
| |
| The profile for the echo window does not need any plugin specific |
| settings. We move on to the plugin profile: |
| |
| \snippet tools/echoplugin/plugin/plugin.pro 0 |
| |
| We need to set the TEMPLATE as we now want to make a library |
| instead of an executable. We also need to tell qmake that we are |
| creating a plugin. The \c EchoInterface that the plugin implements |
| lives in the \c echowindow directory, so we need to add that |
| directory to the include path. We set the TARGET of the project, |
| which is the name of the library file in which the plugin will be |
| stored; qmake appends the appropriate file extension depending on |
| the platform. By convention the target should have the same name |
| as the plugin (set with Q_EXPORT_PLUGIN2) |
| |
| \section1 Further Reading and Examples |
| |
| The \l {qtplugin-defining-plugins}{Defining Plugins} page presents an overview of the macros needed to |
| create plugins. |
| |
| We give an example of a plugin that extends Qt in the \l{Style |
| Plugin Example}{style plugin} example. The \l{Plug & Paint |
| Example}{plug and paint} example shows how to create static |
| plugins. |
| */ |