0

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!

  • How are you compiling these sources into an executable? – user1593858 Jan 13 '19 at 21:39
  • Using Visual Studio, Qt-Addon and mingw I think –  Jan 13 '19 at 21:47
  • 1
    You should not define function body for the signal Sender::mySignal, in fact, with Q_SIGNAL defined, Qt moc system will generate an underlying function used to activate the signal. When you mixed mingw and visual studio, something was broken down the link of the important signal function and you did not get the right connection. – tunglt Jan 13 '19 at 22:43
  • 2
    Signals may not have a body. I can't even compile a signal having a function body. – Martin Hennings Jan 14 '19 at 10:00
  • By the way, if you have a debug build of Qt, you can actually step through the 'emit' call - and would realize that it's only calling your debug code, not the Qt signal machinery. – Martin Hennings Jan 14 '19 at 10:01
  • Thank you very much, it was indeed the function body of the signal. After reinstalling mingw I recieved an error, and deleted the function body. –  Jan 15 '19 at 16:57

1 Answers1

0

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?

user1593858
  • 649
  • 7
  • 12
  • Thank you so much for your time, your solution worked perfectly fine for me! –  Jan 15 '19 at 16:58