Results 1 to 10 of 10

Thread: Signal/slot between widgets

  1. #1
    Join Date
    Mar 2016
    Posts
    11
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Signal/slot between widgets

    Hello everybody,
    I have just started using Qt, and immediately I found the first difficulties in understanding the use of signal / slot.
    The problem is simple: I have a window (QWidget) with a QlineEdit and a button: I would like that, after typing a text in the Qline and pressing the button, another window (QWidget) would open with a QlineEdit field, filled with the text previously entered.
    I can do the reverse (from first page open the second page, and from here -pressing a button - to fill the parent window), but it seems that in my code there is no link between the signal and the generated window slot ... I found this topic: http://www.qtcentre.org/threads/2398...ows?highlight=
    but I can't apply the suggestions.

    Page1.h:
    Qt Code:
    1. #ifndef PAGE1_H
    2. #define PAGE1_H
    3.  
    4. #include <QWidget>
    5.  
    6. namespace Ui {
    7. class Page1;
    8. }
    9.  
    10. class Page1 : public QWidget
    11. {
    12. Q_OBJECT
    13.  
    14. public:
    15. explicit Page1(QWidget *parent = 0);
    16. ~Page1();
    17. signals:
    18. void transfer(QString);
    19.  
    20. private:
    21. Ui::Page1 *ui;
    22.  
    23. private slots:
    24. void on_pushButton_clicked();
    25.  
    26. };
    27.  
    28. #endif // PAGE1_H
    To copy to clipboard, switch view to plain text mode 

    Page1.cpp:
    Qt Code:
    1. #include "page1.h"
    2. #include "ui_page1.h"
    3. #include "page2.h"
    4. Page1::Page1(QWidget *parent) :
    5. QWidget(parent),
    6. ui(new Ui::Page1)
    7. {
    8. ui->setupUi(this);
    9. }
    10.  
    11. Page1::~Page1()
    12. {
    13. delete ui;
    14. }
    15.  
    16. void Page1::on_pushButton_clicked()
    17. {
    18. Page2 *form = new Page2();
    19. QString testo;
    20. testo=ui->to_pass->text();
    21. emit(transfer(testo));
    22. connect(this, SIGNAL(trasfer(QString)), form, SLOT(UpdateField(QString)));
    23. form->show();
    24. }
    To copy to clipboard, switch view to plain text mode 

    Page2.h:
    Qt Code:
    1. #ifndef PAGE2_H
    2. #define PAGE2_H
    3.  
    4. #include <QWidget>
    5.  
    6. namespace Ui {
    7. class Page2;
    8. }
    9.  
    10. class Page2 : public QWidget
    11. {
    12. Q_OBJECT
    13.  
    14. public:
    15. explicit Page2(QWidget *parent = 0);
    16. ~Page2();
    17.  
    18. private slots:
    19. void UpdateField(QString text);
    20.  
    21. private:
    22. Ui::Page2 *ui;
    23. };
    24.  
    25. #endif // PAGE2_H
    To copy to clipboard, switch view to plain text mode 

    Page2.cpp:

    Qt Code:
    1. #include "page2.h"
    2. #include "ui_page2.h"
    3.  
    4. Page2::Page2(QWidget *parent) :
    5. QWidget(parent),
    6. ui(new Ui::Page2)
    7. {
    8. ui->setupUi(this);
    9. }
    10.  
    11. Page2::~Page2()
    12. {
    13. delete ui;
    14. }
    15.  
    16. void Page2::UpdateField(QString text)
    17. {
    18. ui->receive->clear();
    19. ui->receive->setText(text);
    20. }
    To copy to clipboard, switch view to plain text mode 

    Thanks for any suggestion!

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,053
    Thanks
    233
    Thanked 649 Times in 639 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Signal/slot between widgets

    emit(transfer(testo));
    connect(this, SIGNAL(trasfer(QString)), form, SLOT(UpdateField(QString)));
    This is backwards. If you emit the signal before you connect the other window's slot to it, how will the other window receive it? The signal doesn't hang around, asking "Hey, anybody listening? Hello? Hello? Anybody?" until a slot eventually gets connected. Instead, it says, "Hey, anybody listening? No? Then I'm out of here."

    Your code has a serious memory leak. Each time the button is clicked, you create a new Page2 instance, completely unrelated to and independent of any others created during previous clicks. Even if you eventually hide them, they are still around, lurking invisibly in the background.

    A better solution is to create a Page2 instance in the Page1 constructor (as a child of the Page1 instance: page2 = new Page2( this )) and store the pointer as a member variable of Page1 Page2 * page2). When you create it you also make the connection between your signal and the Page2 slot. Once. In the Page1 constructor.

    In your button click slot, you can simply call page2->show() and then emit your signal. Or vice-versa. The Page2 widget instance will receive the signal whether it is visible or not. Because you create the Page2 widget with the Page1 instance as its parent, it will be deleted automatically when the Page1 widget is deleted.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Mar 2016
    Posts
    11
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Signal/slot between widgets

    Thank you very much for your explanation! Now it's clear the way to work. By now, I have this problem: when the child page2=new Page2 (this) is created, it superimposes itself to the Page1, and, as soon as I push the button, I obtain a "mixed" window with Page1 and Page2 widgets together. I can't hide the Page1, because so I remove the whole window... perhaps I have to use different solution than Qwidget-with-Qwidget? Thanks a lot!

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,053
    Thanks
    233
    Thanked 649 Times in 639 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Signal/slot between widgets

    I obtain a "mixed" window with Page1 and Page2 widgets together.
    Ah, yes, that's probably right. If you are not using a layout on Page1, then it will merge Page2 into Page1 when it is shown. OK, when you create page2, do not make it a child of page1 (this). In that case, you need to make sure you delete it in the Page1 destructor, just like you delete the ui pointer.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Mar 2016
    Posts
    11
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re Signal/slot between widgets

    SOLVED...just page2=new Page2 ();
    If someother newbe as me is interested, I resend the code:

    Pag1.h
    Qt Code:
    1. #ifndef PAGE1_H
    2. #define PAGE1_H
    3.  
    4. #include <QWidget>
    5. #include "page2.h"
    6.  
    7. namespace Ui {
    8. class Page1;
    9. }
    10.  
    11. class Page1 : public QWidget
    12. {
    13. Q_OBJECT
    14.  
    15. public:
    16. explicit Page1(QWidget *parent = 0);
    17. ~Page1();
    18.  
    19. signals:
    20. void transfer(QString);
    21.  
    22. private:
    23. Ui::Page1 *ui;
    24. Page2* page2;
    25.  
    26. private slots:
    27. void on_pushButton_clicked();
    28.  
    29. };
    30.  
    31. #endif // PAGE1_H
    To copy to clipboard, switch view to plain text mode 

    Page1.cpp

    Qt Code:
    1. #include "page1.h"
    2. #include "ui_page1.h"
    3. #include "page2.h"
    4. #include <qdebug.h>
    5.  
    6. Page1::Page1(QWidget *parent) :
    7. QWidget(parent),
    8. ui(new Ui::Page1)
    9. {
    10. ui->setupUi(this);
    11. page2=new Page2;
    12. connect(this, SIGNAL(transfer(QString)), page2, SLOT(UpdateField(QString)));
    13. }
    14.  
    15. Page1::~Page1()
    16. {
    17. delete ui;
    18. }
    19.  
    20. void Page1::on_pushButton_clicked()
    21. {
    22. QString testo;
    23. testo=ui->to_pass->text();
    24. emit(transfer(testo));
    25. page2->show();
    26. }
    To copy to clipboard, switch view to plain text mode 

    Page2.h and Page2.cpp were not changed.
    Thanks again!

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,053
    Thanks
    233
    Thanked 649 Times in 639 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Re Signal/slot between widgets

    Still have a small memory leak - you create page2 but never delete it. Change the Page1 destructor to this:

    Qt Code:
    1. Page1::~Page1()
    2. {
    3. delete ui;
    4. delete page2; // <-- add
    5. }
    To copy to clipboard, switch view to plain text mode 
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  7. #7
    Join Date
    Mar 2016
    Posts
    11
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Signal/slot between widgets

    You are right!
    Thank you for your help, d_stranz, and have a nice weekend!

  8. #8
    Join Date
    Jan 2017
    Posts
    58
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Signal/slot between widgets

    d_stranz: What about this solution?

    Qt Code:
    1. void Page1::on_pushButton_clicked()
    2. {
    3. Page2 *form = new Page2();
    4. form->setAttribute(Qt::WA_DeleteOnClose); // added this line
    5. connect(this, SIGNAL(transfer(QString)), form, SLOT(UpdateField(QString)));
    6. QString testo=ui->to_pass->text();
    7. emit(transfer(testo));
    8. form->show();
    9. }
    To copy to clipboard, switch view to plain text mode 

    I understand your solution, in general I do not have problem with that, but I think this looks "better" - at least you do not have to remember to delete it in destructor.
    Last edited by ado130; 26th March 2018 at 09:08.

  9. #9
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,053
    Thanks
    233
    Thanked 649 Times in 639 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Signal/slot between widgets

    What about this solution?
    If you want a completely new Page2 instance every time you click the button, this is one way to do it that avoids a member variable. It depends on how complex Page2 really is and whether constructing it on-the-fly like this would cause a noticeable pause between the click and the show.

    On the other hand, if you want the Page2 instance to "remember" what it was displaying the last time it was used, this approach will not be very good. Making a new instance each time will always initialize it to a fresh state with no memory of what was there before. So, if Page2 is used for setting options, with check boxes, radio buttons, and so forth, having them reset to the default settings each time will not make users very happy. If you have a single instance and simply show() and hide() it, then it will keep its state between uses.

    My preference is to do as I suggested: create a single instance in the constructor and re-use it when needed. If you do need to set it to a default state, then add a method to the Page2 class to do that and call it before you show it.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  10. #10
    Join Date
    Mar 2016
    Posts
    11
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Signal/slot between widgets

    It's a really good solution!
    My first problem was simply to make it working, but of course the second step is "make it work better"...
    With your second suggestion I can optimize my code, and now I'm trying to create a more complex Page2 for better understanding the differences of two ways.
    Have a nice day

Similar Threads

  1. Replies: 1
    Last Post: 14th August 2014, 17:08
  2. Replies: 6
    Last Post: 4th March 2014, 15:09
  3. Replies: 8
    Last Post: 7th November 2012, 14:10
  4. Replies: 2
    Last Post: 12th February 2009, 22:23
  5. signal slot conection using a string, not a SLOT
    By rianquinn in forum Qt Programming
    Replies: 6
    Last Post: 5th February 2006, 18:52

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.