C++ Qt signal and slot not firing

14,481

Solution 1

Add Q_OBJECT to your class, like this:

class MainWidget : public QWidget
{
    Q_OBJECT

You also have to run moc to generate some helper code. qmake does that automatically for your, but if you compile this yourself, you need to run moc.

Solution 2

When I started with Qt, I had this problem a lot. As I see it your slots are defined wrong. If you look at the signature for the signal (Qt Clicked Signal Docs), you will see that the argument list is (bool clicked = false).

The way Qt's signal & slots connect work at run time, is that it will only connect the signal and slot if they have the exact same signatures. If they don't match exactly, no connection.

so in MainWidget.h

 public slots:
        void bAdvice_clicked(bool);

In MainWidget.cpp

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

Things will start working for you.

Solution 3

Edited:

Compiled your code and all the slots were correctly called. It was just the Q_OBJECT macro that was missing.

Share:
14,481
c0d3L0g1c
Author by

c0d3L0g1c

Updated on June 06, 2022

Comments

  • c0d3L0g1c
    c0d3L0g1c almost 2 years

    I am having difficulty in my Qt program with connecting button signals to my slots. My code is:

    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();
    }
    

    The program outputs the following:

    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
    

    The code seems right, no compiler warnings. Just this output at runtime. But it looks like I hooked the signals and slots up correctly.

  • c0d3L0g1c
    c0d3L0g1c over 13 years
    Thanks for the quick response. But can you please be more specific as i am very new to this. I have changed my code to add Q_OBJECT immediately after the open curly braces. Still the same result. I am using Qt Creator IDE.
  • Uli Schlachter
    Uli Schlachter over 13 years
    What happens after you add Q_OBJECT? How are you compiling your code?
  • c0d3L0g1c
    c0d3L0g1c over 13 years
    I have changed my code to add Q_OBJECT immediately after the open curly braces. Still the same result. I am using Qt Creator IDE.
  • Admin
    Admin over 13 years
    Delete all the Makefiles (Makefile, Makefile.Debug and Makefile.Release) from your project directory and recompile. Now the QMake is executed and signals should now be working.
  • c0d3L0g1c
    c0d3L0g1c over 13 years
    I cleaned the build and rebuilt with Q_OBJECT. Now i get build issues saying undefined reference to `vtable for MainWidget'. I hope this sheds more light on the topic. It does however seem related to MOC. How do i get Qt Creator to auomatically handle this? Please help!
  • teukkam
    teukkam over 13 years
    You don't need to delete anything, just rerun qmake after adding the Q_OBJECT macro has been added. In Qt Creator it can be done from the build menu.
  • teukkam
    teukkam over 13 years
    See this question I asked: stackoverflow.com/questions/3607262/… - the solution is the same: rerun qmake
  • c0d3L0g1c
    c0d3L0g1c over 13 years
    Thanks to Roku and Teukkam, your suggestions worked. How do i award points? :-)
  • c0d3L0g1c
    c0d3L0g1c over 13 years
    I have awarded points to Uli Schlachter, as he did point me in the right direction. Thanks to everyone for contributing!
  • Tracy
    Tracy about 13 years
    but i get that works for QPushButton without the bool type parameter