Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Changing dialog's parent disables drag and drop
Qt 6.11 is out! See what's new in the release blog

Changing dialog's parent disables drag and drop

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 2 Posters 1.3k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Dan Princ
    wrote on last edited by
    #1

    I have a main window and a dialog that is opened from this window on a button click. For performance reasons, there is a dialog cache, that keeps an instance of the dialog and only shows it when the dialog should be opened instead of creating new instance. In the dialog, there's a QListWidget with some items which order can be changed by drag and drop. This works when I first open the dialog, but when I close it and open it again, I'm unable to drop the items, I get a Qt::ForbiddenCursor.

    The issue seems to be caused by calling setParent(nullptr) when closing the dialog (or likely by just changing the parent). If I remove this line, drag and drop works. However I need this to prevent the dialog from being deleted by the parent and also the dialog can have different parents in different contexts (this isn't obvious from my simplified example). Any idea what is wrong with this approach? My Qt version is 5.9.3. Can this be a Qt bug?

    MainWindow.h:

    #include "ui_mainwindow.h"
    #include "dialog.h"
    
    #include <QPushButton>
    #include <QMainWindow>
    #include <memory>
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget* parent = nullptr) : QMainWindow(parent), ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
    
            dialog.reset(new Dialog(this));
            dialog->setAttribute(Qt::WA_DeleteOnClose, false);
    
            connect(ui->button, &QPushButton::pressed, [&]
            {
                dialog->setParent(this, dialog->windowFlags());
                dialog->open();
            });
        }
    
        ~MainWindow()
        {
            delete ui;
        }
    
    private:
        Ui::MainWindow* ui;
        std::unique_ptr<Dialog> dialog;
    };
    

    Dialog.h:

    #include "ui_dialog.h"
    #include <QDialog>
    
    class Dialog : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit Dialog(QWidget* parent) : QDialog(parent), ui(new Ui::Dialog)
        {
            ui->setupUi(this);
    
            ui->listWidget->addItem("first");
            ui->listWidget->addItem("second");
            ui->listWidget->addItem("third");
        }
    
        ~Dialog()
        {
            delete ui;
        }
    
    public slots:
        virtual void reject() override
        {
            setParent(nullptr);
            QDialog::reject();
        }
    
    private:
        Ui::Dialog* ui;
    };
    

    Dialog.ui - simple dialog with QListWidget and reject button

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Dialog</class>
     <widget class="QDialog" name="Dialog">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>548</width>
        <height>397</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>Dialog</string>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout">
       <item>
        <widget class="QListWidget" name="listWidget">
         <property name="dragDropMode">
          <enum>QAbstractItemView::DragDrop</enum>
         </property>
         <property name="defaultDropAction">
          <enum>Qt::MoveAction</enum>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QDialogButtonBox" name="buttonBox">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
         <property name="standardButtons">
          <set>QDialogButtonBox::Close</set>
         </property>
        </widget>
       </item>
      </layout>
     </widget>
     <resources/>
     <connections>
      <connection>
       <sender>buttonBox</sender>
       <signal>accepted()</signal>
       <receiver>Dialog</receiver>
       <slot>accept()</slot>
       <hints>
        <hint type="sourcelabel">
         <x>248</x>
         <y>254</y>
        </hint>
        <hint type="destinationlabel">
         <x>157</x>
         <y>274</y>
        </hint>
       </hints>
      </connection>
      <connection>
       <sender>buttonBox</sender>
       <signal>rejected()</signal>
       <receiver>Dialog</receiver>
       <slot>reject()</slot>
       <hints>
        <hint type="sourcelabel">
         <x>316</x>
         <y>260</y>
        </hint>
        <hint type="destinationlabel">
         <x>286</x>
         <y>274</y>
        </hint>
       </hints>
      </connection>
     </connections>
    </ui>
    

    MainWindow.ui - default main window with one button

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>432</width>
        <height>316</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralWidget">
       <widget class="QPushButton" name="button">
        <property name="geometry">
         <rect>
          <x>40</x>
          <y>30</y>
          <width>80</width>
          <height>21</height>
         </rect>
        </property>
        <property name="text">
         <string>PushButton</string>
        </property>
       </widget>
      </widget>
      <widget class="QMenuBar" name="menuBar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>432</width>
         <height>20</height>
        </rect>
       </property>
      </widget>
      <widget class="QToolBar" name="mainToolBar">
       <attribute name="toolBarArea">
        <enum>TopToolBarArea</enum>
       </attribute>
       <attribute name="toolBarBreak">
        <bool>false</bool>
       </attribute>
      </widget>
      <widget class="QStatusBar" name="statusBar"/>
     </widget>
     <layoutdefault spacing="6" margin="11"/>
     <resources/>
     <connections/>
    </ui>
    

    main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Why do you need that widget not to be delete with MainWindow's own destruction ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • D Offline
        D Offline
        Dan Princ
        wrote on last edited by
        #3

        Hi,
        in my real code, parent is not necessarily the main window, it can be some other window. I just tried to create a minimal example that reproduces the bug...

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          How are you passing that dialog around ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          D 1 Reply Last reply
          0
          • SGaistS SGaist

            How are you passing that dialog around ?

            D Offline
            D Offline
            Dan Princ
            wrote on last edited by
            #5

            @SGaist There are more cases... It can be another dialog from the cache as well as just some dialog that is created by new and later deleted. Sometimes parent is the main window as well... This really depends on the context where the dialog is opened.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Do you have the same effect if you don't set the window flags when setting the parent ?

              Note that this is still a bit strange to have a dialog moving from objects to objects like that.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              D 1 Reply Last reply
              0
              • SGaistS SGaist

                Do you have the same effect if you don't set the window flags when setting the parent ?

                Note that this is still a bit strange to have a dialog moving from objects to objects like that.

                D Offline
                D Offline
                Dan Princ
                wrote on last edited by
                #7

                @SGaist Yea, I know it's not the most standard solution... But apart from this bug it seems to work well.
                In this sample code, if you remove the flags, the dialog will not show up. For my real code, I'm gonna have to test that tomorrow as I'm on a device where I don't have it right now.

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  Dan Princ
                  wrote on last edited by
                  #8

                  OK, so I've reported it as Qt bug with a much simpler example. Also, there is a link to a workaround in the bug.

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    Thanks !

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved