Remove echo plugin
Remove echo plugin code and documentation. Fixes: QTBUG-119981 Change-Id: I4083ac6cdb768facaed041241af2c5ee6e28df50 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit 01bf423d67d5e6f8de5ec51a6b85178492681ca9) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
d8b113f46f
commit
83df3a8138
Binary file not shown.
Before Width: | Height: | Size: 7.6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 10 KiB |
@ -1,180 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\example tools/echoplugin
|
||||
\title Echo Plugin Example
|
||||
\examplecategory {Data Processing & I/O}
|
||||
\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.
|
||||
*/
|
@ -130,8 +130,4 @@
|
||||
In addition to the plugin \l{How to Create Qt Plugins}{overview
|
||||
document}, we have other examples and articles that concern
|
||||
plugins.
|
||||
|
||||
In the \l{Echo Plugin Example}{echo plugin example} we show how to
|
||||
implement plugins that extends Qt applications rather than Qt
|
||||
itself, which is the case with the style plugin of this example.
|
||||
*/
|
||||
|
@ -7,7 +7,3 @@ qt_internal_add_example(regularexpression)
|
||||
qt_internal_add_example(styleplugin)
|
||||
qt_internal_add_example(treemodelcompleter)
|
||||
qt_internal_add_example(undoframework)
|
||||
|
||||
if(QT_FEATURE_library)
|
||||
qt_internal_add_example(echoplugin)
|
||||
endif()
|
||||
|
@ -1,18 +0,0 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(echoplugin LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/tools/echoplugin")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
add_subdirectory(plugin)
|
||||
add_subdirectory(echowindow)
|
@ -1,5 +0,0 @@
|
||||
#! [0]
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS = echowindow \
|
||||
plugin
|
||||
#! [0]
|
@ -1,35 +0,0 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt_add_executable(echopluginwindow
|
||||
echointerface.h
|
||||
echowindow.cpp echowindow.h
|
||||
main.cpp
|
||||
)
|
||||
|
||||
set_target_properties(echopluginwindow PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(echopluginwindow PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
if(QT6_IS_SHARED_LIBS_BUILD)
|
||||
# Build the shared plugin too when building this example target.
|
||||
add_dependencies(echopluginwindow echoplugin)
|
||||
else()
|
||||
# Link the echoplugin if Qt is built statically.
|
||||
target_link_libraries(echopluginwindow PRIVATE
|
||||
echoplugin
|
||||
)
|
||||
endif()
|
||||
|
||||
install(TARGETS echopluginwindow
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
@ -1,27 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef ECHOINTERFACE_H
|
||||
#define ECHOINTERFACE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
//! [0]
|
||||
class EchoInterface
|
||||
{
|
||||
public:
|
||||
virtual ~EchoInterface() = default;
|
||||
virtual QString echo(const QString &message) = 0;
|
||||
};
|
||||
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#define EchoInterface_iid "org.qt-project.Qt.Examples.EchoInterface"
|
||||
|
||||
Q_DECLARE_INTERFACE(EchoInterface, EchoInterface_iid)
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
#endif
|
@ -1,90 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "echowindow.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QPluginLoader>
|
||||
#include <QPushButton>
|
||||
|
||||
//! [0]
|
||||
EchoWindow::EchoWindow()
|
||||
{
|
||||
createGUI();
|
||||
setLayout(layout);
|
||||
setWindowTitle("Echo Plugin Example");
|
||||
|
||||
if (!loadPlugin()) {
|
||||
QMessageBox::information(this, "Error", "Could not load the plugin");
|
||||
lineEdit->setEnabled(false);
|
||||
button->setEnabled(false);
|
||||
}
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
void EchoWindow::sendEcho()
|
||||
{
|
||||
QString text = echoInterface->echo(lineEdit->text());
|
||||
label->setText(text);
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
void EchoWindow::createGUI()
|
||||
{
|
||||
lineEdit = new QLineEdit;
|
||||
label = new QLabel;
|
||||
label->setFrameStyle(QFrame::Box | QFrame::Plain);
|
||||
button = new QPushButton(tr("Send Message"));
|
||||
|
||||
connect(lineEdit, &QLineEdit::editingFinished,
|
||||
this, &EchoWindow::sendEcho);
|
||||
connect(button, &QPushButton::clicked,
|
||||
this, &EchoWindow::sendEcho);
|
||||
|
||||
layout = new QGridLayout;
|
||||
layout->addWidget(new QLabel(tr("Message:")), 0, 0);
|
||||
layout->addWidget(lineEdit, 0, 1);
|
||||
layout->addWidget(new QLabel(tr("Answer:")), 1, 0);
|
||||
layout->addWidget(label, 1, 1);
|
||||
layout->addWidget(button, 2, 1, Qt::AlignRight);
|
||||
layout->setSizeConstraint(QLayout::SetFixedSize);
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
bool EchoWindow::loadPlugin()
|
||||
{
|
||||
QDir pluginsDir(QCoreApplication::applicationDirPath());
|
||||
#if defined(Q_OS_WIN)
|
||||
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
|
||||
pluginsDir.cdUp();
|
||||
#elif defined(Q_OS_MAC)
|
||||
if (pluginsDir.dirName() == "MacOS") {
|
||||
pluginsDir.cdUp();
|
||||
pluginsDir.cdUp();
|
||||
pluginsDir.cdUp();
|
||||
}
|
||||
#endif
|
||||
pluginsDir.cd("plugins");
|
||||
const QStringList entries = pluginsDir.entryList(QDir::Files);
|
||||
for (const QString &fileName : entries) {
|
||||
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
|
||||
QObject *plugin = pluginLoader.instance();
|
||||
if (plugin) {
|
||||
echoInterface = qobject_cast<EchoInterface *>(plugin);
|
||||
if (echoInterface)
|
||||
return true;
|
||||
pluginLoader.unload();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//! [3]
|
@ -1,42 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef ECHODIALOG_H
|
||||
#define ECHODIALOG_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "echointerface.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QString;
|
||||
class QLineEdit;
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QGridLayout;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
class EchoWindow : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EchoWindow();
|
||||
|
||||
private slots:
|
||||
void sendEcho();
|
||||
|
||||
private:
|
||||
void createGUI();
|
||||
bool loadPlugin();
|
||||
|
||||
EchoInterface *echoInterface;
|
||||
QLineEdit *lineEdit;
|
||||
QLabel *label;
|
||||
QPushButton *button;
|
||||
QGridLayout *layout;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|
@ -1,21 +0,0 @@
|
||||
QT += widgets
|
||||
|
||||
HEADERS = echowindow.h \
|
||||
echointerface.h
|
||||
SOURCES = echowindow.cpp \
|
||||
main.cpp
|
||||
|
||||
TARGET = echoplugin
|
||||
QMAKE_PROJECT_NAME = echopluginwindow
|
||||
win32 {
|
||||
CONFIG(debug, release|debug):DESTDIR = ../debug/
|
||||
CONFIG(release, release|debug):DESTDIR = ../release/
|
||||
} else {
|
||||
DESTDIR = ../
|
||||
}
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin
|
||||
INSTALLS += target
|
||||
|
||||
CONFIG += install_ok # Do not cargo-cult this!
|
@ -1,19 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include "echowindow.h"
|
||||
#include "echointerface.h"
|
||||
|
||||
//! [0]
|
||||
int main(int argv, char *args[])
|
||||
{
|
||||
QApplication app(argv, args);
|
||||
|
||||
EchoWindow window;
|
||||
window.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
//! [0]
|
@ -1,26 +0,0 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt_add_plugin(echoplugin
|
||||
CLASS_NAME EchoPlugin
|
||||
echoplugin.cpp echoplugin.h
|
||||
)
|
||||
|
||||
set_target_properties(echoplugin PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/echowindow"
|
||||
)
|
||||
|
||||
target_include_directories(echoplugin PRIVATE
|
||||
../echowindow
|
||||
)
|
||||
|
||||
target_link_libraries(echoplugin PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
install(TARGETS echoplugin
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
@ -1,11 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "echoplugin.h"
|
||||
|
||||
//! [0]
|
||||
QString EchoPlugin::echo(const QString &message)
|
||||
{
|
||||
return message;
|
||||
}
|
||||
//! [0]
|
@ -1,23 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef ECHOPLUGIN_H
|
||||
#define ECHOPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtPlugin>
|
||||
#include "echointerface.h"
|
||||
|
||||
//! [0]
|
||||
class EchoPlugin : public QObject, EchoInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.EchoInterface" FILE "echoplugin.json")
|
||||
Q_INTERFACES(EchoInterface)
|
||||
|
||||
public:
|
||||
QString echo(const QString &message) override;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|
@ -1 +0,0 @@
|
||||
{}
|
@ -1,18 +0,0 @@
|
||||
#! [0]
|
||||
TEMPLATE = lib
|
||||
CONFIG += plugin
|
||||
QT += widgets
|
||||
INCLUDEPATH += ../echowindow
|
||||
HEADERS = echoplugin.h
|
||||
SOURCES = echoplugin.cpp
|
||||
TARGET = $$qtLibraryTarget(echoplugin)
|
||||
DESTDIR = ../plugins
|
||||
#! [0]
|
||||
|
||||
EXAMPLE_FILES = echoplugin.json
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin/plugins
|
||||
INSTALLS += target
|
||||
|
||||
CONFIG += install_ok # Do not cargo-cult this!
|
@ -2,13 +2,8 @@ TEMPLATE = subdirs
|
||||
SUBDIRS = \
|
||||
completer \
|
||||
customcompleter \
|
||||
echoplugin \
|
||||
regularexpression \
|
||||
styleplugin \
|
||||
treemodelcompleter \
|
||||
undoframework
|
||||
|
||||
!qtConfig(library) {
|
||||
SUBDIRS -= \
|
||||
echoplugin
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ using namespace Qt::StringLiterals;
|
||||
link to plugins statically. You can use QLibrary if you need to
|
||||
load dynamic libraries in a statically linked application.
|
||||
|
||||
\sa QLibrary, {Echo Plugin Example}
|
||||
\sa QLibrary
|
||||
*/
|
||||
|
||||
static constexpr QLibrary::LoadHints defaultLoadHints = QLibrary::PreventUnloadHint;
|
||||
|
Loading…
x
Reference in New Issue
Block a user