How to organize a system of parent and child windows.



  • Let's say I have a main window.

    Then when I click a button I want a child window to open up and that main windows to hide.
    Then when I close that child window i want the main windows to reappear.

    Right now I'm opening up that child window by doing:

    @s=new SignUpWindow(NULL,temp);
    s->show(); @

    where s is a private pointer of my main window.

    When I try to do:

    @s=new SignUpWindow(this,temp);
    s->show(); @

    The s window doesn't show up.

    Here is the signature of it's constructor:

    @SignUpWindow (QWidget* parent=NULL, Netflix *n=NULL);@

    Thanks for your help!


  • Moderators

    There's nothing obviously wrong in your code so the problem is somewhere else.
    But that's not the usual way to use a sign up dialog. Usually the SignUpWindow would inherit a QDialog and you'd do something like this:
    @
    void MainWindow::showSignUp() {
    hide();
    SignUpWindow dialog;
    if(dialog.exec() == QDialog::Accepted)
    loginData = dialog.whatever();
    show();
    }
    @
    Usually there's no need to keep the dialog pointer around or create the dialog on the heap.



  • Hi chris. I'm still not sure what the purpose of the dialog is. Can you please take a look at my post on stack overflow for more of my code. Maybe you can explain what i'm missing. Thank!

    http://stackoverflow.com/questions/26815855/how-to-organize-a-system-of-parent-and-child-windows-that-hide-their-parent-qt


  • Moderators

    So you've got something that looks like this:
    @
    //.h
    class SignUpWindow : public QWidget {...
    //.cpp
    SignUpWindow::SignUpWindow (QWidget* parent, Netflix n) : QWidget (parent)
    @
    What I'm saying is you should change that to
    @
    //.h
    class SignUpWindow : public QDialog {...
    //.cpp
    SignUpWindow::SignUpWindow (QWidget
    parent, Netflix *n) : QDialog (parent)
    @

    The benefits of a dialog are as follows:

    • It has an exec() method that starts an event loop and blocks the caller until your dialog is done. This allows you to create a more readable and nicer control flow(like in my example). If you just show() a dialog like you have, you're still in the main event loop and the dialog is not really a dialog but a "floating tool window" and you need to monitor somehow when it closes, cancels etc. With exec() you just check the return code in the same place you called it. A lot simpler.
    • QDialog has methods accept() and reject() which you can connect to various buttons in your dialog. This will work nicely with exec() so you can write that if() statement in my example.
    • QDialog is a window by default ie. it will be show as a window and if you give it a parent it will center on it. If your window is just a widget and you give it a parent it will be "embedded" in that parent, which is not what you want.
    • When you close the dialog using the X button on the window frame it correctly handles that and returns QDialog::Rejected from the exec() so you don't need to do anything special to handle that, where with QWidget you would have to.

    Having all that I would recommend something like this:
    @
    //should split this to .h and .cpp but for brevity I'll keep it in one place
    class SignUpWindow : public QDialog() {
    public:
    SignUpWindow::SignUpWindow(QWidget* parent = nullptr) : QDialog(parent) {
    auto okButton = new QPushButton(...);
    connect(okButton, &QPushButton::clicked, this, &QDialog::validate);
    ... //setup layouts, cancel button, other widgets etc.
    }
    void validate() {
    if( /* do whatever to validate the state of the data user entered */) {
    info = //gather the info from widgets, external service or whatever
    accept();
    }
    else
    /show an error message, correction instructions etc./
    }
    SomeSignUpInformation getInfo() const { return info; }
    private:
    SomeSignUpInformation info; //whatever your scheme uses: user name, password, hash id etc.
    };

    //then somewhere you call it like this:
    void MainWindow::showSignUp() {
    hide();
    SignUpWindow dialog(this);
    if(dialog.exec(); == QDialog::Accepted)
    loginData = dialog.getInfo();
    show();
    }
    @

    Btw. don't use NULL macro. It's old and has issues. If you have a decent compiler use nullptr instead.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.