Re: QTabWidget tabBar refresh?

Matic Kukovec <[email protected]>
Newsgroups gmane.comp.python.pyqt-pykde
Message-ID <VI1PR01MB53448BEE720C116CD6D05B47D7310@VI1PR01MB5344.eurprd01.prod.exchangelabs.com>
From: Maurizio Berti <[email protected]>
Sent: Tuesday, May 7, 2019 7:37 PM
To: Matic Kukovec
Cc: [email protected]
Subject: Re: [PyQt] QTabWidget tabBar refresh?

Il giorno mar 7 mag 2019 alle ore 18:48 Matic Kukovec <[email protected]<mailto:[email protected]>> ha scritto:
Hi guys,

I have a QTabWidget that starts a QDrag when a tab is pressed and dragged outside
the bounds of the QTabWidget's tab bar.
That works great, but when the mouse button is released the tab doesn't jump-back into position
until there is a new mouse event on a non active tab and stays wherever the QDrag was initiated.

The default behavior should automatically do that, I assume that you're doing something else within your implementation (also, I remember you were playing around with QTabWidgets some weeks ago). If you can give us a minimal and complete example of your code, we could try and understand what's going on here.
Hey Mauricio,

Sure, here is my working example, as it is a bit more code.

Thanks again

_______________________________________________
PyQt mailing list    [email protected]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
tabs_test.py (text/plain, 5.4 KB)
import sys

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class TabBar(QTabBar):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setMouseTracking(True)
        self.tabMoved.connect(self.tab_moved)
    
    def start_tab_drag(self):
        self.parent().start_tab_drag()
    
    def tab_moved(self, index_from, index_to):
        if index_from == self.parent().indexTab:
            self.parent().indexTab = index_to
            print(index_from, index_to)
            
    
    def mousePressEvent(self, e):
        super().mousePressEvent(e)
        self.parent().store_drag_data(e)
        print("store")
    
    def enterEvent(self, e):
        super().enterEvent(e)
        print("enter")
    
    def leaveEvent(self, e):
        super().leaveEvent(e)
        print("leave")

class TabWidget(QTabWidget):
    move_range = None
    drag_lock = None
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setTabBar(TabBar())
        self.tabBar().installEventFilter(self)
        self.drag_lock = False
    
    def store_drag_data(self, e):
        globalPos = self.mapToGlobal(e.pos())
        tabBar = self.tabBar()
        self.posInTab = tabBar.mapFromGlobal(globalPos)
        self.indexTab = tabBar.tabAt(e.pos())
        self.tabRect = tabBar.tabRect(self.indexTab)
        self.pixmap = QPixmap(self.tabRect.size())
        tabBar.render(self.pixmap,QPoint(),QRegion(self.tabRect))
        painter = QPainter(self.pixmap)
        painter.setCompositionMode(painter.CompositionMode_DestinationIn)
        painter.fillRect(self.pixmap.rect(), QColor(0, 0, 0, 64))
        painter.end()
    
    def start_tab_drag(self):
        tabBar = self.tabBar()
#        tabBar.render(self.pixmap,QPoint(),QRegion(self.tabRect))
        mimeData = QMimeData()
        drag = QDrag(tabBar)
        drag.setMimeData(mimeData)
        drag.setPixmap(self.pixmap)
        cursor = QCursor(Qt.OpenHandCursor)
#        drag.setHotSpot(self.e.pos() - self.posInTab)
        drag.setHotSpot(QPoint(self.tabRect.width()/2, self.tabRect.height()/2))
        drag.setDragCursor(cursor.pixmap(),Qt.MoveAction)
        dropAction = drag.exec_(Qt.MoveAction)

    def eventFilter(self, source, event):
        if source == self.tabBar():
            if event.type() == QEvent.MouseButtonPress and event.buttons() == Qt.LeftButton:
                QTimer.singleShot(0, self.setmove_range)
            elif event.type() == QEvent.MouseButtonRelease:
                self.move_range = None
            elif event.type() == QEvent.MouseMove and self.move_range is not None:
#                if event.x() < self.move_range[0] or event.x() > self.tabBar().width() - self.move_range[1]:
#                    return True
                if event.x() < self.move_range[0]:
                    new_event = QMouseEvent(
                        QEvent.MouseMove,
                        QPoint(self.move_range[0], event.y()),
                        event.button(),
                        event.buttons(),
                        Qt.NoModifier,
                    )
                    QCoreApplication.sendEvent(self.tabBar(), new_event)
                    return True
                elif event.x() > self.tabBar().width() - self.move_range[1]:
                    new_event = QMouseEvent(
                        QEvent.MouseMove,
                        QPoint(self.tabBar().width() - self.move_range[1], event.y()),
                        event.button(),
                        event.buttons(),
                        Qt.NoModifier,
                    )
                    QCoreApplication.sendEvent(self.tabBar(), new_event)
                    return True
            elif event.type() == QEvent.HoverMove:
                pos = event.pos()
                if self.tabBar().rect().contains(pos):
                    self.drag_lock = False
                else:
                    buttons = app.mouseButtons()
                    if buttons == Qt.LeftButton:
                        if self.drag_lock == False:
                            self.drag_lock = True
                            self.start_tab_drag()
                            new_event = QMouseEvent(
                                QEvent.PolishRequest,
                                QPoint(self.tabBar().width()/2, self.tabBar().height()/2),
                                Qt.NoButton,
                                Qt.NoButton,
                                Qt.NoModifier,
                            )
                            QCoreApplication.sendEvent(self.tabBar(), new_event)
                    else:
                        self.drag_lock = False
        return QTabWidget.eventFilter(self, source, event)

    def setmove_range(self):
        tabRect = self.tabBar().tabRect(self.currentIndex())
        pos = self.tabBar().mapFromGlobal(QCursor.pos())
        self.move_range = pos.x() - tabRect.left(), tabRect.right() - pos.x()

class Window(QWidget):
    def __init__(self):

        super().__init__()
        tabWidgetOne = TabWidget(self)
        tabWidgetOne.setMovable(True)
        tabWidgetOne.addTab(QWidget(tabWidgetOne), 'Tab One')
        tabWidgetOne.addTab(QWidget(tabWidgetOne), 'Tab Two')
        layout = QHBoxLayout()
        layout.addWidget(tabWidgetOne)
        self.setLayout(layout)

if __name__ == '__main__':

    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.