【问题标题】:Qt connect "no such slot" when slot definitely does exist当插槽确实存在时,Qt连接“没有这样的插槽”
【发布时间】:2012-05-26 06:10:09
【问题描述】:

Qt v4.8.0,VC2010编译器

我有一个基于QMainWindow 的类,我正在尝试向它发送涉及QUuid 的信号

但是,每次我运行它时都会出现错误:

Object::connect: No such slot MainWindow::on_comp_connected(QUuid) in ..\..\src\mainwindow.cpp:143
Object::connect:  (receiver name: 'MainWindow')

这让我如厕,因为插槽确实存在(它在 moc_ 中)

class MainWindow : public QMainWindow
{
Q_OBJECT

// SNIP private typedefs

public:
    MainWindow(QWidget *parent = 0, Qt::WFlags flags = 0);
    ~MainWindow();
// SNIP public methods

signals:
   void testSendQuuid(const QUuid &qcid);

public slots:
   void on_comp_connected(const QUuid &qcid);

private:
// SNIP private parts

QOpenAcnController *acnInt;  // This is where the signal comes from

};

MainWindow 构造函数的末尾(提到的第 143 行)我有:

connect(acnInt, SIGNAL(callback_comp_connected(QUuid)),
        this, SLOT(on_comp_connected(QUuid)));

鉴于插槽肯定在 moc_mainwindow.cpp 中(我检查过,它是插槽 #1),到底是什么阻止了连接的发生?

如果我尝试将testSendQuuid(QUuid) 信号连接到插槽,我不会收到这样的信号,也不会收到这样的插槽。

我一生都无法弄清楚为什么 Qt 否认存在一个 绝对存在的插槽!

【问题讨论】:

  • 您是否已经尝试过cleanRun qmakebuild 序列?有时 Qt 生成的 make 文件会混淆。
  • 是的,我尝试的第一件事!我有几次让 qmake 或 moc 感到困惑(通常是在将一个类提升为 QObject 后代时,而以前不是这样)。在这种情况下,它没有任何区别。
  • 那些私有类型定义是什么?

标签: qt signals-slots


【解决方案1】:

我通过在主窗口类中添加 Q_OBJECT 宏解决了问题。

【讨论】:

  • 谢谢,这也是我的问题
  • 谢谢!像魅力一样工作!
【解决方案2】:

检查moc_mainwindow.cpp 是否在您的Build Path 中。或者您正在使用其他一些 moc_window.cpp 文件。因为,例如:在 QtCreator 中,它将源构建到新的构建目录。如果您尝试在其他位置打开源代码,它也会使用旧的 moc_cpp 文件。

我想说的是,您检查的 moc 文件可能包含这些插槽定义,但编译器可能正在使用之前创建的其他 moc 文件。

【讨论】:

  • 就是这样 - 不知何故,一个额外的 moc_*.cpp 最终出现在构建输出文件夹而不是 moc 文件夹中,而 clean 并没有删除它。
  • 此清理步骤通常不会清理那些 moc 文件,例如:当您从另一个系统中导出项目并在您的系统中执行清理步骤时,就像这样。
  • 所以如果我的 vuild 目录中有 moc_maindwindow.cpp 文件,那是导致此错误的原因吗?或者如果 ti 不存在?你不是那么清楚。我有同样的问题,我的构建文件夹中有一个 moc_mainwindow.cpp。那么我应该删除它还是应该很好,因为它在那里?
  • 清理项目然后构建它。检查生成moc文件的路径,并检查它是否被清理操作删除。否则删除所有 moc 文件并构建。如果您仍然无法解决它,请将项目(仅源文件而不是构建二进制文件)复制到不同的路径并尝试构建源代码。仍然有问题,请查看您所做的修改。还要检查visual studio是否对bin out目录有写权限。
【解决方案3】:

我这样解决了问题

private slots:
    void on_comp_connected(const QUuid &qcid);

然后在构造函数中

connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(on_comp_connected(QUuid)));

【讨论】:

    【解决方案4】:

    你需要

    connect(acnInt, SIGNAL(callback_comp_connected(QUuid)),         this, SLOT(on_comp_connected(const QUuid&))); 
    

    按值传递不应匹配传递 const 引用。

    但我试过了,它确实如此。我在 Windows 上使用 Qt 4.7.4 创建了一个带有 QtCreator 2.4.1 的最小项目。我在主窗口中添加了一个标签,并修改了 MainWindow.cpp 如下

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        connect(
          this, SIGNAL(testSendQuuid(QUuid)),
          this, SLOT(on_comp_connected(QUuid))
        );
        QUuid x = QUuid::createUuid();
        emit testSendQuuid(x);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_comp_connected(const QUuid &qcid)
    {
        ui->label->setText(qcid.toString());
    }
    

    我在主窗口上得到一个 uuid。

    我还尝试将连接中的两个 QUuid 参数更改为 const Quuid& 并且也可以。

    所以你的问题必须与构建相关。

    【讨论】:

    • 嗯,会试试的。听起来当然有道理。奇怪的是 Qt Creator 会错误地自动完成。
    • 不是这个。它们“规范化”连接的签名,将 const 引用转换为值,因为两者是兼容的。
    • 我确定你可以连接它们,但你确定 moc 会匹配它们吗?
    • 您希望 moc 进行什么样的匹配?它不将信号与插槽匹配。它只是构建枚举方法所需的元对象信息。连接是在运行时建立的,并且 OP 使用的是QObject::connect,这对于那些小的签名差异是稳健的。
    • const T& 和 T 在信号和槽方面是等价的,并且永远不需要输入 const T&(由于标准化,在运行时甚至更慢)。
    猜你喜欢
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多