Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. how can QDialog update MainWindow?

how can QDialog update MainWindow?

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 4.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    WhatIf
    wrote on last edited by WhatIf
    #1

    I have a QDialog (MemberSearch) that takes a member name and try to find it a database. If successful, I want the MainWindow to show the member's info.

    I get the following error:

    error: 'class Ui::MemberSearch' has no member named 'stackedWidget_2'
    ui->stackedWidget_2->setCurrentIndex(2);

    stackedWidget_2 is part of mainwindow. How can I access mainwindow widgets from QDialog?

    1 Reply Last reply
    0
    • M Offline
      M Offline
      michelson
      wrote on last edited by
      #2

      I guess good way would be emiting singnal which triggers some kind of updating function-slot in MainWindow.
      You can as well try getting parent widget ( http://doc.qt.io/qt-5/qwidget.html#parentWidget ) however i think it is not a "clean" solution.

      1 Reply Last reply
      1
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi
        The UI is private to the class owning it.
        This means that outside class like a dialog cannot just talk to another class UI objects.
        This concept is call incapsulation
        https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)

        Very fast it means that is not a good idea that all the rest of the program knows what kind of widgets
        another class has as then if u change something, you will have to change all other places in the program that
        knew u had such widget.
        So a much better way is to use signals and slot.
        A signal is just a notification and the slot/who get the signal dont really care who send it and in this way
        we suddenly have a much better design.

        So in your case.
        You would define a new signal
        void MemberFound( MemeberInfo Info );
        in the dialog.

        and in mainwindow, hook up the signal to a slot in mainwindow
        via the connect statement.

        and then in dialog when u find the member
        u do
        emit MemberFound(theinfofound)

        and in the slot in mainwindow, you will do what ever u need when member found.

        So general rule is that if u have the need to do stuff with other class widget, you will use signals or a
        public function in that class to do what u need. You cannot and should not ever be able to say
        otherclass->ui->somewidget.

        W 1 Reply Last reply
        1
        • mrjjM mrjj

          Hi
          The UI is private to the class owning it.
          This means that outside class like a dialog cannot just talk to another class UI objects.
          This concept is call incapsulation
          https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)

          Very fast it means that is not a good idea that all the rest of the program knows what kind of widgets
          another class has as then if u change something, you will have to change all other places in the program that
          knew u had such widget.
          So a much better way is to use signals and slot.
          A signal is just a notification and the slot/who get the signal dont really care who send it and in this way
          we suddenly have a much better design.

          So in your case.
          You would define a new signal
          void MemberFound( MemeberInfo Info );
          in the dialog.

          and in mainwindow, hook up the signal to a slot in mainwindow
          via the connect statement.

          and then in dialog when u find the member
          u do
          emit MemberFound(theinfofound)

          and in the slot in mainwindow, you will do what ever u need when member found.

          So general rule is that if u have the need to do stuff with other class widget, you will use signals or a
          public function in that class to do what u need. You cannot and should not ever be able to say
          otherclass->ui->somewidget.

          W Offline
          W Offline
          WhatIf
          wrote on last edited by WhatIf
          #4

          @mrjj, @michelson

          Here is what I did so far:

          in MemberSearch.h (QDialog), I added:

          signals:
             void MemberFound(std::string fullName);
          

          in MemberSearch.cpp (QDialog), I added the following line after the code that finds the member's info:

          emit MemberFound(rcd->getFullName());
          close();
          

          in mainwindow.h, I added:

          private slots:
             void displayMemberInfo(std::string fullName);
          

          in mainwindow.cpp, I added:

          void MainWindow::displayMemberInfo(std::string fullName)
          {
              ui->stackedWidget_2->setCurrentIndex(2);
              ui->displayFullNameLbl->setText(QString::fromStdString(fullName));
          }
          

          and inside mainwindow's constructor I added:

               MemberSearch found;
               connect(&found, SIGNAL(MemberFound(std::string)), this, SLOT(displayMemberInfo(std::string)));
          

          The app compiles and runs but the code inside

          void MainWindow::displayMemberInfo(std::string fullName)
          

          doesn't seem to execute.

          The QDialog (MemberSearch) closes, so I assume the the signal was emitted. Also, is the signal just a declaration in the .h file? Does it need an implementation in the .cpp file?

          I added qDebug() statements to both the code inside MemberSearch and mainwindow.

          inside MemberSearch:

                      qDebug()<< "************About to emit signal************";
                      emit MemberFound(memberRecord->getFullName()); 
                      close();
          

          inside mainwindow:

              qDebug()<<"************Inside displayMemberInfo************";
              ui->stackedWidget_2->setCurrentIndex(2);
              ui->displayFullNameLbl->setText(QString::fromStdString(fullName));
          

          Only

          ************About to emit signal************
          

          prints out. What am I doing missing?

          1 Reply Last reply
          0
          • mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by mrjj
            #5

            @WhatIf said:

            and inside mainwindow's constructor I added:

             MemberSearch found;
            

            Hi
            if you add that in constructor , do you also call
            found.exec() ?

            Else it means that the found variable runs out of scope and gets deleted.

            Do you see your MemberSearch dialog at all?

            else the code looks good and clean.

            You should add
            qDebug() << "con:" << connect(&found, SIGNAL(MemberFound(std::string)), this, SLOT(displayMemberInfo(std::string)));

            to see if it returns true.

            but i dont expect MemberSearch found; to live in ctor of mainwindow.
            More like there is a button and when pressed it would
            MemberSearch found;
            found.exec();

            1 Reply Last reply
            0
            • W Offline
              W Offline
              WhatIf
              wrote on last edited by
              #6

              if you add that in constructor , do you also call found.exec() ?

              No but after your comment I added it. What happened is when I first start the app, the QDialog show up only after I close the QDialog, mainwindow displays.

              qDebug() << "con:" << connect(&found, SIGNAL(MemberFound(std::string)), this, SLOT(displayMemberInfo(std::string)));

              I added it and it printed con: true

              Does the connect statement have to be in the constructor? All the examples I found online have the connect statement inside mainwindow constructor.

              For my app, created using Qt Designer, it has mainwindow which contains a button (member search button). Once the member search button is clicked the QDialog displays which asks for user name.

              Code inside member search button which is part of mainwindow :

              MemberSearch memSearch;
              memSearch.setModal(true);
              memSearch.setWindowFlags(Qt::CustomizeWindowHint); 
              memSearch.setWindowFlags(Qt::FramelessWindowHint); 
              memSearch.exec();
              

              Can I have the connect statement before the last line, memSearch.exec();?

              mrjjM 1 Reply Last reply
              0
              • M Offline
                M Offline
                michelson
                wrote on last edited by
                #7

                Look, the way I see it is that you may connect something (dialog) which just is not there anymore, I'd try something like:

                //------------YourDialog.h-------------
                singals:
                    void update_triggered(std::string updated_string);
                slots:
                   void on_updateButton_clicked();
                
                //-------YourDialog.cpp--------
                // somwhere in constructor
                connect(ui->updateButton, SIGNAL(clicked()), this, SLOT(on_updateButton_clicked()));  
                
                void YourDialog::on_updateButton_clicked() 
                {
                    //get things you want eg. process/get string you want to display @ mainwindow
                    emit update_triggered("I AM UPDATED RIGHT?!");
                
                //-------mainwindow.h-------
                slots:
                    void on_update_triggered(std::string str);
                
                //-----mainwindow.cpp-----
                YourDialog* dialog = new YourDialog(this);
                connect(dialog, SIGNAL(update_triggered(std::string)), this, SLOT(on_update_triggered(std::string)));
                dialog.exec();
                delete dialog;
                
                1 Reply Last reply
                1
                • W WhatIf

                  if you add that in constructor , do you also call found.exec() ?

                  No but after your comment I added it. What happened is when I first start the app, the QDialog show up only after I close the QDialog, mainwindow displays.

                  qDebug() << "con:" << connect(&found, SIGNAL(MemberFound(std::string)), this, SLOT(displayMemberInfo(std::string)));

                  I added it and it printed con: true

                  Does the connect statement have to be in the constructor? All the examples I found online have the connect statement inside mainwindow constructor.

                  For my app, created using Qt Designer, it has mainwindow which contains a button (member search button). Once the member search button is clicked the QDialog displays which asks for user name.

                  Code inside member search button which is part of mainwindow :

                  MemberSearch memSearch;
                  memSearch.setModal(true);
                  memSearch.setWindowFlags(Qt::CustomizeWindowHint); 
                  memSearch.setWindowFlags(Qt::FramelessWindowHint); 
                  memSearch.exec();
                  

                  Can I have the connect statement before the last line, memSearch.exec();?

                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by mrjj
                  #8

                  @WhatIf said:

                  MemberSearch memSearch;
                  ..
                  MemberSearch found;

                  Yes you should have connect there.
                  The " MemberSearch found;" you connect in constructor don't survive.

                  Here you you use another one. so that is also the reason it doesn't work for you.
                  This one that you show- have no connect.
                  so connect here and remove the other one from constructor.

                  --

                  • No but after your comment I added it. What happened is when I first start the app, the QDialog show up only after I close the QDialog, mainwindow displays.

                  That is why i wondered why you had in constructor.
                  the exec() calls starts a local event loop and stay in there, meaning it won't execute next statement before you
                  close the dialog, So mainwindow first show when u close dialog,

                  1 Reply Last reply
                  1

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved