+ Reply to Thread
Results 1 to 3 of 3

Thread: Friend Classes in Separate .h files

  1. #1
    Join Date
    Jun 2017
    Posts
    2
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Friend Classes in Separate .h files

    Hello everyone, first of all I just start learning Qt.

    I have MainWindow class defined in "mainwindow.h" and "mainwindow.cpp" files.
    The "Dialog" and "Dialog_2" classes are friend classes of that MainWindow class.
    An object of "MainWindow" class is parent of "Dialog" and "Dialog_2" type objects.
    But I cannot access the members of MainWindow from both of that friend classes.
    From the function "void Dialog_2::add_new_person()", I am trying to access the data_map member of parent object, but I cannot do that.

    The code is:

    "mainwindow.h"
    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QMainWindow>
    5.  
    6. namespace Ui {
    7. class MainWindow;
    8. }
    9.  
    10. class MainWindow : public QMainWindow
    11. {
    12. friend class Dialog;
    13. friend class Dialog_2;
    14. Q_OBJECT
    15. .......
    16. }
    To copy to clipboard, switch view to plain text mode 

    "mainwindow.cpp"
    Qt Code:
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3. #include "dialog.h"
    4. #include "dialog_2.h"
    5.  
    6. MainWindow::MainWindow(QWidget *parent) :
    7. QMainWindow(parent),
    8. ui(new Ui::MainWindow)
    9. {
    10. ui->setupUi(this);
    11. }
    12. .....
    To copy to clipboard, switch view to plain text mode 

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

    "dialog_2.cpp"
    Qt Code:
    1. #include "dialog_2.h"
    2. #include "ui_dialog_2.h"
    3. #include <QMessageBox>
    4. #include <QDebug>
    5. #include "mainwindow.h"
    6.  
    7. Dialog_2::Dialog_2(QWidget *parent) :
    8. QDialog(parent),
    9. ui(new Ui::Dialog_2)
    10. {
    11. ui->setupUi(this);
    12. }
    13.  
    14. Dialog_2::~Dialog_2()
    15. {
    16. delete ui;
    17. }
    18.  
    19. void Dialog_2::on_pushButton_clicked()
    20. {
    21. add_new_person();
    22. close();
    23. }
    24.  
    25. void Dialog_2::on_pushButton_2_clicked()
    26. {
    27. close();
    28. }
    29.  
    30. void Dialog_2::add_new_person()
    31. {
    32. QString new_name = ui->lineEdit_1->text();
    33. QString new_number = ui->lineEdit_2->text();
    34.  
    35. this->parent()->data_map.insert(new_name, new_number);
    36.  
    37. QMessageBox::information(this, "Added!", new_name + " has added successfully!");
    38. }
    To copy to clipboard, switch view to plain text mode 

    It's same for dialog.h class, so I didnot add the code.

    Thanks for your help

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    3,117
    Thanks
    194
    Thanked 491 Times in 481 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Friend Classes in Separate .h files

    The "Dialog" and "Dialog_2" classes are friend classes of that MainWindow class.
    Wrong, wrong, wrong. Except in rare circumstance you never need friend classes, and certainly not for the case you are describing.

    Your case is exactly what Qt's signals and slots are designed for. You want to add a new person to MainWindow's data structure from your Dialog class? Then add a signal to Dialog_2 to let MainWindow know:

    Qt Code:
    1. class Dialog_2 /...
    2. {
    3. Q_OBJECT
    4.  
    5. // ...
    6.  
    7. signals:
    8. void addNewPerson( const QString & name, const QString & number );
    9.  
    10. // ...
    11. };
    To copy to clipboard, switch view to plain text mode 


    In your Dialog_2::add_new_person method, you do this:

    Qt Code:
    1. void Dialog_2::add_new_person()
    2. {
    3. QString new_name = ui->lineEdit_1->text();
    4. QString new_number = ui->lineEdit_2->text();
    5.  
    6. emit addNewPerson(new_name, new_number);
    7. }
    To copy to clipboard, switch view to plain text mode 

    In your MainWindow class, you create a slot:

    Qt Code:
    1. // MainWindow.h
    2.  
    3. class MainWindow : //...
    4. {
    5. Q_OBJECT
    6. // ...
    7.  
    8. private slots:
    9. void onAddNewPerson( const QString & name, const QString & number );
    10.  
    11. };
    12.  
    13. // MainWindow.cpp:
    14.  
    15. void MainWindow::onAddNewPerson( const QString & name, const QString & number )
    16. {
    17. data_map.insert( name, number );
    18. }
    To copy to clipboard, switch view to plain text mode 

    And at the place where you invoke the Dialog_2 instance:

    Qt Code:
    1. void MainWindow::getNewPersonInfo()
    2. {
    3. Dialog_2 dlg( this );
    4. connect ( &dlg, &Dialog_2::addNewPerson, this, &MainWindow::onAddNewPerson );
    5. dlg.exec();
    6. }
    To copy to clipboard, switch view to plain text mode 

    And as soon as the Add button is clicked in Dialog_2, the signal gets sent to MainWindow, and the new person gets added. If you want to get feedback to Dialog_2 to report success, then you add a signal to MainWindow ("void newPersonAdded( bool bStatus )" ) that you emit after the insert into the map. If the insert succeeded, you pass "true" in the signal, otherwise you pass "false" as the "bStatus" value.

    In Dialog_2, you add a slot (void onNewPersonAdded( bool bStatus ) ). In that slot you can display your QMessageBox with the "Success!" or "Failed!" message.

    You add a second connection between the MainWindow's signal and the Dialog_2 slot at the same place you made the first connection:

    Qt Code:
    1. void MainWindow::getNewPersonInfo()
    2. {
    3. Dialog_2 dlg( this );
    4. connect ( &dlg, &Dialog_2::addNewPerson, this, &MainWindow::onAddNewPerson );
    5. connect( this, &MainWindow::onNewPersonAdded, &dlg, &Dialog_2::onNewPersonAdded );
    6. dlg.exec();
    7. }
    8.  
    9. // and update this method:
    10. void MainWindow::onAddNewPerson( const QString & name, const QString & number )
    11. {
    12. if ( data_map.contains( name ) )
    13. emit newPersonAdded( false ); // duplicate name, so don't add it
    14. else
    15. {
    16. data_map.insert( name, number );
    17. emit newPersoanAdded( true );
    18. }
    19. }
    To copy to clipboard, switch view to plain text mode 

    No need for friend classes, no need for Dialog_2 to know how MainWindow stores person information, no need for Dialog_2 to even know there is a MainWindow class. The signals and slots take care of transmitting the information between Dialog_2 and MainWindow.
    Last edited by d_stranz; 19th June 2017 at 17:23.
    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 2 users say thank you to d_stranz for this useful post:

    newBie123 (19th June 2017), scgrant327 (20th June 2017)

  4. #3
    Join Date
    Jun 2017
    Posts
    2
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: Friend Classes in Separate .h files

    Thank you so much for your detailed explanation. It helped me so much to understand signals and slots mechanism.
    I think I need to refresh my knowledge in fundamentals before starting to write my project.

+ Reply to Thread

Similar Threads

  1. Replies: 1
    Last Post: 8th April 2016, 21:34
  2. Separate Classes for Windows
    By Atomic_Sheep in forum General Programming
    Replies: 2
    Last Post: 14th January 2013, 12:21
  3. Export created files in shared library into separate folder
    By alizadeh91 in forum Qt Programming
    Replies: 1
    Last Post: 9th December 2012, 10:49
  4. Replies: 2
    Last Post: 25th September 2012, 03:38
  5. C++ friend classes, with structs and enums
    By kachofool in forum General Programming
    Replies: 4
    Last Post: 3rd December 2009, 15:03

Tags for this Thread

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