Reparenting of QDialog leads to wrong Z-ordering? - simple example
-
Hi.
This simple application results in dialog 'Foo' being drawn under its parent, the window is modal, active and eats user input, yet it is drawn under 'Bar'. Am i doing something wrong?
Note that this only happens these two dialogs are first opened in child-parent relationship and then the relationship is reversed;
Also this does not occur without the presence of the main parent dialog.Edit: I only tried this on Windows 10 with Qt 5.9.3
#include <QApplication> #include <QDialog> int main(int argc, char *argv[]) { QApplication a(argc, argv); QDialog mainDialog; mainDialog.setWindowTitle("mainDialog"); mainDialog.resize(500, 500); QDialog bar(&mainDialog); bar.setWindowTitle("bar"); bar.resize(400, 300); QDialog foo(&mainDialog); foo.setWindowTitle("foo"); foo.resize(300, 400); mainDialog.open(); // parent one dialog to another and open them foo.open(); bar.setParent(&foo, bar.windowFlags()); bar.open(); // close dialogs bar.reject(); foo.reject(); // re-order parent-child and open again bar.setParent(&mainDialog, bar.windowFlags()); bar.open(); foo.setParent(&bar, foo.windowFlags()); foo.open(); return a.exec(); }
-
Hi.
This simple application results in dialog 'Foo' being drawn under its parent, the window is modal, active and eats user input, yet it is drawn under 'Bar'. Am i doing something wrong?
Note that this only happens these two dialogs are first opened in child-parent relationship and then the relationship is reversed;
Also this does not occur without the presence of the main parent dialog.Edit: I only tried this on Windows 10 with Qt 5.9.3
#include <QApplication> #include <QDialog> int main(int argc, char *argv[]) { QApplication a(argc, argv); QDialog mainDialog; mainDialog.setWindowTitle("mainDialog"); mainDialog.resize(500, 500); QDialog bar(&mainDialog); bar.setWindowTitle("bar"); bar.resize(400, 300); QDialog foo(&mainDialog); foo.setWindowTitle("foo"); foo.resize(300, 400); mainDialog.open(); // parent one dialog to another and open them foo.open(); bar.setParent(&foo, bar.windowFlags()); bar.open(); // close dialogs bar.reject(); foo.reject(); // re-order parent-child and open again bar.setParent(&mainDialog, bar.windowFlags()); bar.open(); foo.setParent(&bar, foo.windowFlags()); foo.open(); return a.exec(); }
@Spellcross
You may wish to state which platform(s) you have observed this behaviour on. Recently I had nasties with modeless dialogs, parenting & up-fronting: behaviour was different under Windows (to which I did not have access) vs Linux/GNOME. And GNOME has its own settings which affect this too. -
My colleague just found out that replacing line
bar.setParent(&mainDialog, bar.windowFlags());
with
auto flags = bar.windowFlags(); bar.setParent(&mainDialog); bar.setWindowFlags(flags);
solves the issue.
Seems like a bug in Qt -
My colleague just found out that replacing line
bar.setParent(&mainDialog, bar.windowFlags());
with
auto flags = bar.windowFlags(); bar.setParent(&mainDialog); bar.setWindowFlags(flags);
solves the issue.
Seems like a bug in Qt@Spellcross
On Windows or linux or ? -
Windows 10, I edited that into my original question
-
My colleague just found out that replacing line
bar.setParent(&mainDialog, bar.windowFlags());
with
auto flags = bar.windowFlags(); bar.setParent(&mainDialog); bar.setWindowFlags(flags);
solves the issue.
Seems like a bug in Qt@Spellcross
Could you explain what the overload https://doc.qt.io/qt-5/qwidget.html#setParent-1 (QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
) is supposed to do anyway? The docs only sayThis function also takes widget flags, f as an argument.
which is blindingly obvious, but doesn't tell me what it does with them? Bearing in mind it's a call which involves both the child & parent widgets, I don't even know which of the two it applies them to? You obviously consider it the same as going
bar.setWindowFlags()
, I wish the docs said so! -
@Spellcross
Could you explain what the overload https://doc.qt.io/qt-5/qwidget.html#setParent-1 (QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
) is supposed to do anyway? The docs only sayThis function also takes widget flags, f as an argument.
which is blindingly obvious, but doesn't tell me what it does with them? Bearing in mind it's a call which involves both the child & parent widgets, I don't even know which of the two it applies them to? You obviously consider it the same as going
bar.setWindowFlags()
, I wish the docs said so!@JonB
It would be very unexpected if it applied the flags to the parent. Anyway, the flags are applied to the child, which you can test by applying some specific flags that change the behavior... Btw the origin of the code in question comes from this comment.edit: filed a bug report: https://bugreports.qt.io/browse/QTBUG-77134