Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
6.5.3
-
None
Description
When deleting the modal parent of a modal dialog, the grandparent window position is pushed backwards.
In the below example I have created a single QDialog called mainwindow, which is the parent of another QDialog called ABParent. The dialog ABParent is the modal parent of two more modal dialogs called A and B.
When calling `deleteLater` in the following order,
- `B`
- `ABParent`
- `A`
The grandparent of B (mainwindow) will be pushed behind the last focused application on the OS. Because I am launching my code using Visual Studio, this will be the console window. However, when the order is changed so that all children are called with `deleteLater` and then the modal parent `ABParent`, the grandparent window position is unchanged and in front of the console window.
This was discovered in our PyQt6 environment with our use case being multiple alert dialogs appearing from the parent modal dialog, with the option of these alert dialogs deleting the parent. This causes the main application to change the window positioning, giving the user the appearance of the application minimizing.
The minimal reproducible code is below,
— CMake —
cmake_minimum_required(VERSION 3.30) project(QtBug) set(CMAKE_AUTOMOC ON) find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) qt_add_executable(QtBug main.cpp) target_include_directories(QtBug PRIVATE ${CMAKE_CURRENT_LIST_DIR}/include) target_link_libraries(QtBug PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets)
— C++ (main.cpp)---
#include <QApplication> #include <QDialog> #include <QLabel> #include <QPushButton> #include <QVBoxLayout> #include <iostream> #include "main.h" #include "moc_main.cpp" DialogB::DialogB(QWidget *parent) : QDialog(parent) { setWindowTitle("Dialog B"); setLayout(new QVBoxLayout()); QPushButton *closeButton = new QPushButton("Close", this); layout()->addWidget(closeButton); setWindowModality(Qt::ApplicationModal); connect(closeButton, &QPushButton::clicked, this, &DialogB::close_dialog); } void DialogB::close_dialog() { std::cout << "Deleting B" << std::endl; deleteLater(); // Delete B ABParent *parentDialog = qobject_cast<ABParent *>(parent()); if (parentDialog) { std::cout << "Deleting parent " << parentDialog->objectName().toStdString() << std::endl; parentDialog->deleteLater(); // Delete the Modal parent std::cout << "Deleting A" << std::endl; parentDialog->dialogA->deleteLater(); // Delete dialog A } } ABParent::ABParent(QWidget *parent) : QDialog(parent) { setWindowTitle("AB Parent"); setObjectName("AB Parent"); setWindowModality(Qt::ApplicationModal); dialogA = new QDialog(this); dialogB = new DialogB(this); dialogA->setWindowTitle("Dialog A"); dialogA->setWindowModality(Qt::ApplicationModal); dialogA->show(); dialogB->show(); } int main(int argc, char *argv[]) { QApplication app(argc, argv); QDialog *mainwindow = new QDialog(); mainwindow->setWindowTitle("Main Window"); mainwindow->show(); ABParent *abparent = new ABParent(mainwindow); abparent->show(); int result = app.exec(); delete mainwindow; delete abparent; return result; }
— Header File (main.h) —
#pragma once #include <QDialog> class DialogB; class ABParent : public QDialog { Q_OBJECT public: QDialog *dialogA; DialogB *dialogB; ABParent(QWidget *parent = nullptr); }; class DialogB : public QDialog { Q_OBJECT public: DialogB(QWidget *parent = nullptr); public slots: void close_dialog(); };
Attachments
Issue Links
- relates to
-
QTBUG-84208 window is sent to back of all other windows in the OS if its child dialog which has another child dialog is deleted
-
- Reported
-