当前位置:网站首页>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
边栏推荐
- Getting started with Message Oriented Middleware
- 无心剑中译泰戈尔《漂鸟集(1~10)》
- How to use AAB to APK and APK to AAB of Google play apps on the shelves
- Brush questions -- sword finger offer
- The mixlab editing team is recruiting teammates~~
- MB10M-ASEMI整流桥MB10M
- 架构实战营 - 第 6 期 毕业总结
- ASEMI整流桥UMB10F参数,UMB10F规格,UMB10F封装
- Low level version of drawing interface (explain each step in detail)
- 探索Cassandra的去中心化分布式架构
猜你喜欢
[系统安全] 四十三.Powershell恶意代码检测系列 (5)抽象语法树自动提取万字详解
Nifi from introduction to practice (nanny level tutorial) - flow
Salary 3000, monthly income 40000 by "video editing": people who can make money never rely on hard work!
The difference between calling by value and simulating calling by reference
How can technology managers quickly improve leadership?
How to use AAB to APK and APK to AAB of Google play apps on the shelves
Brush questions -- sword finger offer
From the 18th line to the first line, the new story of the network security industry
[proteus simulation] 8 × 8LED dot matrix screen imitates elevator digital scrolling display
近视:摘镜or配镜?这些问题必须先了解清楚
随机推荐
Deep understanding of grouping sets statements in SQL
《天天数学》连载56:二月二十五日
Using optimistic lock and pessimistic lock in MySQL to realize distributed lock
阿飞的期望
Getting started with Message Oriented Middleware
用同花顺炒股开户安全吗?
“用Android复刻Apple产品UI”(2)——丝滑的AppStore卡片转场动画
"Remake Apple product UI with Android" (3) - elegant statistical chart
“用Android复刻Apple产品UI”(3)—优雅的数据统计图表
pyinstaller不是内部或外部命令,也不是可运行的程序 或批处理文件
拼夕夕二面:说说布隆过滤器与布谷鸟过滤器?应用场景?我懵了。。
How to use AAB to APK and APK to AAB of Google play apps on the shelves
Unity project optimization case 1
[combinatorics] combinatorial identities (sum of variable terms 3 combinatorial identities | sum of variable terms 4 combinatorial identities | binomial theorem + derivation to prove combinatorial ide
六月 致 -.-- -..- -
【OpenCV 例程200篇】217. 鼠标交互获取多边形区域(ROI)
How can technology managers quickly improve leadership?
"Remake Apple product UI with Android" (2) -- silky Appstore card transition animation
PHP CI(CodeIgniter)log级别设置
Persisting in output requires continuous learning