Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Have a separate window as the child



  • Hi all,

    I want to have a separate UI when the button "with parent" is clicked as a child and another separate UI when the button "without Parent" is clicked as a non-child of the main widget. I created a class for that separate UI. The non child one is shown/created fine but the child one is created right upon the parent!

    MltpDlgs1.h:

    #ifndef MLTPDLGS1_H
    #define MLTPDLGS1_H
    
    #include <QDialog>
    #include "mltpdlgs2.h"
    
    class QPushButton;
    
    class MltpDlgs1 : public QDialog
    {
        Q_OBJECT
    
    public:
        MltpDlgs1(QWidget *parent = nullptr);
    
    private slots:
        void on_withParent();
        void on_withoutParent();
    
    private:
        QPushButton* withParent = nullptr;
        QPushButton* withoutParent = nullptr;
    };
    #endif // MLTPDLGS1_H
    

    MltpDlgs1.cpp:

    #include "mltpdlgs1.h"
    
    #include <QPushButton>
    #include <QVBoxLayout>
    
    MltpDlgs1::MltpDlgs1(QWidget *parent)
        : QDialog(parent)
    {
        withParent = new QPushButton(tr("With Parent"));
        withoutParent = new QPushButton(tr("Without Parent"));
    
        auto mainLayout = new QVBoxLayout;
        mainLayout->addWidget(withParent);
        mainLayout->addStretch();
        mainLayout->addWidget(withoutParent);
    
        setLayout(mainLayout);
    
        connect(withParent, &QPushButton::clicked, this, &MltpDlgs1::on_withParent);
        connect(withoutParent, &QPushButton::clicked, this, &MltpDlgs1::on_withoutParent);
    }
    
    void MltpDlgs1::on_withParent()
    {
        // With Parent
      auto dialog2 = new MltpDlgs2(this);
      dialog2->setMinimumSize(100, 100);
      dialog2->show();
    }
    
    void MltpDlgs1::on_withoutParent()
    {
        // Without Parent
        auto dialog2 = new MltpDlgs2;
        dialog2->setMinimumSize(100, 100);
        dialog2->show();
    }
    

    MltpDlgs2.h:

    #ifndef MLTPDLGS2_H
    #define MLTPDLGS2_H
    
    #include <QWidget>
    
    class QPushButton;
    class QLabel;
    
    class MltpDlgs2 : public QWidget
    {
        Q_OBJECT
    public:
        explicit MltpDlgs2(QWidget *parent = nullptr);
    
    private:
        QPushButton* clse = nullptr;
        QLabel* label = nullptr;
    };
    
    #endif // MLTPDLGS2_H
    
    

    MltpDlgs2.cpp:

    #include "mltpdlgs2.h"
    
    #include <QPushButton>
    #include <QLabel>
    #include <QVBoxLayout>
    
    MltpDlgs2::MltpDlgs2(QWidget *parent) : QWidget(parent)
    {
        label = new QLabel(tr("This is dialog 2"));
        clse = new QPushButton(tr("Close"));
    
        auto mainLayout = new QVBoxLayout;
        mainLayout->addWidget(label);
        mainLayout->addStretch();
        mainLayout->addWidget(clse);
        setLayout(mainLayout);
    
        connect(clse, &QPushButton::clicked, this, &MltpDlgs2::close);
    }
    
    

    main.cpp:

    #include "mltpdlgs1.h"
    
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MltpDlgs1 w;
        w.setMinimumSize(300, 100);
        w.show();
        return a.exec();
    }
    

  • Lifetime Qt Champion

    @tomy said in Have a separate window as the child:

    but the child one is created right upon the parent!

    What do you mean by that?



  • @jsulm

    Sorry, I must have said "inside it" (not as a separate UI).



  • @tomy That is a widget which has a parent normally performs.
    Do you mean you want it to be a top-level window, but with a parent set?
    Since the class name is MltpDlgs2, why don't you subclass from QDialog? That will show you what you want.


  • Lifetime Qt Champion

    @tomy Well, it does exactly what you asked it to do. See @Bonnie post.
    You can also easily find this information in the documentation (https://doc.qt.io/qt-5/qwidget.html#QWidget):
    "If parent is nullptr, the new widget becomes a window. If parent is another widget, this widget becomes a child window inside parent. "



  • @Bonnie

    Do you mean you want it to be a top-level window, but with a parent set?

    Yes, I think.

    Since the class name is MltpDlgs2, why don't you subclass from QDialog? That will show you what you want.

    I wanted, but there isn't such a base class on the list!!

    Untitled.png

    @jsulm Probably a new class (for the second UI) is not correct and for that purpose I need to use something else. Right?



  • @tomy ...Do you think all of us can only subclass those several classes?
    Use that <Custom> and you can subclass any class by filling in the empty line edit...
    This is only a wizard...you can even create a new class without using it.
    Though I usually select the QWidget as base class and then modify it to another widget class after the files are auto generated.
    Like now, you can just modify your existing code, I'll only post the lines you need to change:
    MltpDlgs2.h:

    #include <QDialog>
    
    class MltpDlgs2 : public QDialog
    

    MltpDlgs2.cpp:

    MltpDlgs2::MltpDlgs2(QWidget *parent) : QDialog(parent)
    

    P.S. Then how did you create MltpDlgs1 class in the first place?



  • @Bonnie

    Then how did you create MltpDlgs1 class in the first place?

    By inheriting from QLabel. But for the second class that base class doesn't exist and had to manually inherit from QLabel.

    But why this works now, please?
    I mean what's the difference between those two widgets (QWidget& QDialog) for my project that makes that difference?



  • @tomy Because the default windowFlags for QDialog is Qt::Dialog, that indicates Qt::Window.
    ( Qt::Dialog = 0x00000002 | Qt::Window)
    If you want a widget to both having a parent and being a top-level window, you must have Qt::Window set in windowFlags.
    So if you don't change your code according to my last post, you can also have it done by changing:
    MltpDlgs2.cpp:

    MltpDlgs2::MltpDlgs2(QWidget *parent) : QWidget(parent, Qt::Window)
    


  • @Bonnie

    Qh, that's rather too advanced for me at least for the time being. So for now I stick to the prior version (inheriting from QLabel manually). Perhaps some time in the future I will need to get used to those window and flags more. :)

    PS: This, too, worked, thanks. :)



  • @Bonnie

    MltpDlgs2::MltpDlgs2(QWidget *parent) : QWidget(parent, Qt::Window)

    What does that Qt::Window above mean if you want to say in simple language, please?



  • @tomy This is where you pass the windowFlags to the QWidget constructor.
    A Qt::Window means I want this widget to be a top-level window, no matter with or without a parent.



  • @tomy
    You can read through what all the window flags are at https://doc.qt.io/qt-5/qt.html#WindowType-enum, and there is even an example you can run at https://doc.qt.io/qt-5/qtwidgets-widgets-windowflags-example.html which lets you click to see what each window flag does in practice!


Log in to reply