2016-03-21 6 views
0

Мне не хватает точки при попытке подключения сигналов/слотов между плагинами. Учитывая this question Я сделал следующее.QObject :: connect: Не удается подключиться (null) :: mySignal() to (null) :: mySlot()

Я буду представлять полный исходный код из 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*> возвращается нуль. Зачем?

+0

почему вы литье в любом случае? – AngryDuck

+0

, вы также дали waaaay большому коду, который не имеет ничего общего с вашей проблемой. – AngryDuck

+0

Говорят, что он был брошен на http://stackoverflow.com/questions/36117031/qt-piping-data-between-plugins, by @Felix , – KcFnMi

ответ

1

Я слишком ленив, чтобы скомпилировать такой длинный проект, но я вижу одну причину, почему ваш код не работает и почему вы получаете нулевой указатель от актера.

В ваших плагинов использовать наследование

class RawPlugin : public QObject, PluginInterface 

что эквивалентно

class RawPlugin : public QObject, private PluginInterface 

Это означает, что ваш базовый класс PluginInterface недоступен и dynamic_cast или qobject_cast потерпит неудачу.

Исправление легко:

class RawPlugin : public QObject, public PluginInterface 
+0

http://stackoverflow.com/questions/8993347/signal-slot-interaction-for-two-plugins-in-qt?rq=1 представляет альтернативный подход, хотел бы знать плюсы и минусы каждого. – KcFnMi

+1

Это просто другой способ сделать то же самое. Программисту следует выбрать дизайн, который является наиболее читаемым и простым. Риторический вопрос: Какой подход является самым простым для вас? –

 Смежные вопросы

  • Нет связанных вопросов^_^