Solved 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(); }
-
@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?
-
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 isMltpDlgs2
, why don't you subclass fromQDialog
? That will show you what you want. -
@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. " -
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!!
@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? -
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 isQt::Dialog
, that indicatesQt::Window
.
(Qt::Dialog
= 0x00000002 |Qt::Window
)
If you want a widget to both having a parent and being a top-level window, you must haveQt::Window
set inwindowFlags
.
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)
-
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. :)
-
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.
AQt::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!