Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Signals and Slots within same Class



  • Hello,

    I want to run the Signal-Slot connection within same class.

    For example:

    mainWindow.h

    public:
        void  A(QString data);
    signals:
        void dataReceived(QString data);
    private slots:
        void B(QString data);
    private:
        Ui::MainWindow *ui;
    

    mainWindow.cpp

    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        QObject::connect(this , SIGNAL(dataReceived(QString)),this, SLOT(B(QString)));
    
       QString value="some_text";
       A(value);  // Can I use this to emit signal ??
    
    }
    
    
    void MainWindow::A(QString data)
    {
        emit  dataReceived(data);
    }
    
    void MainWindow::B(QString data)
    {
        ui->label->setText(data);
    }
    

    How to change call the function which emits the signal & connects to Slot within the same class??


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    There's no event loop running at that point of your code hence the slot is not called.

    Sorry for the wrong pointer, I was thinking about a different use case involving further propagation of the signal.

    From the constructor you should call the slot directly.

    As @VRonin suggested below, check that you are not missing the Q_OBJECT macro.



  • Thanks for the reply.

    Normally, Can we do this signal-slot within the same class?
    Can you provide me an example?


  • Lifetime Qt Champion

    Yes you can, but if you are only going to use that in your constructor then, there's no point.



  • No, I dont want to call it from constructor.
    Please, show me the other method


  • Lifetime Qt Champion

    What example are you expecting ? You can connect a signal to a slot within the same class.

    [edit: Removed wrong reference to event loop SGaist]


  • Lifetime Qt Champion

    @reddy9pp

    Hi
    Just to be sure its 100% clear
    You did it right - but since MainWindows is often used this way

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w; <<<< created here and tries to signal itself
        w.show();
    
        return a.exec(); <<< however, it needs to be in here for it to work
    }
    

    In this case, emitting the signal to itself in the constructor will not do anything.

    But emitting in other functions after the window is shown will work as its then inside a.exec();



  • @reddy9pp

    Ignoring the constructor thing, you don't even need function A to emit the signal. You can emit your custom signals everywhere you want (inside constructor makes no sense). So instead of calling A and passing the value to your public function first, you can just emit the signal and pass the QString as parameter.



  • @Pl45m4

    Could you provide an example code? I am bit confused



  • @reddy9pp

    Sure (it's not that complicated)

    public:
        // constructor
        // destructor
    
        void aRandomFnctn(); 
    
    signals:
        void dataReceived(QString data);
    
    private slots:
        void processData(QString data);
    
    private:
        Ui::MainWindow *ui;
    


    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        connect(this, SIGNAL( dataReceived(QString) ), this, SLOT( processData(QString) ) );
        
      // if you are using Qt5, you can use this syntax for signals and slots
     // connect( this, &MainWindow::dataReceived, this, &MainWindow::processData);
    
    }
    
    
    void MainWindow::aRandomFnctn();
    {
       // do stuff
      // [ ... ]
    
       QString value ="TEXT";
    
     /// stuff
     // even more stuff
     // [ ... ]
     // just emit / trigger you signal where and when you want to notify another class or instance inside same class
        emit dataReceived(value); // -> slot "processData" is called afterwards
        emit dataReceived("TEST"); // this is possible too
    
       // continue doing stuff
    
    }
    
    void MainWindow::processData(QString data)
    {
        // do something with your data here
    }
    


  • @SGaist said in Signals and Slots within same Class:

    There's no event loop running at that point of your code hence the slot is not called.

    ??? Qt::DirectConnection don't care about no loop afaik. OP original code looks good to me.

    Make sure you have Q_OBJECT in your mainWindow.h


  • Lifetime Qt Champion

    @VRonin said in Signals and Slots within same Class:

    @SGaist said in Signals and Slots within same Class:

    There's no event loop running at that point of your code hence the slot is not called.

    ??? Qt::DirectConnection don't care about no loop afaik. OP original code looks good to me.

    Make sure you have Q_OBJECT in your mainWindow.h

    You're completely right ! I have mixed that with another consequence of calling signals directly in a constructor especially when it should propagate further to other objects in the code base.

    Though it should be working, I still do not recommend doing that as it may have unexpected consequence.

    Fixed my original answer.


Log in to reply