Results 1 to 6 of 6

Thread: Connecting signal from QDialog to slot from MainWindow classes

  1. #1
    Join Date
    Mar 2017
    Posts
    6
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Connecting signal from QDialog to slot from MainWindow classes

    I want that when the QDialog is closed by a button that emits "accepted();" signal, a slot in MaiWindow to capture the accept signal from QDialog. The slot is a custom method, show_table();.

    Qt Code:
    1. //mainwindow
    2.  
    3. AddRecipe * addrecipes = new AddRecipe;
    4. connect(ui->pushButton_4,SIGNAL(released()),this,SLOT(show_table()));
    5. connect(addrecipes,SIGNAL(accepted()),this,SLOT(show_table()));
    6. ....
    7.  
    8. //QDialog
    9. connect(ui->pushButton_4,SIGNAL(clicked(bool)),this,SLOT(accept()));
    10. .....
    11. void AddRecipe::on_pushButton_4_clicked()
    12.  
    13. // destroy();
    14. emit accepted();
    15. accept();
    16.  
    17. }
    To copy to clipboard, switch view to plain text mode 

    But show_table is never called. I've managed to use signal/slot mechanism in the same window, but not from another one.
    Attached Files Attached Files

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,715
    Thanks
    259
    Thanked 759 Times in 749 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: Connecting signal from QDialog to slot from MainWindow classes

    It is not necessary for you to emit the QDialog::accepted() signal. This signal is emitted by the QDialog base class when you call the QDialog::accept() method.

    You show three different connect() calls. The first one (line 4) won't compile because "ui->pushButton_4" is a private member of the AddRecipe class (unless your MainWindow class also happens to have a ui->pushButton_4 member, in which case you are connecting the wrong button).

    The second (line 5) looks correct, as does the one in line 9. If you added a signal-slot connection in Qt Designer when designing your dialog, then you probably have two slots being executed when the button is clicked: the one you manually connect to in line 9, and the one that is generated for you by Qt Designer that connects the button's clicked() signal to on_pushButton4_clicked().

    What you don't show us is the code where you actually show the AddRecipe dialog. My hunch is that your problem lies there.

    Edit: Ah, I noticed that you attached the zip file with your code. My hunch is correct.

    Qt Code:
    1. void MainWindow::on_actionAdd_New_triggered()
    2. {
    3.  
    4. AddRecipe mDialogAddRecipe;
    5. mDialogAddRecipe.setModal(true);
    6. mDialogAddRecipe.exec();
    7.  
    8.  
    9. }
    To copy to clipboard, switch view to plain text mode 

    You do understand that the AddRecipe instance you create -on the stack- here is not the same instance that you created in the MainWindow constructor, right? This instance has no connections to anything. And you also understand that the instance you create -on the heap- in the MainWindow constructor becomes basically an inaccessible dangling pointer once the constructor exits because you haven't saved the pointer anywhere, right?

    The easiest solution is to get rid of the code in the constructor that deals with this dialog and move it into the slot:

    Qt Code:
    1. void MainWindow::on_actionAdd_New_triggered()
    2. {
    3. AddRecipe addRecipes ( this );
    4. connect( &addrecipes,SIGNAL(accepted()),this,SLOT(show_table()));
    5. addRecipes.exec();
    6. }
    To copy to clipboard, switch view to plain text mode 

    Calling setModal() is redundant. By calling exec(), you -are- executing it as a modal dialog. Delete these lines from the MainWindow constructor:

    Qt Code:
    1. AddRecipe * addrecipes = new AddRecipe;
    2. connect(ui->pushButton_4,SIGNAL(released()),this,SLOT(show_table()));
    3. connect(addrecipes,SIGNAL(accepted()),this,SLOT(show_table()));
    To copy to clipboard, switch view to plain text mode 

    I haven't looked at the rest of your code, but unless your AddRecipe dialog somehow magically knows about your recipe database, anything that happens in the dialog disappears as soon as it closes because there aren't any other signals or slots connected to MainWindow or any data structures being retrieved from the dialog that tell MainWindow what has happened there. MainWindow's show_table() -can- access the dialog, but only temporarily, using the sender() method inside the show_table() slot. But once that slot exits, the dialog is gone.
    Last edited by d_stranz; 4th April 2017 at 23:06.
    <=== 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. The following user says thank you to d_stranz for this useful post:

    editheraven (4th April 2017)

  4. #3
    Join Date
    Mar 2017
    Posts
    6
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Connecting signal from QDialog to slot from MainWindow classes

    The pushbutton_4 in the mainwindow ui was just for testing to see if it can connect to the show_table method.
    I haven't added any signal-slot connections into the UI.
    You are so right, the instance created on the heap was useless as it couldn't be accessed when the constructor exited.
    Now, with the connect in the dialog constructor, the method is accessed.

    Anyway, the table model is not updated, but this is an issue I'll have to address later.

    Thanks alot for your insights on this one.
    Last edited by editheraven; 4th April 2017 at 23:32.

  5. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,715
    Thanks
    259
    Thanked 759 Times in 749 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: Connecting signal from QDialog to slot from MainWindow classes

    Anyway, the table model is not updated, but this is an issue I'll have to address later.
    I use the following pattern whenever I implement a dialog that collects non-trivial information from the user which then must be passed back to the main program:

    - create a struct or class that holds the data to be filled in by the dialog. Both the dialog and the main window know about this struct
    - before posting the dialog, fill an instance of the struct with appropriate default values
    - store the struct instance in the dialog instance
    - exec() the dialog
    - if exec() returns QDialog::Rejected, do nothing
    - if exec() returns QDialog::Accepted then do the following
    - retrieve the modified copy of the struct from the dialog
    - process it as appropriate to store it in the main app

    The code would roughly go like this:

    Qt Code:
    1. void MainWindow::on_actionAdd_New_triggered()
    2. {
    3. AddRecipe addRecipes ( this );
    4. RecipeTemplate newRecipe; // the struct, filled by default values on construction
    5. addRecipes.setRecipeTemplate( newRecipe );
    6. if ( QDialog::Accepted == addRecipes.exec() )
    7. {
    8. newRecipe = addRecipes.getNewRecipe();
    9. addNewRecipeToDB( newRecipe );
    10. }
    11. }
    To copy to clipboard, switch view to plain text mode 

    The dialog doesn't need any extra signals or slots, nor do I need to connect to any existing signals. Everything is handled internally to the MainWindow slot.
    <=== 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.

  6. #5
    Join Date
    Mar 2017
    Posts
    6
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Connecting signal from QDialog to slot from MainWindow classes

    I'll try this when I'll come from work.
    As I can see, this works almost like a callback function system.

    le : well I actually had too add
    Qt Code:
    1. emit accepted();
    To copy to clipboard, switch view to plain text mode 
    to be able to update my table.
    Last edited by editheraven; 5th April 2017 at 18:55.

  7. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,715
    Thanks
    259
    Thanked 759 Times in 749 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: Connecting signal from QDialog to slot from MainWindow classes

    As I can see, this works almost like a callback function system.
    Signals and slots are similar to that, yes. But in order for your dialog to do anything useful, it has to be able to communicate that to the rest of the program. So the callback (MainWindow slot in this case) has to receive data from the dialog. When calling this slot (by way of a signal), the dialog has to pass that information along.

    So an alternative to my pattern above would be similar to what is used in QFileDialog: whenever the user changes to a new directory, selects a different file extension from the combobox, or selects a file, QFileDialog emits a signal that notifies of the change. For your AddRecipe dialog to work the same way, it would have to emit a signal that contains the data the user has entered for the new recipe, and MainWindow needs a slot to receive that data. A signal / slot pair that don't transmit any information (like your show_table() slot) means that you have to find some alternative means to get the information from the dialog.

    I use the QFileDialog pattern when I need to keep track of changes occurring in the dialog while the dialog is still posted (like an "Apply" button that updates the main UI based on the current settings being defined in the dialog). If I don't need that, I generally use the pattern I described in the previous post.
    <=== 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.

Similar Threads

  1. Replies: 3
    Last Post: 19th October 2016, 16:07
  2. Connecting custom signal and slot
    By DmitryNik in forum Newbie
    Replies: 4
    Last Post: 12th September 2011, 15:15
  3. Connecting signal and slot by name
    By grayfox in forum Qt Programming
    Replies: 1
    Last Post: 22nd July 2011, 10:00
  4. Connecting signal to custom slot?
    By dbrmik in forum Qt Tools
    Replies: 2
    Last Post: 30th April 2009, 10:28
  5. Connecting two classes with slgnal and slot
    By Benjamin in forum Newbie
    Replies: 2
    Last Post: 22nd January 2009, 14:16

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.