将小部件信号与父小部件插槽连接时没有这样的插槽

No such slot when connecting widget signal with parent widget slot

我有以下 classes:

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QStringList pluginsToStart, QWidget *parent = 0);
    ~MainWindow();

// some other stuff

public slots:
    void on_timeDataChanged(logging::TimeValueVector<bool>& aData);
    void on_importStarted();
}

class DataImporterWidget : public PluginWidget
{
    Q_OBJECT

public:
    explicit DataImporterWidget(QWidget *parent = 0);
    ~DataImporterWidget();

    void initConnections(QMap<QString, PluginWidget*> pluginWidgetMap);

在方法 initConnections 中,我希望小部件像这样初始化信号槽连接:

void DataImporterWidget::initConnections(QMap<QString, PluginWidget*> pluginWidgetMap)
{
    for(Importer* importer : this->getImporterMap().values())
    {
        connect(importer, SIGNAL(signal_timeDataChanged(logging::TimeValueVector<bool>&)),
            parentWidget(), SLOT(on_timeDataChanged(logging::TimeValueVector<bool>&)));
    }

    connect(this, SIGNAL(signal_importStarted()), parentWidget(), SLOT(on_importStarted()));
}

Importer 是一个 QGroupBox 和一个基础 class 派生子 classes 指定具体的数据导入器类型。 它是这样工作的:如果我按下一个按钮,就会创建一个 DataImporterWidget 并将其作为 QMdiSubWindow 添加到 QMdiArea。创建 DataImporterWidget 时,我调用了 initConnections() 方法来设置信号槽连接。

现在,当我 运行 程序时,我收到以下消息:

QObject::connect: No such slot 
QMdiSubWindow::on_timeDataChanged(logging::TimeValueVector<bool>&) in src/dataimporter/DataImporterWidget.cpp:81
QObject::connect: No such slot QMdiSubWindow::on_importStarted() in src/dataimporter/DataImporterWidget.cpp:85
QObject::connect:  (sender name:   'DataImporterWidget')

我不明白为什么我得到它,因为插槽在那里。即使我将 parentWidget 投射到 MainWindow,我也会得到同样的错误。

PluginWidget 只是一个 class 派生自 QWidget 的基础,它包含我使用的插件的一些通用功能。 我将 Q_OBJECT 放在每个基础上并导出 class 但仍然出现此错误。但是,如果我在主窗口中设置连接,它工作得很好,但我想知道为什么上面的解决方案不起作用。

不要从子对象创建连接,而是在创建子对象后从父对象代码创建它。 这样你就不需要转换任何类型了。

您没有显示大量重要代码(例如创建 DataImporterWidget、将 MainWindow 设置为其父级、您调用 initConnections 的地方...)。然而,你说

If I use the new signal slot syntax, my program crashes with a segmentation fault...

如果它崩溃了,那么您必须找到原因。使用旧的信号槽连接语法并不能治愈疾病,它只会延迟它的表现。根据 this,您得到段错误的原因可能是 parentWidget() == nullptrparent 尚未初始化。

我的建议是,检查你的代码,并在调用 initConnections() 之前创建并指定用户 DataImporterWidget 的父级。

我找到问题了。原因是,MainWidget class 拥有一个 QMdiArea,我在其中添加了我的 PluginWidgets。所以,当我创建 PluginWidget 时,我将 MainWidget 设置为它的父级,但是一旦我将它添加到 QMdiArea,它也成为 QMdiSubWindow 的子级。 parentWidget 永远不会为空,但它是错误的 ...