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
Forum Updated to NodeBB v4.3 + New Features

App crashing on dropevent in QtabWidget

Scheduled Pinned Locked Moved Solved General and Desktop
drag and dropqtabwidgetmouseeventcrash appqt6.5
8 Posts 6 Posters 815 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.
  • 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 ?

                  J 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 ?

                    J Offline
                    J 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

                    4/8

                    1 Jul 2023, 21:24

                    • Login

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