Do not see the data which is transferred between forms when using Signal and Slot



  • Hi all,

    I am a newbie in C++ QT. Currently I am writing a small applicatiion which using Signal and Slot to transfer data between 2 forms. I have read "Signals & Slots document":http://qt-project.org/doc/qt-4.8/signalsandslots.html to transfer data but I can not receive data .

    I have 2 following forms (is created by QT Creator 2.7.2):

    Form1.h
    @
    class Form1: public QDialog
    {

    ...........

    private slots:
    void on_btnOK_clicked();

    signals:
    void SendId(int id);

    };
    @

    Form1.cpp
    @
    #include "form2.h"

    void Form1::on_btnOK_clicked()
    {
    emit SendId(2); //ID = 2

    Form2 form2;
    form2.setModal(true);
    form2.exec();
    }
    @

    Form2.h
    @
    class Form2 : public QDialog
    {

    ...........

    public slots:
    void ReceiveId(int id);
    };
    @

    Form2.cpp
    @
    #include "form1.h"

    Form2::Form2(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Form2)
    {
    ui->setupUi(this);

    // Instantiating the forms
    Form1 form1;
    
    // Connecting the signal we created in the Form1
    // with the slot created in the Form2
    QObject::connect(&form1, SIGNAL(SendId(int)),
                     this, SLOT(ReceiveId(int)));
    

    }

    void Form2::ReceiveId(int id)
    {
    qDebug() << "Received id";
    }
    @

    When running program, I don't receive the message "Received id". I think the ReceiveId(int id) function not working. Could you give me some solutions to solve this issue?

    Thanks,
    Lee.



  • Hi,

    it does not work because in the constructor of Form2 you connect to a new instance of Form1 and not to the one, which emits the signal.

    You could for example connect the signal in Form1::on_btnOK_clicked().



  • If the code you given here is the code you used, yes, it doesn't work.

    @
    Form2::Form2(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Form2)
    {
    ui->setupUi(this);

    // Instantiating the forms
    Form1 form1;
    
    // Connecting the signal we created in the Form1
    // with the slot created in the Form2
    QObject::connect(&form1, SIGNAL(SendId(int)),
                     this, SLOT(ReceiveId(int)));
    

    }
    @

    You create one object of Form1, connect the signal of it to current object's slot. Then the Form1 object get destroyed without any signal get emitted.



  • Just create the Form1 object on the heap i.e.:
    @
    Form1* pForm1 = new Form1(this);
    @
    and give Form2 a member variable holding the Form1 pointer:
    @
    Form2.h

    class Form2 : public QDialog
    {

    ...........

    public slots:
    void ReceiveId(int id);
    private:
    Form1* m_pForm1;
    };

    Form2.cpp

    Form2::Form2(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Form2)

    {
    ui->setupUi(this);
    m_pForm1 = new Form1(this);

    // Connecting the signal we created in the Form1
    // with the slot created in the Form2
    QObject::connect(m_pForm1, SIGNAL(SendId(int)),
                     this, SLOT(ReceiveId(int)));
    

    }
    @



  • Thanks very much! I understood my issue.

    [quote author="1+1=2" date="1373954840"]If the code you given here is the code you used, yes, it doesn't work.

    @
    Form2::Form2(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Form2)
    {
    ui->setupUi(this);

    // Instantiating the forms
    Form1 form1;
    
    // Connecting the signal we created in the Form1
    // with the slot created in the Form2
    QObject::connect(&form1, SIGNAL(SendId(int)),
                     this, SLOT(ReceiveId(int)));
    

    }
    @

    You create one object of Form1, connect the signal of it to current object's slot. Then the Form1 object get destroyed without any signal get emitted.[/quote]

    [quote author="chris17" date="1373954664"]Hi,

    it does not work because in the constructor of Form2 you connect to a new instance of Form1 and not to the one, which emits the signal.

    You could for example connect the signal in Form1::on_btnOK_clicked().[/quote]



  • Thanks for your response! As I said, I am newbie so I don't understand what the heap is. Could you tell me where I have to insert the code Form1 pForm1 = new Form1(this); * is please ?

    [quote author="KA51O" date="1373956496"]Just create the Form1 object on the heap i.e.:
    @
    Form1* pForm1 = new Form1(this);
    @
    and give Form2 a member variable holding the Form1 pointer:
    @
    Form2.h

    class Form2 : public QDialog
    {

    ...........

    public slots:
    void ReceiveId(int id);
    private:
    Form1* m_pForm1;
    };

    Form2.cpp

    Form2::Form2(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Form2)

    {
    ui->setupUi(this);
    m_pForm1 = new Form1(this);

    // Connecting the signal we created in the Form1
    // with the slot created in the Form2
    QObject::connect(m_pForm1, SIGNAL(SendId(int)),
                     this, SLOT(ReceiveId(int)));
    

    }
    @[/quote]



  • Everything you create with a new is allocated on the heap. This means it will stay alive after going out of scope.
    Example:
    @
    void SomeClass::someFunction()
    {
    Class1 class1; //allocated on the stack
    Class2* class2 = new Class2(); //allocated on the heap
    }
    // at this point (after the function is done with its work)
    // the class1 object no longer exists. the class2 object will still exist.
    // BUT this comes at a trade off! You are now responsible for deleting
    // the object that was allocated on the heap by calling delete later.
    @

    [quote]
    Could you tell me where I have to insert the code Form1 pForm1 = new Form1(this); * is please ?
    [/quote]
    I already inserted that in your code. Have a look at the second code snippet.
    @
    Form2.h
    ————————————————
    class Form2 : public QDialog
    {

    ………..

    public slots: void ReceiveId(int id);
    private: Form1* m_pForm1; // CHANGE IS HERE
    };

    Form2.cpp
    ——————————————————————————
    Form2::Form2(QWidget *parent) : QDialog(parent), ui(new Ui::Form2)

    {
    ui->setupUi(this);
    m_pForm1 = new Form1(this); // CHANGE IS HERE
    // Connecting the signal we created in the Form1
    // with the slot created in the Form2
    QObject::connect(m_pForm1, SIGNAL(SendId(int)),
    this, SLOT(ReceiveId(int)));
    } @

    Because of the parent child relations in Qt you don't have to call delete on the m_pForm1 object.



  • You are a very enthusiasm person. Thank you very much!

    [quote author="KA51O" date="1373976592"]Everything you create with a new is allocated on the heap. This means it will stay alive after going out of scope.
    Example:
    @
    void SomeClass::someFunction()
    {
    Class1 class1; //allocated on the stack
    Class2* class2 = new Class2(); //allocated on the heap
    }
    // at this point (after the function is done with its work)
    // the class1 object no longer exists. the class2 object will still exist.
    // BUT this comes at a trade off! You are now responsible for deleting
    // the object that was allocated on the heap by calling delete later.
    @

    [quote]
    Could you tell me where I have to insert the code Form1 pForm1 = new Form1(this); * is please ?
    [/quote]
    I already inserted that in your code. Have a look at the second code snippet.
    @
    Form2.h
    ————————————————
    class Form2 : public QDialog
    {

    ………..

    public slots: void ReceiveId(int id);
    private: Form1* m_pForm1; // CHANGE IS HERE
    };

    Form2.cpp
    ——————————————————————————
    Form2::Form2(QWidget *parent) : QDialog(parent), ui(new Ui::Form2)

    {
    ui->setupUi(this);
    m_pForm1 = new Form1(this); // CHANGE IS HERE
    // Connecting the signal we created in the Form1
    // with the slot created in the Form2
    QObject::connect(m_pForm1, SIGNAL(SendId(int)),
    this, SLOT(ReceiveId(int)));
    } @

    Because of the parent child relations in Qt you don't have to call delete on the m_pForm1 object.[/quote]



  • Hi, there is a HUGE and BIG difference between the stack and the heap. This comes from "older" and much "smaller" processors without OS running on it. The stack used to be the 'small' and fast to access memory near the core of the CPU. The heap used to be a 'larger' memory usually connected via parallel bus or seriel bus, so much slower in accesstimes, but a lot larger then the stack. Therefor there is a difference in allocation made in C and C++. When a program is created it 'gets' a piece of memory from the OS, this is the stack. With the new keyword you request new memory on the OS, this is the heap. (oke, this is just a quick and not complete explanation, but think it goes a bit to far to go into details).
    Just keep in mind that your stack will not grown when you want more local variables etc. The heap is as big as the OS will give you run time!



  • Wow, your explanation is very clear. I understand more about the heap and the stack in C/C++ program. Thanks bro!

    [quote author="Jeroentje@home" date="1374042608"]Hi, there is a HUGE and BIG difference between the stack and the heap. This comes from "older" and much "smaller" processors without OS running on it. The stack used to be the 'small' and fast to access memory near the core of the CPU. The heap used to be a 'larger' memory usually connected via parallel bus or seriel bus, so much slower in accesstimes, but a lot larger then the stack. Therefor there is a difference in allocation made in C and C++. When a program is created it 'gets' a piece of memory from the OS, this is the stack. With the new keyword you request new memory on the OS, this is the heap. (oke, this is just a quick and not complete explanation, but think it goes a bit to far to go into details).
    Just keep in mind that your stack will not grown when you want more local variables etc. The heap is as big as the OS will give you run time![/quote]


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.