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. Drag tab between two QtabWidget
QtWS25 Last Chance

Drag tab between two QtabWidget

Scheduled Pinned Locked Moved Solved General and Desktop
qtabwidgetpyqt5qt6.5mouseeventdrag and drop
12 Posts 4 Posters 1.3k 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 28 Jun 2023, 15:03 last edited by
    #1

    I am trying to drag a tab from one QtabWidget to another QtabWidget i am implementing it in c++ and copied from this solution "https://forum.qt.io/topic/67542/drag-tabs-between-qtabwidgets/5" which is in python and the problem i am facing is i can't find same function that is used in the python solution example this e.source().parentWidget() function does not exist i am using qt6.5 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;
    };
    
    CustomTab::CustomTab()
    {
        setAcceptDrops(true);
        setMovable(true);
        setMouseTracking(true);
    
        addTab(new QWidget(), "TAB ONE");
    }
    
    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;
    
        indexOf(this->widget(this->currentIndex()));
    }
    
    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();
    }
    
    J 1 Reply Last reply 28 Jun 2023, 16:38
    0
    • N Narutoblaze
      30 Jun 2023, 16:31

      @JonB this only solves for one function
      what about others why c++ does not have similar function ? self.addTab(e.source().parentWidget().widget(self.parent.TABINDEX),e.source().tabText(self.parent.TABINDEX))

      e.source().tabText() not found
      parent.TABINDEX not found

      and few more.

      M Offline
      M Offline
      mpergand
      wrote on 30 Jun 2023, 17:32 last edited by mpergand
      #12

      AS @JonB said,
      Python is a dynamic language, C++ is not.
      So, you need to make an explicit cast to retreive the type of object you want.
      If you expect e->source() to return a QTabWidget, you need to do:

      QTabWidget* tabWidget=qobject_cast<QTabWidget*>(e->source());
      if(tabWidget)  // is a tab widget ?
      (
      // indeed it is
      )
      else
      {
      // is not
      }
      
      1 Reply Last reply
      0
      • N Narutoblaze
        28 Jun 2023, 15:03

        I am trying to drag a tab from one QtabWidget to another QtabWidget i am implementing it in c++ and copied from this solution "https://forum.qt.io/topic/67542/drag-tabs-between-qtabwidgets/5" which is in python and the problem i am facing is i can't find same function that is used in the python solution example this e.source().parentWidget() function does not exist i am using qt6.5 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;
        };
        
        CustomTab::CustomTab()
        {
            setAcceptDrops(true);
            setMovable(true);
            setMouseTracking(true);
        
            addTab(new QWidget(), "TAB ONE");
        }
        
        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;
        
            indexOf(this->widget(this->currentIndex()));
        }
        
        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();
        }
        
        J Offline
        J Offline
        JonB
        wrote on 28 Jun 2023, 16:38 last edited by JonB
        #2

        @Narutoblaze said in Drag tab between two QtabWidget:

        e.source().parentWidget()

        I see 4 occurrences of this in the Python code. Which are you talking about? Where in your C++ code is parentWidget()?

        N 1 Reply Last reply 28 Jun 2023, 19:06
        0
        • J JonB
          28 Jun 2023, 16:38

          @Narutoblaze said in Drag tab between two QtabWidget:

          e.source().parentWidget()

          I see 4 occurrences of this in the Python code. Which are you talking about? Where in your C++ code is parentWidget()?

          N Offline
          N Offline
          Narutoblaze
          wrote on 28 Jun 2023, 19:06 last edited by
          #3

          @JonB this function does not exist in c++ i have also looked in doc this e->source()->parent() exist but e->source()->parentWidget() does not.

          M C 2 Replies Last reply 28 Jun 2023, 19:23
          0
          • N Narutoblaze
            28 Jun 2023, 19:06

            @JonB this function does not exist in c++ i have also looked in doc this e->source()->parent() exist but e->source()->parentWidget() does not.

            M Offline
            M Offline
            mpergand
            wrote on 28 Jun 2023, 19:23 last edited by mpergand
            #4

            @Narutoblaze

            @Narutoblaze said in Drag tab between two QtabWidget:

            if (e->source()->parent() == this)
            return;

            It shouldn't make any difference since you are comparing pointer addresses.

            N 1 Reply Last reply 30 Jun 2023, 15:45
            1
            • N Narutoblaze
              28 Jun 2023, 19:06

              @JonB this function does not exist in c++ i have also looked in doc this e->source()->parent() exist but e->source()->parentWidget() does not.

              C Online
              C Online
              Chris Kawa
              Lifetime Qt Champion
              wrote on 28 Jun 2023, 19:24 last edited by Chris Kawa
              #5

              @Narutoblaze source() returns a pointer to QObject. QObject has a parent() method and QWidget also has a parentWidget() method. You can cast that pointer to QWidget pointer if you need to, but here you just want to compare addresses, so using parent() is enough. In case of widgets parent and parent widget are (usually) the same thing.

              N 1 Reply Last reply 30 Jun 2023, 13:57
              1
              • C Chris Kawa
                28 Jun 2023, 19:24

                @Narutoblaze source() returns a pointer to QObject. QObject has a parent() method and QWidget also has a parentWidget() method. You can cast that pointer to QWidget pointer if you need to, but here you just want to compare addresses, so using parent() is enough. In case of widgets parent and parent widget are (usually) the same thing.

                N Offline
                N Offline
                Narutoblaze
                wrote on 30 Jun 2023, 13:57 last edited by
                #6

                @Chris-Kawa so what function do i use, how can i make c++ equivalent of this python code when smiller function does not exist.

                inside *dropevent (QDropEvent e) function i need e->source()->parentWidget() e->source()->parentWidget().widget() e->source()->TABINDEX etc but in c++ there is no function like this so i can i transform those python code to c++ ?? is there alternative function that i can use ??

                J 1 Reply Last reply 30 Jun 2023, 14:06
                0
                • N Narutoblaze
                  30 Jun 2023, 13:57

                  @Chris-Kawa so what function do i use, how can i make c++ equivalent of this python code when smiller function does not exist.

                  inside *dropevent (QDropEvent e) function i need e->source()->parentWidget() e->source()->parentWidget().widget() e->source()->TABINDEX etc but in c++ there is no function like this so i can i transform those python code to c++ ?? is there alternative function that i can use ??

                  J Offline
                  J Offline
                  JonB
                  wrote on 30 Jun 2023, 14:06 last edited by JonB
                  #7

                  @Narutoblaze
                  Where QObject will do just use e->source()->parent().

                  If you do need a QWidget via parentWidget():

                  QWidget *parentWidget = qobject_cast<QWidget *>(parent());
                  Q_ASSERT(parentWidget);
                  // Now `parentWidget` is indeed a `QWidget*` pointing to a widget, use as per Python code
                  
                  N 1 Reply Last reply 30 Jun 2023, 16:31
                  0
                  • M mpergand
                    28 Jun 2023, 19:23

                    @Narutoblaze

                    @Narutoblaze said in Drag tab between two QtabWidget:

                    if (e->source()->parent() == this)
                    return;

                    It shouldn't make any difference since you are comparing pointer addresses.

                    N Offline
                    N Offline
                    Narutoblaze
                    wrote on 30 Jun 2023, 15:45 last edited by
                    #8

                    @mpergand what about other function that does not exist function used on the python code does not exist in c++ problem is not about some pointer !

                    1 Reply Last reply
                    0
                    • J JonB
                      30 Jun 2023, 14:06

                      @Narutoblaze
                      Where QObject will do just use e->source()->parent().

                      If you do need a QWidget via parentWidget():

                      QWidget *parentWidget = qobject_cast<QWidget *>(parent());
                      Q_ASSERT(parentWidget);
                      // Now `parentWidget` is indeed a `QWidget*` pointing to a widget, use as per Python code
                      
                      N Offline
                      N Offline
                      Narutoblaze
                      wrote on 30 Jun 2023, 16:31 last edited by
                      #9

                      @JonB this only solves for one function
                      what about others why c++ does not have similar function ? self.addTab(e.source().parentWidget().widget(self.parent.TABINDEX),e.source().tabText(self.parent.TABINDEX))

                      e.source().tabText() not found
                      parent.TABINDEX not found

                      and few more.

                      M J 3 Replies Last reply 30 Jun 2023, 16:43
                      0
                      • N Narutoblaze
                        30 Jun 2023, 16:31

                        @JonB this only solves for one function
                        what about others why c++ does not have similar function ? self.addTab(e.source().parentWidget().widget(self.parent.TABINDEX),e.source().tabText(self.parent.TABINDEX))

                        e.source().tabText() not found
                        parent.TABINDEX not found

                        and few more.

                        M Offline
                        M Offline
                        mpergand
                        wrote on 30 Jun 2023, 16:43 last edited by mpergand
                        #10

                        @Narutoblaze said in Drag tab between two QtabWidget:

                        e.source().tabText() not found
                        parent.TABINDEX not found

                        tabText() is a method of QTabWidget
                        TABINDEX is a variable defined in the custom Window python class

                        1 Reply Last reply
                        1
                        • N Narutoblaze
                          30 Jun 2023, 16:31

                          @JonB this only solves for one function
                          what about others why c++ does not have similar function ? self.addTab(e.source().parentWidget().widget(self.parent.TABINDEX),e.source().tabText(self.parent.TABINDEX))

                          e.source().tabText() not found
                          parent.TABINDEX not found

                          and few more.

                          J Offline
                          J Offline
                          JonB
                          wrote on 30 Jun 2023, 17:20 last edited by
                          #11

                          @Narutoblaze said in Drag tab between two QtabWidget:

                          what about others why c++ does not have similar function ?

                          Because Python allows you to write code to call any function you like on any object, and if the object is of the right type it works and if not it generates a runtime error. C++ requires you have the right class at compile-time before you can call a method, e.g. qobject_cast, dynamic_cast, static_cast etc.

                          1 Reply Last reply
                          1
                          • N Narutoblaze
                            30 Jun 2023, 16:31

                            @JonB this only solves for one function
                            what about others why c++ does not have similar function ? self.addTab(e.source().parentWidget().widget(self.parent.TABINDEX),e.source().tabText(self.parent.TABINDEX))

                            e.source().tabText() not found
                            parent.TABINDEX not found

                            and few more.

                            M Offline
                            M Offline
                            mpergand
                            wrote on 30 Jun 2023, 17:32 last edited by mpergand
                            #12

                            AS @JonB said,
                            Python is a dynamic language, C++ is not.
                            So, you need to make an explicit cast to retreive the type of object you want.
                            If you expect e->source() to return a QTabWidget, you need to do:

                            QTabWidget* tabWidget=qobject_cast<QTabWidget*>(e->source());
                            if(tabWidget)  // is a tab widget ?
                            (
                            // indeed it is
                            )
                            else
                            {
                            // is not
                            }
                            
                            1 Reply Last reply
                            0
                            • N Narutoblaze has marked this topic as solved on 1 Jul 2023, 17:33

                            10/12

                            30 Jun 2023, 16:43

                            • Login

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