2016-03-21 9 views
0

Ich vermisse den Punkt beim Versuch, Signal/Slots zwischen Plugins zu verbinden. Unter Berücksichtigung this question habe ich folgendes gemacht.QObject :: connect: Kann nicht verbinden (null) :: mySignal() zu (null) :: mySlot()

ich den vollständigen Quellcode von 3 Qt Projekten werden präsentiert:

  • pluginTCP: Ein Plugin
  • pluginRaw: Ein weiteres Plugin
  • Plattform: Die Plattform die Plugins

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; 
} 

Es scheint, die dynamic_cast<QObject*> null zurückkehrt. Warum?

+0

warum Sie trotzdem werfen? – AngryDuck

+0

Sie haben auch waaaay viel Code gegeben, der nichts mit Ihrem Problem zu tun hat – AngryDuck

+0

Es wurde gesagt, um http://stackoverflow.com/questions/36117031/qt-piping-data-between-plugins, von @Felix zu werfen . – KcFnMi

Antwort

1

Ich bin zu faul, um ein so langes Projekt zu kompilieren, aber ich sehe einen Grund, warum Ihr Code nicht funktioniert und warum Sie einen Nullzeiger aus dem Cast bekommen.

In Plugins verwenden Sie die Vererbung

class RawPlugin : public QObject, PluginInterface 

, die

class RawPlugin : public QObject, private PluginInterface 

scheitern Dies bedeutet, dass Ihre Basisklasse wird PluginInterface ist unzugänglich und dynamic_cast oder qobject_cast entspricht.

Die Lösung ist einfach:

class RawPlugin : public QObject, public PluginInterface 
+0

http://stackoverflow.com/questions/8993347/signal-slot-interaction-for-two-plugins-in-qt?rq=1 stellt einen alternativen Ansatz dar, würde gerne die Vor- und Nachteile von jedem kennen. – KcFnMi

+1

Es ist nur eine andere Möglichkeit, das Gleiche zu tun. Ein Programmierer sollte ein Design auswählen, das am besten lesbar und einfach ist. Rhetorische Frage: Welcher Ansatz ist der einfachste für dich? –

Verwandte Themen