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

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.
  • NarutoblazeN Offline
    NarutoblazeN Offline
    Narutoblaze
    wrote on 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();
    }
    
    JonBJ 1 Reply Last reply
    0
    • NarutoblazeN Narutoblaze

      @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 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
      • NarutoblazeN Narutoblaze

        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();
        }
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on 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()?

        NarutoblazeN 1 Reply Last reply
        0
        • JonBJ JonB

          @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()?

          NarutoblazeN Offline
          NarutoblazeN Offline
          Narutoblaze
          wrote on 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 Chris KawaC 2 Replies Last reply
          0
          • NarutoblazeN Narutoblaze

            @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 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.

            NarutoblazeN 1 Reply Last reply
            1
            • NarutoblazeN Narutoblaze

              @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.

              Chris KawaC Online
              Chris KawaC Online
              Chris Kawa
              Lifetime Qt Champion
              wrote on 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.

              NarutoblazeN 1 Reply Last reply
              1
              • Chris KawaC Chris Kawa

                @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.

                NarutoblazeN Offline
                NarutoblazeN Offline
                Narutoblaze
                wrote on 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 ??

                JonBJ 1 Reply Last reply
                0
                • NarutoblazeN Narutoblaze

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

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on 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
                  
                  NarutoblazeN 1 Reply Last reply
                  0
                  • M mpergand

                    @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.

                    NarutoblazeN Offline
                    NarutoblazeN Offline
                    Narutoblaze
                    wrote on 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
                    • JonBJ JonB

                      @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
                      
                      NarutoblazeN Offline
                      NarutoblazeN Offline
                      Narutoblaze
                      wrote on 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 JonBJ 3 Replies Last reply
                      0
                      • NarutoblazeN Narutoblaze

                        @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 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
                        • NarutoblazeN Narutoblaze

                          @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.

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on 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
                          • NarutoblazeN Narutoblaze

                            @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 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
                            • NarutoblazeN Narutoblaze has marked this topic as solved on

                            • Login

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