1、插件和多线程问题:
创建插件对象不能放到多线程执行,不然报错:ASSERT failure in QWidget: "Widgets must be created in the GUlthread.
//不能放在多线程执行
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject* plugin = pluginLoader.instance();
解决办法:把创建插件的对象写到一个方法里,然后把这个方法强制塞入主线程执行。
QMetaObject::invokeMethod(qApp, [this]() { //对象不是静态
QMetaObject::invokeMethod(qApp, []() { //对象是静态
下图中m_PluginCore是静态指针
getinstance方法会在多线程执行,但loadPlugin会被强制塞入主线程执行,执行完毕继续多线程执行下面的代码
2、插件都会被创建为QObject*对象,怎么通过QObject*直接调用插件基类中的方法(这种方式也实现了只有插件dll,没有头文件也能调用插件中的方法)
假如插件基类有个纯虚函数virtual QWidget* getWidget()=0;
现通过QObject*直接调用getWidget
第一步:插件实现纯虚函数时把方法通过 Q_INVOKABLE 宏注册到 Qt 的元对象系统中,即在方法前加Q_INVOKABLE
Q_INVOKABLE QWidget* GetWidget(){....}
第二步:
//获取插件对象的元对象
const QMetaObject* metaObject = plugin->metaObject();
//获取方法索引。如果返回值为 -1,则说明没有找到该方法
int methodIndex = metaObject->indexOfMethod("GetWidget()");
if (methodIndex != -1) {
//获取方法
QMetaMethod method = metaObject->method(methodIndex);
// 调用插件中的方法
QWidget* result = nullptr;
// 判断方法是否调用成功,如果成功可以获取到result指针,success返回true
bool success = method.invoke(plugin, Q_RETURN_ARG(QWidget*, result));
}