QObject :: connect:无法连接(null):: mySignal()到(null):: mySlot()

时间:2016-03-21 00:12:42

标签: c++ qt c++11 qt4 qt5

在尝试连接插件之间的信号/插槽时,我忽略了这一点。考虑this question我做了以下事情。

我将展示3个Qt项目的完整源代码:

  • pluginTCP:插件
  • pluginRaw:另一个插件
  • 平台:使用插件的平台

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。为什么呢?

1 个答案:

答案 0 :(得分:1)

我太懒了,无法编译这么长的项目,但是我看到了为什么你的代码无法工作以及为什么你从演员表中得到一个空指针的原因。

在插件中使用继承

class RawPlugin : public QObject, PluginInterface

相当于

class RawPlugin : public QObject, private PluginInterface

这意味着您的基类PluginInterface无法访问,dynamic_castqobject_cast将失败。

修复很简单:

class RawPlugin : public QObject, public PluginInterface