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. Show and hide parent window (QWidget) from child (QDialog)
Forum Updated to NodeBB v4.3 + New Features

Show and hide parent window (QWidget) from child (QDialog)

Scheduled Pinned Locked Moved General and Desktop
13 Posts 5 Posters 12.6k Views 3 Watching
  • 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.
  • JeroentjehomeJ Offline
    JeroentjehomeJ Offline
    Jeroentjehome
    wrote on last edited by
    #2

    Hi,
    The parent pointer is a QObject pointer, not a Widget!! So do a qobject_cast to change it into a QWidget pointer and use the show.
    That might do the trick!

    Greetz, Jeroen

    1 Reply Last reply
    0
    • Y Offline
      Y Offline
      Yossi
      wrote on last edited by Yossi
      #3

      Hi Jeroen,

      Thanks for your fast response.

      parent is already Qwidget pointer

      mySetupDialog::mySetupDialog(QWidget *parent) :
      QDialog(parent),
      ui(new Ui::mySetupDialog)
      {
      ...
      }

      Anyhow, I tried your suggestion and it wont work

      ((QWidget*)parent)->show();
      ERROR: invalid use of member (did you forget the ‘&’ ?)

      1 Reply Last reply
      0
      • J Offline
        J Offline
        Jumetor
        wrote on last edited by
        #4

        Hi Jossi,

        I solved my problem with the signals and slots like this:

        in child.h
        signals:
        void Want2Close();

        in child.cpp
        void child::on_btnClose_clicked()
        {
        this->close();
        emit Want2Close();
        }

        in parent.cpp on a QpushButton

        child *child1 = new child;
        connect(child1,&child::Want2Close,this,&MainWindow::show);
        this->hide();
        child1->show();
        
        Y 1 Reply Last reply
        1
        • Chris KawaC Offline
          Chris KawaC Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by
          #5

          @Yossi said:

          ((QWidget*)parent)->show();
          ERROR: invalid use of member (did you forget the ‘&’ ?)

          parent() is a function, so you need to give it a parameter list, even if it's empty: (QWidget*)parent()->show().

          But you don't have to do that at all. There are also parentWidget() and window() methods that give you your widget's parent widget and your widget's top level widget respectively. Just remember to check if what they return is not null before you try to call anything on it.

          1 Reply Last reply
          1
          • J Jumetor

            Hi Jossi,

            I solved my problem with the signals and slots like this:

            in child.h
            signals:
            void Want2Close();

            in child.cpp
            void child::on_btnClose_clicked()
            {
            this->close();
            emit Want2Close();
            }

            in parent.cpp on a QpushButton

            child *child1 = new child;
            connect(child1,&child::Want2Close,this,&MainWindow::show);
            this->hide();
            child1->show();
            
            Y Offline
            Y Offline
            Yossi
            wrote on last edited by
            #6

            @Jumetor

            I tried it and I got the following errors:
            error: cannot call member function ‘void child::Want2Close()’ without object
            error: lvalue required as unary ‘&’ operand

            Any idea why?

            Thanks.

            J 1 Reply Last reply
            0
            • Chris KawaC Offline
              Chris KawaC Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on last edited by
              #7

              Want2Close() is not a static memberfunction so you cant call it on a class name like that. You need to call it on an instance of your class, e.g. something like child1->Want2Close(), but you need to post the code that actually errors out for us to help.

              Btw. Please surround code blocks with ```. It will make it a lot easier for us to read here.

              1 Reply Last reply
              0
              • Y Yossi

                @Jumetor

                I tried it and I got the following errors:
                error: cannot call member function ‘void child::Want2Close()’ without object
                error: lvalue required as unary ‘&’ operand

                Any idea why?

                Thanks.

                J Offline
                J Offline
                Jumetor
                wrote on last edited by
                #8

                @Yossi ,

                here my exemple :
                https://mega.nz/#!TxtXXLhD!BxXcBix1ObvFEik7w8x9rdISmdz9g_zAi7zRZ8NJrT0

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  ambershark
                  wrote on last edited by ambershark
                  #9

                  My guess is your pointer to your "parent" is not your mainwindow for some reason.

                  Try putting in something like this:

                  void mySetupDialog::jump()
                  {
                     QObject *p = this;
                     do 
                     {
                        p = p->parent();
                     } while (p->parent() != NULL);
                  
                     QMainWindow *mw = qobject_cast<QMainWindow *>(p);
                     if (!mw)
                     {
                        // couldnt find main window
                     }
                     else
                     {
                        mw->show();
                        hide();
                     }
                  }
                  

                  Now if that works, I would figure out why mw != parent to prevent further issues. Once you figure that out you can ditch this loop method.

                  This also assumes QMainWIndow is your top level widget, which it should be. If it's not, add pointer cast testing with qobject_cast into your loop till you find your main window.

                  My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                  1 Reply Last reply
                  0
                  • Chris KawaC Offline
                    Chris KawaC Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by Chris Kawa
                    #10

                    OMG, guys, you're complicating this beyond reason.

                    @Jumetor You're basically reinventing the wheel - a dialog. Also, you're leaking memory (Form instance).
                    @ambershark Loops and casts are total overkill. All you need is window()->show(), but even that is unnecessary here.

                    The child shouldn't even know about its parent and it's not its role to show or hide it. "Sniffing" for a parent of concrete type is just evil. What if top most class changes one day?

                    Here's a simple example (I ommited layouts and such for simplicity):

                    #include <QApplication>
                    #include <QMainWindow>
                    #include <QDialog>
                    #include <QPushButton>
                    
                    class Form : public QDialog {
                    public:
                        Form() {
                            auto closeBtn = new QPushButton("Close", this);
                            connect(closeBtn, &QPushButton::clicked, this, &Form::accept);
                        }
                    };
                    
                    class MainWindow : public QMainWindow {
                    public:
                        MainWindow() {
                            auto openBtn = new QPushButton("Open child", this);
                            connect(openBtn, &QPushButton::clicked, this, &MainWindow::showDialog);
                        }
                        void showDialog() {
                            hide();
                            Form form;
                            form.exec();
                            show();
                        }
                    };
                    
                    
                    int main(int argc, char *argv[])
                    {
                        QApplication a(argc, argv);
                        MainWindow w;
                        w.show();
                    
                        return a.exec();
                    }
                    
                    J A 2 Replies Last reply
                    0
                    • Chris KawaC Chris Kawa

                      OMG, guys, you're complicating this beyond reason.

                      @Jumetor You're basically reinventing the wheel - a dialog. Also, you're leaking memory (Form instance).
                      @ambershark Loops and casts are total overkill. All you need is window()->show(), but even that is unnecessary here.

                      The child shouldn't even know about its parent and it's not its role to show or hide it. "Sniffing" for a parent of concrete type is just evil. What if top most class changes one day?

                      Here's a simple example (I ommited layouts and such for simplicity):

                      #include <QApplication>
                      #include <QMainWindow>
                      #include <QDialog>
                      #include <QPushButton>
                      
                      class Form : public QDialog {
                      public:
                          Form() {
                              auto closeBtn = new QPushButton("Close", this);
                              connect(closeBtn, &QPushButton::clicked, this, &Form::accept);
                          }
                      };
                      
                      class MainWindow : public QMainWindow {
                      public:
                          MainWindow() {
                              auto openBtn = new QPushButton("Open child", this);
                              connect(openBtn, &QPushButton::clicked, this, &MainWindow::showDialog);
                          }
                          void showDialog() {
                              hide();
                              Form form;
                              form.exec();
                              show();
                          }
                      };
                      
                      
                      int main(int argc, char *argv[])
                      {
                          QApplication a(argc, argv);
                          MainWindow w;
                          w.show();
                      
                          return a.exec();
                      }
                      
                      J Offline
                      J Offline
                      Jumetor
                      wrote on last edited by
                      #11

                      Hi @Chris-Kawa ,

                      Thank you for your example. I do not know. I use every time a QWidget for my forms.
                      In my example, I can avoid the memory leak?

                      1 Reply Last reply
                      0
                      • Chris KawaC Offline
                        Chris KawaC Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on last edited by Chris Kawa
                        #12

                        @Jumetor You can set a Qt::WA_DeleteOnClose attribute on your form using setAttribute(). This would delete the Form instance when it is closed. But the code widow->show() in the Form will not show the main window. It will show the top most widget containing the caller. In other words it'll just show itself. The form really shouldn't try to show the main window. The main window should show the dialog and wait for it to close then show up again, like in my example. The dependencies are much smaller this way, as only one class knows about another and not both referring to each other.

                        Btw. If you never used QDialog I suggest you start doing so. That's what it's there for.

                        1 Reply Last reply
                        0
                        • Chris KawaC Chris Kawa

                          OMG, guys, you're complicating this beyond reason.

                          @Jumetor You're basically reinventing the wheel - a dialog. Also, you're leaking memory (Form instance).
                          @ambershark Loops and casts are total overkill. All you need is window()->show(), but even that is unnecessary here.

                          The child shouldn't even know about its parent and it's not its role to show or hide it. "Sniffing" for a parent of concrete type is just evil. What if top most class changes one day?

                          Here's a simple example (I ommited layouts and such for simplicity):

                          #include <QApplication>
                          #include <QMainWindow>
                          #include <QDialog>
                          #include <QPushButton>
                          
                          class Form : public QDialog {
                          public:
                              Form() {
                                  auto closeBtn = new QPushButton("Close", this);
                                  connect(closeBtn, &QPushButton::clicked, this, &Form::accept);
                              }
                          };
                          
                          class MainWindow : public QMainWindow {
                          public:
                              MainWindow() {
                                  auto openBtn = new QPushButton("Open child", this);
                                  connect(openBtn, &QPushButton::clicked, this, &MainWindow::showDialog);
                              }
                              void showDialog() {
                                  hide();
                                  Form form;
                                  form.exec();
                                  show();
                              }
                          };
                          
                          
                          int main(int argc, char *argv[])
                          {
                              QApplication a(argc, argv);
                              MainWindow w;
                              w.show();
                          
                              return a.exec();
                          }
                          
                          A Offline
                          A Offline
                          ambershark
                          wrote on last edited by
                          #13

                          @Chris-Kawa I didn't give him that loop for production reasons. I gave it to him to check to see why his parent widget wasn't matching the main window (assuming it wasn't). If you read my whole post you would see I told him to "ditch this loop method".

                          This was just to help him figure out what was going on not to leave in for actual usage in a program.

                          And if the parent changed some day then the if (!mw) would catch that. Assuming he left this code in which again I recommended against. :)

                          My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                          1 Reply Last reply
                          0

                          • Login

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