【问题标题】:QObject::connect: Cannot connect (null)::mySignal() to (null)::mySlot()QObject::connect: 无法将 (null)::mySignal() 连接到 (null)::mySlot()
【发布时间】:2016-03-21 00:12:42
【问题描述】:

我在尝试连接插件之间的信号/插槽时错过了重点。考虑到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

插件接口.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();
}

主窗口.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&lt;QObject*&gt; 似乎返回 null。为什么?

【问题讨论】:

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


【解决方案1】:

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

在你的插件中你使用继承

class RawPlugin : public QObject, PluginInterface

相当于

class RawPlugin : public QObject, private PluginInterface

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

修复很简单:

class RawPlugin : public QObject, public PluginInterface

【讨论】:

  • stackoverflow.com/questions/8993347/… 提出了另一种方法,想知道每种方法的优缺点。
  • 这只是做同样事情的另一种方式。程序员应该选择最易读和最简单的设计。反问:哪种方法对您来说最简单?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-15
  • 1970-01-01
  • 2015-05-29
  • 2014-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多