【问题标题】:C++ Qt signal and slot not firingC ++ Qt信号和插槽未触发
【发布时间】:2011-04-08 10:28:08
【问题描述】:

我的 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

代码看起来正确,没有编译器警告。只是运行时的这个输出。但看起来我正确连接了信号和插槽。

【问题讨论】:

    标签: c++ qt qt-signals


    【解决方案1】:

    当我开始使用 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 没有 bool 类型参数
    【解决方案2】:

    编辑:

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

    【讨论】:

    • 我已经给 Uli Schlachter 加分了,因为他确实为我指明了正确的方向。感谢大家的贡献!
    【解决方案3】:

    Q_OBJECT 添加到您的班级,如下所示:

    类 MainWidget : 公共 QWidget
    {
        Q_OBJECT
    

    您还必须运行 moc 来生成一些帮助代码。 qmake 会自动为您执行此操作,但如果您自己编译,则需要运行 moc。

    【讨论】:

    • 感谢您的快速回复。但是请你说得更具体一些,因为我对此很陌生。我已更改代码以在打开的花括号后立即添加 Q_OBJECT。结果还是一样。我正在使用 Qt Creator IDE。
    • 添加 Q_OBJECT 后会发生什么?你是如何编译你的代码的?
    • 我已更改代码以在打开的花括号后立即添加 Q_OBJECT。结果还是一样。我正在使用 Qt Creator IDE。
    • 从您的项目目录中删除所有 Makefile(Makefile、Makefile.Debug 和 Makefile.Release)并重新编译。现在 QMake 已执行,信号现在应该可以工作了。
    • 你不需要删除任何东西,添加Q_OBJECT宏后重新运行qmake即可。在 Qt Creator 中,它可以从构建菜单中完成。
    猜你喜欢
    • 1970-01-01
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 2015-07-18
    • 2013-09-27
    相关资源
    最近更新 更多