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

QObject::connect: Cannot connect (null)::mySignal() to (null)::mySlot()

本文关键字:null mySlot mySignal 连接 connect QObject      更新时间:2023-10-16

我在尝试连接插件之间的信号/插槽时错过了重点。考虑到这个问题,我提出了以下意见。

我将展示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

插件接口.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

原始插件.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;
};

原始插件.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

主.cpp

#include <QApplication>
#include "mainwindow.h"
int main(int argv, char *args[])
{
    QApplication app(argv, args);
    MainWindow window;
    window.show();
    return app.exec();
}

主窗口.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

主窗口.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。为什么?

我懒得编译这么长的项目,但我看到了你的代码不起作用的一个原因,以及为什么你从强制转换中获得一个空指针。

在您的插件中使用继承

class RawPlugin : public QObject, PluginInterface

相当于

class RawPlugin : public QObject, private PluginInterface

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

修复很简单:

class RawPlugin : public QObject, public PluginInterface