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

Drag tab between two QtabWidget

Scheduled Pinned Locked Moved Solved General and Desktop
qtabwidgetpyqt5qt6.5mouseeventdrag and drop
12 Posts 4 Posters 1.5k 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 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 Offline
          C Offline
          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

                        11/12

                        30 Jun 2023, 17:20

                        • Login

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