C++ Qt信号和槽未触发

10

我在我的Qt程序中连接按钮信号到我的槽函数时遇到了困难。我的代码如下:

Main.cpp

#include <QtGui/QApplication>
#include "MainWidget.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    MainWidget mainWidget;
    mainWidget.show();

    return app.exec();
}

MainWidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>

class MainWidget : public QWidget
{
public:
    MainWidget();

public slots:
    void bAdvice_clicked();
    void bWeather_clicked();
    void bNextMeeting_clicked();
    void bQuit_clicked();
};

#endif // MAINWIDGET_H

MainWidget.cpp

#include "MainWidget.h"
#include <QMessageBox>
#include <QPushButton>
#include <QTextEdit>
#include <QVBoxLayout>

MainWidget::MainWidget()
{
    QLayout *layout = new QVBoxLayout();
    this->setLayout(layout);

    QTextEdit *message = new QTextEdit();
    layout->addWidget(message);

    QPushButton *bAdvice = new QPushButton("Advice");
    connect(bAdvice, SIGNAL(clicked()), this, SLOT(bAdvice_clicked()));
    layout->addWidget(bAdvice);

    QPushButton *bWeather = new QPushButton("Weather");
    connect(bWeather, SIGNAL(clicked()), this, SLOT(bWeather_clicked()));
    layout->addWidget(bWeather);

    QPushButton *bNextMeeting = new QPushButton("Next Meeting");
    connect(bNextMeeting, SIGNAL(clicked()), this, SLOT(bNextMeeting_clicked()));
    layout->addWidget(bNextMeeting);

    QPushButton *bQuit = new QPushButton("Quit");
    connect(bQuit, SIGNAL(clicked()), this, SLOT(bQuit_clicked()));
    layout->addWidget(bQuit);
}

void MainWidget::bAdvice_clicked()
{
}

void MainWidget::bWeather_clicked()
{
}

void MainWidget::bNextMeeting_clicked()
{
    QMessageBox::information(this, "Next Meeting", "Today", QMessageBox::Ok);
}

void MainWidget::bQuit_clicked()
{
    this->close();
}

程序输出以下结果:

Starting C:\Users\Sameer\Documents\PartAQuestion2\debug\PartAQuestion2.exe...
Object::connect: No such slot QWidget::bAdvice_clicked() in MainWidget.cpp:16
Object::connect: No such slot QWidget::bWeather_clicked() in MainWidget.cpp:20
Object::connect: No such slot QWidget::bNextMeeting_clicked() in MainWidget.cpp:24
Object::connect: No such slot QWidget::bQuit_clicked() in MainWidget.cpp:28

C:\Users\Sameer\Documents\PartAQuestion2\debug\PartAQuestion2.exe exited with code 0

代码看起来没问题,没有编译器警告。但是运行时出现了这个输出。不过我看起来已经正确地连接了这些信号和槽。

3个回答

16

Q_OBJECT添加到你的类中,就像这样:

class MainWidget : public QWidget
{
    Q_OBJECT

你还需要运行moc工具生成一些辅助代码。如果你使用qmake编译,它会自动运行moc。但是如果你自己编译,需要手动运行moc。


我已经修改了我的代码,在左花括号后立即添加了Q_OBJECT。但结果仍然相同。我正在使用Qt Creator IDE。 - c0d3L0g1c
1
从您的项目目录中删除所有Makefiles(Makefile,Makefile.Debug和Makefile.Release),然后重新编译。现在执行QMake,信号应该可以正常工作了。 - user362638
1
你不需要删除任何东西,只需在添加了Q_OBJECT宏之后重新运行qmake即可。在Qt Creator中,可以从构建菜单中完成此操作。 - teukkam
请看我提出的这个问题:https://dev59.com/fFDTa4cB1Zd3GeqPGyYb - 解决方案也是一样的:重新运行qmake。 - teukkam
多亏了 Roku 和 Teukkam,你们的建议非常有用。我如何授予积分? :-) - c0d3L0g1c
显示剩余3条评论

3
当我开始使用Qt时,我经常遇到这个问题。我认为你的槽函数定义有误。如果你查看信号的签名(Qt Clicked Signal Docs),你会发现参数列表是(bool clicked = false)
在运行时,Qt的信号和槽连接方式要求它们具有完全相同的签名才能连接成功。如果它们的签名不完全匹配,则不会连接成功。
所以在MainWidget.h中:
 public slots:
        void bAdvice_clicked(bool);

在MainWidget.cpp中

  connect(bAdvice, SIGNAL(clicked(bool)), this, SLOT(bAdvice_clicked(bool)));

您的事情即将开始进展。


但我发现这适用于没有布尔类型参数的QPushButton。 - Tracy

2

编辑:

编译了你的代码,所有插槽都被正确调用了。问题只是缺少 Q_OBJECT 宏。


我已向Uli Schlachter授予了点数,因为他指引了我正确的方向。感谢每个人的贡献! - c0d3L0g1c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接