Drag tab between two QtabWidget
-
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(); }
-
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 }
-
@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()
? -
@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.
-
@Narutoblaze
source()
returns a pointer to QObject. QObject has aparent()
method and QWidget also has aparentWidget()
method. You can cast that pointer to QWidget pointer if you need to, but here you just want to compare addresses, so usingparent()
is enough. In case of widgets parent and parent widget are (usually) the same thing. -
@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 ??
-
@Narutoblaze
WhereQObject
will do just usee->source()->parent()
.If you do need a
QWidget
viaparentWidget()
:QWidget *parentWidget = qobject_cast<QWidget *>(parent()); Q_ASSERT(parentWidget); // Now `parentWidget` is indeed a `QWidget*` pointing to a widget, use as per Python code
-
@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 foundand few more.
-
@Narutoblaze said in Drag tab between two QtabWidget:
e.source().tabText() not found
parent.TABINDEX not foundtabText() is a method of QTabWidget
TABINDEX is a variable defined in the custom Window python class -
@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. -
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 }
-