在尝试连接插件之间的信号/插槽时,我忽略了这一点。考虑this question我做了以下事情。
我将展示3个Qt项目的完整源代码:
pluginTcp.pro
TEMPLATE = lib
CONFIG += plugin
CONFIG(debug, debug | release) {
DESTDIR = debug
} else {
DESTDIR = release
}
OBJECTS_DIR = $$DESTDIR
MOC_DIR = $$DESTDIR
RCC_DIR = $$DESTDIR
UI_DIR = $$DESTDIR
QMAKE_CXXFLAGS += -std=c++0x
HEADERS = ../../plugins/plugininterface.h \
../tcpplugin.h
SOURCES = ../tcpplugin.cpp
TARGET = $$qtLibraryTarget(tplugin)
DESTDIR = ../../plugins
plugininterface.h
class PluginInterface
{
public:
virtual ~PluginInterface() {}
signals:
virtual void mySignal() = 0;
public slots:
virtual void mySlot() = 0;
};
#define PluginInterface_iid "org.qt-project.Qt.Examples.PluginInterface"
Q_DECLARE_INTERFACE(PluginInterface, PluginInterface_iid)
tcpplugin.h
#include <QObject>
#include "../plugins/plugininterface.h"
class QLineEdit;
class TcpPlugin : public QObject, PluginInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.PluginInterface" /*FILE "echoplugin.json"*/)
Q_INTERFACES(PluginInterface)
public:
TcpPlugin();
signals:
void mySignal() Q_DECL_FINAL;
public slots:
void mySlot() Q_DECL_OVERRIDE;
};
tcpplugin.h
#include "tcpplugin.h"
TcpPlugin::TcpPlugin()
{
}
void TcpPlugin::mySlot()
{
}
pluginRaw.pro
TEMPLATE = lib
CONFIG += plugin
CONFIG(debug, debug | release) {
DESTDIR = debug
} else {
DESTDIR = release
}
OBJECTS_DIR = $$DESTDIR
MOC_DIR = $$DESTDIR
RCC_DIR = $$DESTDIR
UI_DIR = $$DESTDIR
QMAKE_CXXFLAGS += -std=c++0x
HEADERS = ../../plugins/plugininterface.h \
../rawplugin.h
SOURCES = ../rawplugin.cpp
TARGET = $$qtLibraryTarget(rawplugin)
DESTDIR = ../../plugins
rawplugin.h
#include <QObject>
#include "../plugins/plugininterface.h"
class RawPlugin : public QObject, PluginInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.PluginInterface" /*FILE "echoplugin.json"*/)
Q_INTERFACES(PluginInterface)
public:
RawPlugin();
signals:
void mySignal() Q_DECL_FINAL;
public slots:
void mySlot() Q_DECL_OVERRIDE;
};
rawplugin.cpp
#include "rawplugin.h"
RawPlugin::RawPlugin()
{
}
void RawPlugin::mySlot()
{
}
platform.pro
QT += core widgets
TEMPLATE = app
CONFIG(debug, debug | release) {
DESTDIR = debug
} else {
DESTDIR = release
}
OBJECTS_DIR = $$DESTDIR
MOC_DIR = $$DESTDIR
RCC_DIR = $$DESTDIR
UI_DIR = $$DESTDIR
QMAKE_CXXFLAGS += -std=c++0x
HEADERS += ../../plugins/plugininterface.h \
../mainwindow.h
SOURCES += ../main.cpp \
../mainwindow.cpp
的main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argv, char *args[])
{
QApplication app(argv, args);
MainWindow window;
window.show();
return app.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "../../plugins/plugininterface.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
private:
PluginInterface *loadPlugin(const QString name);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QDir>
#include <QPluginLoader>
#include <QApplication>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
PluginInterface *t = loadPlugin("tplugind.dll");
PluginInterface *r = loadPlugin("rawplugind.dll");
connect(dynamic_cast<QObject*>(t), SIGNAL(mySignal()),
dynamic_cast<QObject*>(r), SLOT(mySlot()));
}
PluginInterface *MainWindow::loadPlugin(const QString name)
{
PluginInterface *p;
QDir pluginsDir(qApp->applicationDirPath());
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
pluginsDir.cdUp();
pluginsDir.cd("../../plugins");
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(name));
QObject *plugin = pluginLoader.instance();
if (plugin)
p = qobject_cast<PluginInterface *>(plugin);
return p;
}
似乎dynamic_cast<QObject*>
返回null。为什么呢?
答案 0 :(得分:1)
我太懒了,无法编译这么长的项目,但是我看到了为什么你的代码无法工作以及为什么你从演员表中得到一个空指针的原因。
在插件中使用继承
class RawPlugin : public QObject, PluginInterface
相当于
class RawPlugin : public QObject, private PluginInterface
这意味着您的基类PluginInterface
无法访问,dynamic_cast
或qobject_cast
将失败。
修复很简单:
class RawPlugin : public QObject, public PluginInterface