Qt使用QPluginLoader实现热插拔的功能

本文介绍了如何在Qt中创建一个新的QWidget项目,定义一个插件接口类TestInterface,并演示了如何通过loadPlugin函数加载和管理插件,包括loadHints的作用以及如何在卸载后删除插件。
摘要由CSDN通过智能技术生成

新建一个QWidget项目,并定义一个插件接口类

在这里插入图片描述

testinterface.h

#pragma once

#include <QObject>

class TestInterface {

public:
	TestInterface(){};
	virtual ~TestInterface() {};

	virtual void print() = 0;
};

//一定是唯一的标识符
#define TestInterface_iid "Examples.Plugin.TestInterface"

QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(TestInterface, TestInterface_iid)
QT_END_NAMESPACE
插件加载函数

bool Test::loadPlugin() {
	QDir pluginsDir(qApp->applicationDirPath());
	pluginsDir.cd("plugins");
	QStringList names = pluginsDir.entryList(QDir::Files);
	for (QString fileName : names) {
		pluginLoader->setFileName(pluginsDir.absoluteFilePath(fileName));
		qDebug() << pluginLoader->loadHints();
		//pluginLoader->setLoadHints(QLibrary::PreventUnloadHint);
		pluginLoader->setLoadHints(0);
		qDebug() << pluginLoader->loadHints();
		QObject* plugin = pluginLoader->instance();
		if (plugin) {
			testIn == nullptr ?
				testIn = qobject_cast<TestInterface*>(plugin) : void();
			testIn->print();
			break;
		}
		else {
			qWarning() << "插件加载错误:" + pluginLoader->errorString().toUtf8();
			//return false;
		}
	}
	QTimer::singleShot(300, this, [&]() {
		bool stesa;
		stesa = pluginLoader->isLoaded();//判断是否加载
		stesa = pluginLoader->unload();//卸载
		//testIn->print();
		qWarning() << stesa;
		});

	return true;
}

以上代码只是测试加载和卸载
通过测试插件加载时默认的loadHints是PreventUnloadHint,即使卸载成功也无法删除插件,但是能改名称,如果想卸载后删除插件需要在instance()前调用pluginLoader->setLoadHints(0);

在这里插入图片描述

新建插件项目

在这里插入图片描述
在这里插入图片描述
将插件生成路径改到运行程序根目录的plugins文件下
在这里插入图片描述

代码如下

qtclasslibrary1.h

#pragma once

#include "qtclasslibrary1_global.h"
#include <QGenericPlugin>
#include "../test/testinterface.h"

class QTCLASSLIBRARY1_EXPORT QtClassLibrary1 :public QObject, public TestInterface {
	Q_OBJECT
	Q_INTERFACES(TestInterface)
	Q_PLUGIN_METADATA(IID TestInterface_iid)

public:
    QtClassLibrary1();
	~QtClassLibrary1();

	void print();//继承接口,并实现成员函数

};
qtclasslibrary1.cpp

#include "qtclasslibrary1.h"
QtClassLibrary1::QtClassLibrary1(){

}

QtClassLibrary1::~QtClassLibrary1() {

}

void QtClassLibrary1::print() {
	qDebug() << "sjfkdjsfd";
}

总结:
1.多个插件可以使用同样的接口,插件会被重复的单独加载成一个实例。
2.插件加载时默认的loadHints是PreventUnloadHint,即使卸载成功也无法删除插件,但是能改名称,如果想卸载后删除插件需要调用pluginLoader->setLoadHints(0)
setLoadHints(0)出处;
3.一旦卸载成功,插件的所有引用将不能使用
若多个实例使用了相同的插件,则唯有当所有实例都调用 unload()时,函数才会返回true,插件才会被卸载,之前的实例在调用unload()时都会返回false

要在Qt实现USB热插拔检测,可以使用QDeviceWatcher类。QDeviceWatcher是一个用于监测设备插入和移除事件的类。 首先,确保在项目文件(.pro)中添加以下内容以启用Qt的udev库: ```cpp LIBS += -ludev ``` 然后,可以按照以下步骤在Qt实现USB热插拔检测: 1. 在头文件中包含必要的头文件: ```cpp #include <QObject> #include <QDeviceWatcher> ``` 2. 创建一个类并继承自QObject: ```cpp class USBWatcher : public QObject { Q_OBJECT public: explicit USBWatcher(QObject *parent = nullptr); private slots: void deviceAdded(const QString &devPath); void deviceRemoved(const QString &devPath); private: QDeviceWatcher *m_deviceWatcher; }; ``` 3. 在实现文件中定义构造函数,并在构造函数中初始化QDeviceWatcher对象,并连接相应的槽函数: ```cpp USBWatcher::USBWatcher(QObject *parent) : QObject(parent) { m_deviceWatcher = new QDeviceWatcher(this); connect(m_deviceWatcher, SIGNAL(deviceAdded(QString)), this, SLOT(deviceAdded(QString))); connect(m_deviceWatcher, SIGNAL(deviceRemoved(QString)), this, SLOT(deviceRemoved(QString))); m_deviceWatcher->start(); } ``` 4. 实现设备插入和移除的槽函数: ```cpp void USBWatcher::deviceAdded(const QString &devPath) { // 处理设备插入事件 qDebug() << "Device added: " << devPath; } void USBWatcher::deviceRemoved(const QString &devPath) { // 处理设备移除事件 qDebug() << "Device removed: " << devPath; } ``` 5. 在你的应用程序中实例化USBWatcher对象,并将其保持活动状态: ```cpp int main(int argc, char *argv[]) { QApplication app(argc, argv); USBWatcher usbWatcher; return app.exec(); } ``` 通过以上步骤,你现在可以在`deviceAdded()`和`deviceRemoved()`槽函数中处理设备插入和移除事件。你可以根据需求来执行一些自定义的操作,比如更新UI或者执行特定的任务。 请注意,USB热插拔检测需要在具有相应权限的操作系统上运行,如Linux。在不同的操作系统和平台上,可能需要使用不同的方法来实现设备监测。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值