Search code examples
c++qtsignalsslots

Qt5: Though connected, Signal emmited but Slot not being called


So I have a Qt class MyQtClass, and a QOject inherited class Sender. I want to access the Ui from the Senderclass (Which by the way only consists static members), so I set up the static Sender& instance(), static void emitSignal()functions and the QSignal Q_SIGNAL void mySignal()in the Sender class (See the code below). In the Qt-class-header MyQtClass.h I've set up the QSlot Q_SLOT void mySlot(). I connect those two slots in the main.cpp
(const bool connected = QObject::connect(&Sender::instance(), &Sender::mySignal, &w, &MyQtClass::mySlot);)

Via qDebug();I found out that the connect is successful, and once I invoke the method emitSignal()the Signal is being emitted. The Slot though is never being called.

I gues that my mistake is in the main at the connection.

Code:

Sender.h:

#pragma once
#include <QtWidgets/QMainWindow>
#include <qdebug.h>

class Sender : public QObject
{
    Q_OBJECT
    using QObject::QObject;
public:

    /*----------------------------*/
    /*---Lots of static Members---*/
    /*----------------------------*/


    static Sender& instance(){
        static Sender m_instance;
        return m_instance;
    }

    static void emitSignal() {
        emit instance().mySignal();
    }

    Q_SIGNAL void mySignal() {
        qDebug() << "Signal emitted!";
    }
};

MyQtClass.h

#pragma once
#include <qdebug.h>
#include <QtWidgets/QMainWindow>
#include "ui_MyQtClass.h"

class MyQtClass : public QMainWindow
{
    Q_OBJECT

public:
    MyQtClass(QWidget *parent = Q_NULLPTR);

    Q_SLOT void mySlot() {
        qDebug() << "Slot invoked";
    }

private:
    Ui::MyQtClassClass ui;
};

MyQtClass.cpp

#include "MyQtClass.h"
#include "Sender.h";
#include <qdebug.h>

MyQtClass::MyQtClass(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    qDebug() << "Ui has been setup!";

}

main.cpp

#include "MyQtClass.h"
#include "Sender.h"
#include <qdebug.h>
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyQtClass w;
    w.show();
    const bool connected = QObject::connect(&Sender::instance(), &Sender::mySignal, &w, &MyQtClass::mySlot);
    qDebug() << "Connection established: " << connected;
    Sender::emitSignal();
    return a.exec();
}

Thank you very much for your time!


Solution

  • I would check your build system. You should not be able to compile the Q_SIGNAL with a function body without getting a redefinition error. If you can build it you are likely not involving any of the Qt machinery that you want to use. I do not have any experience with your Visual Studio/mingw environment but I was able to get the following to build on an Linux platform.

    main.cpp

    #include <QDebug>
    #include <QtWidgets/QApplication>
    #include <QtWidgets/QMainWindow> 
    #include "Sender.h"                                                          
    #include "MyQtClass.h"                                                       
    //#include "ui_MyQtClass.h"                                                  
    
    MyQtClass::MyQtClass(QWidget *parent)                                        
        : QMainWindow(parent)                                                    
    {                                                                            
        qDebug() << "Ui has been setup!";                                        
    
    }                                                                            
    
    int main(int argc, char *argv[])                                             
    {                                                                            
        QApplication a(argc, argv);                                              
        MyQtClass w;                                                             
        w.show();                                                                
        const bool connected = QObject::connect(&Sender::instance(), &Sender::mySignal, &w, &MyQtClass::mySlot);
        qDebug() << "Connection established: " << connected;                     
        Sender::emitSignal();
        return a.exec();
    } 
    

    Sender.h

    #pragma once
    #include <QtWidgets/QMainWindow>
    class Sender : public QObject
    {
        Q_OBJECT
        using QObject::QObject;                                                  
    public:                                                                      
    
        /*----------------------------*/                                         
        /*---Lots of static Members---*/                                         
        /*----------------------------*/
    
    
        static Sender& instance(){                                               
            static Sender m_instance;                                            
            return m_instance;                                                   
        }
    
        static void emitSignal() {                                               
            emit instance().mySignal();
        }
    
        Q_SIGNAL void mySignal();
    }; 
    

    MyQtClass.h

    #pragma once
    #include <QtWidgets/QMainWindow>
    #include <QDebug>
    
    class MyQtClass : public QMainWindow
    {   
        Q_OBJECT                                                                 
    
    public:
        MyQtClass(QWidget *parent = Q_NULLPTR);                                  
    
        Q_SLOT void mySlot() {
            qDebug() << "Slot invoked";                                          
        }   
    
    private:
        //Ui::MyQtClassClass ui;
    };
    

    I then built it manually invoking the Meta-Object Compiler

    moc Sender.h > moc_Sender.cpp
    moc MyQtClass.h > moc_MyQtClass.cpp
    g++  main.cpp moc_Sender.cpp moc_MyQtClass.cpp -I /usr/include/x86_64-linux-gnu/qt5/QtCore/ -I /usr/include/x86_64-linux-gnu/qt5 -fPIC -std=c++11 -I /usr/include/x86_64-linux-gnu/qt5/QtWidgets/ -lQt5Core -lQt5Widgets
    

    which produced the expected output

    user@mintvm ~ $ ./a.out 
    Ui has been setup!
    Connection established:  true
    Slot invoked
    

    Have you tried to use the qmake build system so that you do not need to worry about all of the details related to the compilation of the meta object system?