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. App crashing on dropevent in QtabWidget
QtWS25 Last Chance

App crashing on dropevent in QtabWidget

Scheduled Pinned Locked Moved Solved General and Desktop
drag and dropqtabwidgetmouseeventcrash appqt6.5
8 Posts 6 Posters 787 Views
  • 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.
  • N Offline
    N Offline
    Narutoblaze
    wrote on 1 Jul 2023, 17:42 last edited by Narutoblaze 7 Jan 2023, 17:43
    #1

    I am trying to drag tab from one QtabWidget to another QtabWidget i have implemented my code based on this python solution " https://forum.qt.io/topic/67542/drag-tabs-between-qtabwidgets/5 " everything is working as expected but my app is crashing when i drop my tab in QtabWidget, my app is crashing exactly inside dropEvent(QDropEvent) addTab() and insertTab() i have no idea what is causing this any help is appreciated.

    class CustomTab : public QTabWidget
    {
    public:
        CustomTab();
    
    protected:
        void mouseMoveEvent(QMouseEvent *e) override;
        void dragEnterEvent(QDragEnterEvent *e) override;
        void dragLeaveEvent(QDragLeaveEvent *e) override;
        void dropEvent(QDropEvent *e) override;
    };
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        QSplitter *splitter = new QSplitter;
        CustomTab *tab1 = new CustomTab;
        CustomTab *tab2 = new CustomTab;
    
        tab1->addTab(new QWidget(), "TAB ONE 1");
        tab1->addTab(new QWidget(), "TAB ONE 2");
    
        tab2->addTab(new QWidget(), "TAB TWO 1");
        tab2->addTab(new QWidget(), "TAB TWO 2");
    
        splitter->addWidget(tab1);
        splitter->addWidget(tab2);
    
        QGridLayout *gL = new QGridLayout;
        gL->addWidget(splitter);
    
        ui->centralwidget->setLayout(gL);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    // Custom Tab
    CustomTab::CustomTab()
    {
        setAcceptDrops(true);
        setMovable(true);
        setMouseTracking(true);
        setTabsClosable(true);
    
        tabBar()->setMouseTracking(true);
    }
    
    void CustomTab::mouseMoveEvent(QMouseEvent *e)
    {
        if (e->buttons() != Qt::RightButton)
            return;
    
        QPoint global_pos = mapToGlobal(e->pos());
        QTabBar *tabbar = tabBar();
    
        QPoint posInTab = tabbar->mapFromGlobal(global_pos);
    
        int indexTab = tabbar->tabAt(e->pos());
        QRect tabrect = tabbar->tabRect(indexTab);
    
        QPixmap pix = QPixmap(tabrect.size());
        tabbar->render(&pix, QPoint(), QRegion(tabrect));
        QMimeData mimedata = QMimeData();
    
        QDrag drag = QDrag(tabbar);
        drag.setMimeData(&mimedata);
        drag.setPixmap(pix);
    
        QCursor cursor = QCursor(Qt::OpenHandCursor);
        drag.setHotSpot(e->pos() - posInTab);
        drag.setDragCursor(cursor.pixmap(), Qt::MoveAction);
        drag.exec(Qt::MoveAction);
    }
    
    void CustomTab::dragEnterEvent(QDragEnterEvent *e)
    {
        e->accept();
        if (e->source()->parent() != this)
            return;
    }
    
    void CustomTab::dragLeaveEvent(QDragLeaveEvent *e)
    {
        e->accept();
    }
    
    void CustomTab::dropEvent(QDropEvent *e)
    {
        if (e->source()->parent() == this)
            return;
    
        e->setDropAction(Qt::MoveAction);
        e->accept();
        int counter = count();
    
        QTabWidget *parentWidget = qobject_cast<QTabWidget *>(e->source()->parent());
    
    // crashing from here :
        if (counter == 0) {
            addTab(parentWidget->currentWidget(), parentWidget->tabText(parentWidget->currentIndex()));
        } else {
            insertTab(counter + 1,
                      parentWidget->currentWidget(),
                      parentWidget->tabText(parentWidget->currentIndex()));
        }
    }
    
    C M J 3 Replies Last reply 1 Jul 2023, 17:49
    0
    • C Offline
      C Offline
      CPPUIX
      wrote on 1 Jul 2023, 22:05 last edited by CPPUIX 7 Jan 2023, 22:06
      #5

      Hi,

      I made an example based on the code you provided and ran it through a debugger, it crashed in qdrag.cpp, when it tried to delete your QDrag data after leaving mouseMoveEvent scope.

      I allocated QMimeData on the heap and it worked, I was able to drag and drop tabs.

      in mouseMoveEvent:
      QMimeData *mimedata = new QMimeData();

      See if this is it.

      1 Reply Last reply
      3
      • N Narutoblaze
        1 Jul 2023, 17:42

        I am trying to drag tab from one QtabWidget to another QtabWidget i have implemented my code based on this python solution " https://forum.qt.io/topic/67542/drag-tabs-between-qtabwidgets/5 " everything is working as expected but my app is crashing when i drop my tab in QtabWidget, my app is crashing exactly inside dropEvent(QDropEvent) addTab() and insertTab() i have no idea what is causing this any help is appreciated.

        class CustomTab : public QTabWidget
        {
        public:
            CustomTab();
        
        protected:
            void mouseMoveEvent(QMouseEvent *e) override;
            void dragEnterEvent(QDragEnterEvent *e) override;
            void dragLeaveEvent(QDragLeaveEvent *e) override;
            void dropEvent(QDropEvent *e) override;
        };
        
        MainWindow::MainWindow(QWidget *parent)
            : QMainWindow(parent)
            , ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
        
            QSplitter *splitter = new QSplitter;
            CustomTab *tab1 = new CustomTab;
            CustomTab *tab2 = new CustomTab;
        
            tab1->addTab(new QWidget(), "TAB ONE 1");
            tab1->addTab(new QWidget(), "TAB ONE 2");
        
            tab2->addTab(new QWidget(), "TAB TWO 1");
            tab2->addTab(new QWidget(), "TAB TWO 2");
        
            splitter->addWidget(tab1);
            splitter->addWidget(tab2);
        
            QGridLayout *gL = new QGridLayout;
            gL->addWidget(splitter);
        
            ui->centralwidget->setLayout(gL);
        }
        
        MainWindow::~MainWindow()
        {
            delete ui;
        }
        
        // Custom Tab
        CustomTab::CustomTab()
        {
            setAcceptDrops(true);
            setMovable(true);
            setMouseTracking(true);
            setTabsClosable(true);
        
            tabBar()->setMouseTracking(true);
        }
        
        void CustomTab::mouseMoveEvent(QMouseEvent *e)
        {
            if (e->buttons() != Qt::RightButton)
                return;
        
            QPoint global_pos = mapToGlobal(e->pos());
            QTabBar *tabbar = tabBar();
        
            QPoint posInTab = tabbar->mapFromGlobal(global_pos);
        
            int indexTab = tabbar->tabAt(e->pos());
            QRect tabrect = tabbar->tabRect(indexTab);
        
            QPixmap pix = QPixmap(tabrect.size());
            tabbar->render(&pix, QPoint(), QRegion(tabrect));
            QMimeData mimedata = QMimeData();
        
            QDrag drag = QDrag(tabbar);
            drag.setMimeData(&mimedata);
            drag.setPixmap(pix);
        
            QCursor cursor = QCursor(Qt::OpenHandCursor);
            drag.setHotSpot(e->pos() - posInTab);
            drag.setDragCursor(cursor.pixmap(), Qt::MoveAction);
            drag.exec(Qt::MoveAction);
        }
        
        void CustomTab::dragEnterEvent(QDragEnterEvent *e)
        {
            e->accept();
            if (e->source()->parent() != this)
                return;
        }
        
        void CustomTab::dragLeaveEvent(QDragLeaveEvent *e)
        {
            e->accept();
        }
        
        void CustomTab::dropEvent(QDropEvent *e)
        {
            if (e->source()->parent() == this)
                return;
        
            e->setDropAction(Qt::MoveAction);
            e->accept();
            int counter = count();
        
            QTabWidget *parentWidget = qobject_cast<QTabWidget *>(e->source()->parent());
        
        // crashing from here :
            if (counter == 0) {
                addTab(parentWidget->currentWidget(), parentWidget->tabText(parentWidget->currentIndex()));
            } else {
                insertTab(counter + 1,
                          parentWidget->currentWidget(),
                          parentWidget->tabText(parentWidget->currentIndex()));
            }
        }
        
        C Offline
        C Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on 1 Jul 2023, 17:49 last edited by
        #2

        @Narutoblaze said in App crashing on dropevent in QtabWidget:

        // crashing from here :

        Then you should look at the debugger to see what's wrong there. I would guess parentWidget is a nullptr.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        0
        • N Narutoblaze
          1 Jul 2023, 17:42

          I am trying to drag tab from one QtabWidget to another QtabWidget i have implemented my code based on this python solution " https://forum.qt.io/topic/67542/drag-tabs-between-qtabwidgets/5 " everything is working as expected but my app is crashing when i drop my tab in QtabWidget, my app is crashing exactly inside dropEvent(QDropEvent) addTab() and insertTab() i have no idea what is causing this any help is appreciated.

          class CustomTab : public QTabWidget
          {
          public:
              CustomTab();
          
          protected:
              void mouseMoveEvent(QMouseEvent *e) override;
              void dragEnterEvent(QDragEnterEvent *e) override;
              void dragLeaveEvent(QDragLeaveEvent *e) override;
              void dropEvent(QDropEvent *e) override;
          };
          
          MainWindow::MainWindow(QWidget *parent)
              : QMainWindow(parent)
              , ui(new Ui::MainWindow)
          {
              ui->setupUi(this);
          
              QSplitter *splitter = new QSplitter;
              CustomTab *tab1 = new CustomTab;
              CustomTab *tab2 = new CustomTab;
          
              tab1->addTab(new QWidget(), "TAB ONE 1");
              tab1->addTab(new QWidget(), "TAB ONE 2");
          
              tab2->addTab(new QWidget(), "TAB TWO 1");
              tab2->addTab(new QWidget(), "TAB TWO 2");
          
              splitter->addWidget(tab1);
              splitter->addWidget(tab2);
          
              QGridLayout *gL = new QGridLayout;
              gL->addWidget(splitter);
          
              ui->centralwidget->setLayout(gL);
          }
          
          MainWindow::~MainWindow()
          {
              delete ui;
          }
          
          // Custom Tab
          CustomTab::CustomTab()
          {
              setAcceptDrops(true);
              setMovable(true);
              setMouseTracking(true);
              setTabsClosable(true);
          
              tabBar()->setMouseTracking(true);
          }
          
          void CustomTab::mouseMoveEvent(QMouseEvent *e)
          {
              if (e->buttons() != Qt::RightButton)
                  return;
          
              QPoint global_pos = mapToGlobal(e->pos());
              QTabBar *tabbar = tabBar();
          
              QPoint posInTab = tabbar->mapFromGlobal(global_pos);
          
              int indexTab = tabbar->tabAt(e->pos());
              QRect tabrect = tabbar->tabRect(indexTab);
          
              QPixmap pix = QPixmap(tabrect.size());
              tabbar->render(&pix, QPoint(), QRegion(tabrect));
              QMimeData mimedata = QMimeData();
          
              QDrag drag = QDrag(tabbar);
              drag.setMimeData(&mimedata);
              drag.setPixmap(pix);
          
              QCursor cursor = QCursor(Qt::OpenHandCursor);
              drag.setHotSpot(e->pos() - posInTab);
              drag.setDragCursor(cursor.pixmap(), Qt::MoveAction);
              drag.exec(Qt::MoveAction);
          }
          
          void CustomTab::dragEnterEvent(QDragEnterEvent *e)
          {
              e->accept();
              if (e->source()->parent() != this)
                  return;
          }
          
          void CustomTab::dragLeaveEvent(QDragLeaveEvent *e)
          {
              e->accept();
          }
          
          void CustomTab::dropEvent(QDropEvent *e)
          {
              if (e->source()->parent() == this)
                  return;
          
              e->setDropAction(Qt::MoveAction);
              e->accept();
              int counter = count();
          
              QTabWidget *parentWidget = qobject_cast<QTabWidget *>(e->source()->parent());
          
          // crashing from here :
              if (counter == 0) {
                  addTab(parentWidget->currentWidget(), parentWidget->tabText(parentWidget->currentIndex()));
              } else {
                  insertTab(counter + 1,
                            parentWidget->currentWidget(),
                            parentWidget->tabText(parentWidget->currentIndex()));
              }
          }
          
          M Offline
          M Offline
          mpergand
          wrote on 1 Jul 2023, 18:03 last edited by
          #3

          @Narutoblaze said in App crashing on dropevent in QtabWidget:

          QTabWidget *parentWidget = qobject_cast<QTabWidget *>(e->source()->parent());

          parentWidget == null ?

          1 Reply Last reply
          0
          • N Offline
            N Offline
            Narutoblaze
            wrote on 1 Jul 2023, 21:24 last edited by Narutoblaze 7 Jan 2023, 21:27
            #4

            @Christian-Ehrlicher @mpergand I have debugged this portion of the code and found it is not null.

            qDebug() << parentWidget();
            qDebug() << parentWidget()->tabText(parentWidget()->currentIndex());
            

            I got the address of parentWidget & the text of the parentWidget "values received provided below"

            output :

            0xc00009e230
            TAB ONE 1
            
            1 Reply Last reply
            0
            • C Offline
              C Offline
              CPPUIX
              wrote on 1 Jul 2023, 22:05 last edited by CPPUIX 7 Jan 2023, 22:06
              #5

              Hi,

              I made an example based on the code you provided and ran it through a debugger, it crashed in qdrag.cpp, when it tried to delete your QDrag data after leaving mouseMoveEvent scope.

              I allocated QMimeData on the heap and it worked, I was able to drag and drop tabs.

              in mouseMoveEvent:
              QMimeData *mimedata = new QMimeData();

              See if this is it.

              1 Reply Last reply
              3
              • N Narutoblaze
                1 Jul 2023, 17:42

                I am trying to drag tab from one QtabWidget to another QtabWidget i have implemented my code based on this python solution " https://forum.qt.io/topic/67542/drag-tabs-between-qtabwidgets/5 " everything is working as expected but my app is crashing when i drop my tab in QtabWidget, my app is crashing exactly inside dropEvent(QDropEvent) addTab() and insertTab() i have no idea what is causing this any help is appreciated.

                class CustomTab : public QTabWidget
                {
                public:
                    CustomTab();
                
                protected:
                    void mouseMoveEvent(QMouseEvent *e) override;
                    void dragEnterEvent(QDragEnterEvent *e) override;
                    void dragLeaveEvent(QDragLeaveEvent *e) override;
                    void dropEvent(QDropEvent *e) override;
                };
                
                MainWindow::MainWindow(QWidget *parent)
                    : QMainWindow(parent)
                    , ui(new Ui::MainWindow)
                {
                    ui->setupUi(this);
                
                    QSplitter *splitter = new QSplitter;
                    CustomTab *tab1 = new CustomTab;
                    CustomTab *tab2 = new CustomTab;
                
                    tab1->addTab(new QWidget(), "TAB ONE 1");
                    tab1->addTab(new QWidget(), "TAB ONE 2");
                
                    tab2->addTab(new QWidget(), "TAB TWO 1");
                    tab2->addTab(new QWidget(), "TAB TWO 2");
                
                    splitter->addWidget(tab1);
                    splitter->addWidget(tab2);
                
                    QGridLayout *gL = new QGridLayout;
                    gL->addWidget(splitter);
                
                    ui->centralwidget->setLayout(gL);
                }
                
                MainWindow::~MainWindow()
                {
                    delete ui;
                }
                
                // Custom Tab
                CustomTab::CustomTab()
                {
                    setAcceptDrops(true);
                    setMovable(true);
                    setMouseTracking(true);
                    setTabsClosable(true);
                
                    tabBar()->setMouseTracking(true);
                }
                
                void CustomTab::mouseMoveEvent(QMouseEvent *e)
                {
                    if (e->buttons() != Qt::RightButton)
                        return;
                
                    QPoint global_pos = mapToGlobal(e->pos());
                    QTabBar *tabbar = tabBar();
                
                    QPoint posInTab = tabbar->mapFromGlobal(global_pos);
                
                    int indexTab = tabbar->tabAt(e->pos());
                    QRect tabrect = tabbar->tabRect(indexTab);
                
                    QPixmap pix = QPixmap(tabrect.size());
                    tabbar->render(&pix, QPoint(), QRegion(tabrect));
                    QMimeData mimedata = QMimeData();
                
                    QDrag drag = QDrag(tabbar);
                    drag.setMimeData(&mimedata);
                    drag.setPixmap(pix);
                
                    QCursor cursor = QCursor(Qt::OpenHandCursor);
                    drag.setHotSpot(e->pos() - posInTab);
                    drag.setDragCursor(cursor.pixmap(), Qt::MoveAction);
                    drag.exec(Qt::MoveAction);
                }
                
                void CustomTab::dragEnterEvent(QDragEnterEvent *e)
                {
                    e->accept();
                    if (e->source()->parent() != this)
                        return;
                }
                
                void CustomTab::dragLeaveEvent(QDragLeaveEvent *e)
                {
                    e->accept();
                }
                
                void CustomTab::dropEvent(QDropEvent *e)
                {
                    if (e->source()->parent() == this)
                        return;
                
                    e->setDropAction(Qt::MoveAction);
                    e->accept();
                    int counter = count();
                
                    QTabWidget *parentWidget = qobject_cast<QTabWidget *>(e->source()->parent());
                
                // crashing from here :
                    if (counter == 0) {
                        addTab(parentWidget->currentWidget(), parentWidget->tabText(parentWidget->currentIndex()));
                    } else {
                        insertTab(counter + 1,
                                  parentWidget->currentWidget(),
                                  parentWidget->tabText(parentWidget->currentIndex()));
                    }
                }
                
                J Offline
                J Offline
                JonB
                wrote on 2 Jul 2023, 07:03 last edited by
                #6

                @Narutoblaze said in App crashing on dropevent in QtabWidget:

                drag.setMimeData(&mimedata);

                void QDrag::setMimeData(QMimeData *data) states:

                Ownership of the data is transferred to the QDrag object.

                Whenever you read about a function taking "ownership" of a pointer that means Qt infrastructure will delete the object you passed when the now-parent object later gets destroyed. That can only be performed against an object allocated on the heap (new) not on the stack (local variable whose address you take with &, like your code).

                Consequently @Abderrahmene_Rayene's code will address this correctly by creating your QMimeData object on the heap. Do not delete it yourself once you have passed to setMimeData()!

                N 1 Reply Last reply 3 Jul 2023, 14:29
                2
                • J JonB
                  2 Jul 2023, 07:03

                  @Narutoblaze said in App crashing on dropevent in QtabWidget:

                  drag.setMimeData(&mimedata);

                  void QDrag::setMimeData(QMimeData *data) states:

                  Ownership of the data is transferred to the QDrag object.

                  Whenever you read about a function taking "ownership" of a pointer that means Qt infrastructure will delete the object you passed when the now-parent object later gets destroyed. That can only be performed against an object allocated on the heap (new) not on the stack (local variable whose address you take with &, like your code).

                  Consequently @Abderrahmene_Rayene's code will address this correctly by creating your QMimeData object on the heap. Do not delete it yourself once you have passed to setMimeData()!

                  N Offline
                  N Offline
                  Narutoblaze
                  wrote on 3 Jul 2023, 14:29 last edited by
                  #7

                  @JonB if i don't delete the mimedata created on heap it will cause memory leak right ?

                  jsulmJ 1 Reply Last reply 3 Jul 2023, 14:48
                  0
                  • N Narutoblaze
                    3 Jul 2023, 14:29

                    @JonB if i don't delete the mimedata created on heap it will cause memory leak right ?

                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on 3 Jul 2023, 14:48 last edited by
                    #8

                    @Narutoblaze Please read again what @JonB wrote. Especially what he copied from Qt documentation...

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • N Narutoblaze has marked this topic as solved on 3 Jul 2023, 16:38
                    • C CPPUIX referenced this topic on 19 Sept 2023, 07:36

                    3/8

                    1 Jul 2023, 18:03

                    5 unread
                    • Login

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