当前位置:网站首页>Custom plug-in construction and use of QT plug-in
Custom plug-in construction and use of QT plug-in
2022-07-03 16:16:00 【Manon Feifei】
List of articles
The last article introduced how to build Qt Designer plug-in unit . In fact, the plug-in mechanism QT It's open to the outside world , Here is how to use QT Develop custom plug-ins . Before developing a custom plug-in, we first define the plug-in SDK. The plug-in SDK Is the interface description of the plug-in , Any plug-in developed by developers should implement the corresponding interface . At the same time, as long as the plug-in of the corresponding interface is implemented , Can be integrated into the system , This actually provides a unified interface standard for custom plug-ins .
Define the SDK
Here we define the plug-in SDK, The implementation is as follows :
//sdk/MyPluginInterface.h
#ifndef MY_PLUGIN_INTERFACE_H
#define MY_PLUGIN_INTERFACE_H
#include <QWidget>
// Prevent naming conflicts by adding namespaces
namespace Plugin {
class MyPluginInterface
{
public:
virtual ~MyPluginInterface() {
}
// Name of the plug-in instance
virtual QString name() const = 0;
// establish UI Example
virtual QWidget* createWidget(QWidget* parent) = 0;
// Get the display name of the plug-in
virtual QString displayName() const = 0;
};
}
// Defined in the QT The globally unique interface in the system ID
// Realize the SDK The plug-in of should also define the same ID
// Interface ID Contains version information , Through the ID We can distinguish between different versions SDK And plug-ins
//Q_DECLARE_INTERFACE Macros will be of type and ID Connect , such QT You can verify whether the loaded plug-in can be converted into MyPluginInterface type
#define interface_iid "org.pluginqt.custompluginuse.myplugin.myplugin1.0.0"
Q_DECLARE_INTERFACE(Plugin::MyPluginInterface, interface_iid)
#endif
The plug-in SDK The plug-in interface is defined in QT Global in object system ID. At the same time, in order to prevent naming conflicts , We also added a namespace to the interface of the plug-in , Prevent naming conflicts in different environments .
Write a custom plug-in
First, create a new dynamic library project . The project configuration is as follows :
QT += core widgets
TARGET = $$qtLibraryTarget(custom-colorcombo-plugin)
TEMPLATE = lib
CONFIG += plugin
# Include the corresponding plug-ins SDK Catalog
INCLUDEPATH += $$PWD/sdk
DEPENDPATH += $$PWD/sdk
# Specify the output path
debug:DESTDIR = $$PWD/../CustomPlugin_output/debug/
release:DESTDIR =$$PWD/../CustomPlugin_output/release/
SOURCES += \
customplugin.cpp \
colorcombox.cpp
HEADERS += \
customplugin.h \
colorcombox.h
# add to SDK file
OTHER_FILES += \
sdk/MyPluginInterface.h \
After creating the plug-in project , Write with QT Designer The plug-in is the same , Add one inherited from MyPluginInterface and QObject Class plug-in information description class , The plug-in ID Should be and SDK Medium ID bring into correspondence with . The specific implementation is as follows :
//customplugin.h
#ifndef CUSTOMPLUGIN_H
#define CUSTOMPLUGIN_H
#include "sdk/MyPluginInterface.h"
#include <QObject>
class CustomPlugin : public QObject, Plugin::MyPluginInterface
{
Q_OBJECT
// Statement QT Unique identifier of the identification
// and SDK Medium ID bring into correspondence with
Q_PLUGIN_METADATA(IID "org.pluginqt.custompluginuse.myplugin.myplugin1.0.0")
// Declare the implemented plug-in interface
Q_INTERFACES(Plugin::MyPluginInterface)
public:
CustomPlugin(QObject* parent = 0);
QString name() const override;
QWidget* createWidget(QWidget* parent) override;
QString displayName() const override;
};
#endif // CUSTOMPLUGIN_H
//customplugin.cpp
#include "customplugin.h"
#include "colorcombox.h"
CustomPlugin::CustomPlugin(QObject *parent):QObject(parent)
{
}
QString CustomPlugin::name() const
{
return "colorCombox";
}
QWidget* CustomPlugin::createWidget(QWidget* parent)
{
return new ColorComboBox(parent);
}
QString CustomPlugin::displayName() const
{
return " Used to select colors ";
}
The plug-in is responsible for loading a user-defined control , Here, the color drop-down list control is also taken as an example , The specific implementation is as follows :
//colorcombox.h
#ifndef COLORCOMBOBOX_H
#define COLORCOMBOBOX_H
#include <QComboBox>
class ColorComboBox : public QComboBox
{
Q_OBJECT
public:
explicit ColorComboBox(QWidget *parent = 0);
private slots:
void slot_currentIndexChanged(int index);
public:
bool getShowColorName();
QString getColorName();
public slots:
void setShowColorName(bool showColorName);
void setColorName(QString colorName);
void initColorItems();
signals:
// Name and color change signal
void colorChanged(QString colorName);
void colorChanged(QColor color);
private:
// Whether to display English name
bool menableColorName;
// Current color name
QString mcolorName;
};
#endif // COLORCOMBOBOX_H
//colorcombox.cpp
#include "colorcombox.h"
ColorComboBox::ColorComboBox(QWidget *parent) : QComboBox(parent),
menableColorName(true)
{
initColorItems();
connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(slot_currentIndexChanged(int)));
}
void ColorComboBox::slot_currentIndexChanged(int index)
{
if (index >= 0)
{
mcolorName = QColor::colorNames().at(index);
emit colorChanged(mcolorName);
emit colorChanged(QColor(mcolorName));
}
}
bool ColorComboBox::getShowColorName()
{
return menableColorName;
}
QString ColorComboBox::getColorName()
{
return mcolorName;
}
void ColorComboBox::setShowColorName(bool showColorName)
{
if (menableColorName != showColorName) {
menableColorName = showColorName;
}
}
void ColorComboBox::setColorName(QString colorName)
{
if (mcolorName != colorName)
{
mcolorName = colorName;
int index = QColor::colorNames().indexOf(colorName);
this->setCurrentIndex(index);
}
}
void ColorComboBox::initColorItems()
{
clear();
QStringList colorList = QColor::colorNames();
for(QString strColor: colorList)
{
QPixmap pix(this->iconSize());
pix.fill(strColor);
this->addItem(QIcon(pix), menableColorName ? strColor : "");
}
}
Dynamically load custom plug-ins
After writing the custom plug-in , We can use QPluginLoader Dynamically load custom plug-ins . adopt QPluginLoader Class loading plug-ins , It can automatically check the of writing plug-ins QT Version and write the main application QT Version consistency , At the same time through instance() You can directly convert plug-in objects into QObject object .
When loading plug-ins , We can also pass QPluginLoader Get plug-in METADATA, Then according to different Q_PLUGIN_METADATA Perform different actions . In this way, the main application can be compatible with different versions of plug-ins .
An example of dynamically loading plug-ins in the main application is shown below :
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
public slots:
void slot_load_plugin();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
//widget.cpp
#pragma execution_character_set("utf-8")
#include "ui_widget.h"
#include "sdk/MyPluginInterface.h"
#include <QFileDialog>
#include <QPluginLoader>
#include <QHBoxLayout>
#include <memory>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui->load_plugin_btn,SIGNAL(clicked(bool)),this, SLOT(slot_load_plugin()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::slot_load_plugin()
{
QString file_path = QFileDialog::getOpenFileName(NULL," Add plug-ins ","../cutomplugin_output","dll (*.dll *.so)");
if(file_path.isEmpty())
{
return;
}
QPluginLoader pluginLoader(file_path);
QObject* plugin = pluginLoader.instance();
if (plugin) {
std::unique_ptr<Plugin::MyPluginInterface> interface_ptr = std::unique_ptr<Plugin::MyPluginInterface>(qobject_cast<Plugin::MyPluginInterface*>(plugin));
QWidget* widget = interface_ptr->createWidget(this);
widget->setFixedHeight(40);
widget->setFixedWidth(200);
QHBoxLayout* mainLayout = new QHBoxLayout(this);
mainLayout->addWidget(widget);
ui->widget->setLayout(mainLayout);
}
}
The dynamic loading effect of custom plug-ins is as follows :
distribution SDK
Define the plug-in SDK after , We can SDK Distribute to plug-in developers . As long as the plug-in developed by the plug-in developer realizes the corresponding SDK Interface , Then the developed plug-ins can be integrated into the corresponding system . In this way, plug-in development and main application development are completely decoupled . Developers do not need to know the details of the main application to develop plug-ins that can be integrated into the main application .
Reference examples
link :https://pan.baidu.com/s/1HoG3OAAyEbozs7CshH0B1w
Extraction code :vt3x
边栏推荐
- Microservice - fuse hystrix
- How can technology managers quickly improve leadership?
- 关于网页中的文本选择以及统计选中文本长度
- Page dynamics [2]keyframes
- Salary 3000, monthly income 40000 by "video editing": people who can make money never rely on hard work!
- Pandora IOT development board learning (HAL Library) - Experiment 5 external interrupt experiment (learning notes)
- 远程办公之大家一同实现合作编辑资料和开发文档 | 社区征文
- App mobile terminal test [4] APK operation
- [combinatorics] combinatorial identities (review of eight combinatorial identities | product of combinatorial identities 1 | proof | use scenario | general method for finding combinatorial numbers)
- The accept attribute of the El upload upload component restricts the file type (detailed explanation of the case)
猜你喜欢

TCP拥塞控制详解 | 3. 设计空间

Initial test of scikit learn Library

【OpenCV 例程200篇】217. 鼠标交互获取多边形区域(ROI)
![[list to map] collectors Tomap syntax sharing (case practice)](/img/ac/e02deb1cb237806d357a88fb812852.jpg)
[list to map] collectors Tomap syntax sharing (case practice)
![App mobile terminal test [3] ADB command](/img/f1/4bff6e66b77d0f867bf7237019e982.png)
App mobile terminal test [3] ADB command

Break through 1million, sword finger 2million!

ASEMI整流桥UMB10F参数,UMB10F规格,UMB10F封装

nifi从入门到实战(保姆级教程)——flow
![[系统安全] 四十三.Powershell恶意代码检测系列 (5)抽象语法树自动提取万字详解](/img/cd/00954b9c592c253d42e6a3b8298999.jpg)
[系统安全] 四十三.Powershell恶意代码检测系列 (5)抽象语法树自动提取万字详解

Détails du contrôle de la congestion TCP | 3. Espace de conception
随机推荐
Why does the std:: string operation perform poorly- Why do std::string operations perform poorly?
Page dynamics [2]keyframes
分布式事务(Seata) 四大模式详解
[combinatorics] non descending path problem (outline of non descending path problem | basic model of non descending path problem | non descending path problem expansion model 1 non origin starting poi
如何在本机搭建SVN服务器
坚持输出需要不断学习
Slam learning notes - build a complete gazebo multi machine simulation slam from scratch (I)
Hibernate的缓存机制/会话级缓存机制
Qt插件之自定义插件构建和使用
How to thicken the brush in the graphical interface
Persisting in output requires continuous learning
Semi supervised learning
Approval process design
How to use AAB to APK and APK to AAB of Google play apps on the shelves
首发!!lancet饿了么官方文档
Batch files: list all files in a directory with relative paths - batch files: list all files in a directory with relative paths
Initial test of scikit learn Library
Pandora IOT development board learning (HAL Library) - Experiment 5 external interrupt experiment (learning notes)
Famous blackmail software stops operation and releases decryption keys. Most hospital IOT devices have security vulnerabilities | global network security hotspot on February 14
【Proteus仿真】8×8LED点阵屏仿电梯数字滚动显示