Frage

I want to detect middle mouse clicks on a QTabWidget. I was expecting there to be a mouse event related signal on QWidget, but all I am seeing are methods.

Do I need to subclass the QTabWidget and then override said methods in order to do what I want, or am I missing something?

War es hilfreich?

Lösung

You can either install an event filter on the QTabBar (returned by QTabWidget.tabBar()) to receive and handle press and release events, or subclass QTabBar to redefine mousePressEvent and mouseReleaseEvent and replace the QTabBar of the QTabWidget with QTabWidget.setTabBar().

  1. Example using the event filter:

    class MainWindow(QMainWindow):
        def __init__(self):
            super(QMainWindow,self).__init__()
            self.tabWidget = QTabWidget(self)
            self.setCentralWidget(self.tabWidget)
            self.tabWidget.tabBar().installEventFilter(self)
            self.tabWidget.tabBar().previousMiddleIndex = -1           
    
        def eventFilter(self, object, event):
            if object == self.tabWidget.tabBar() and \
                event.type() in [QEvent.MouseButtonPress, 
                                 QEvent.MouseButtonRelease] and \
                event.button() == Qt.MidButton: 
                tabIndex = object.tabAt(event.pos())
                if event.type() == QEvent.MouseButtonPress:
                    object.previousMiddleIndex = tabIndex
                else:   
                    if tabIndex != -1 and tabIndex == object.previousMiddleIndex:
                        self.onTabMiddleClick(tabIndex)                    
                    object.previousMiddleIndex = -1                        
                return True               
            return False
    
        # function called with the index of the clicked Tab
        def onTabMiddleClick(self, index):
            pass
    
  2. Example using a QTabBar subclass:

    class TabBar(QTabBar):
        middleClicked = pyqtSignal(int)
    
        def __init__(self):
            super(QTabBar, self).__init__()
            self.previousMiddleIndex = -1
    
        def mousePressEvent(self, mouseEvent):
            if mouseEvent.button() == Qt.MidButton:
                self.previousIndex = self.tabAt(mouseEvent.pos())
            QTabBar.mousePressEvent(self, mouseEvent)
    
        def mouseReleaseEvent(self, mouseEvent):
            if mouseEvent.button() == Qt.MidButton and \
                self.previousIndex == self.tabAt(mouseEvent.pos()):
                self.middleClicked.emit(self.previousIndex)
            self.previousIndex = -1
            QTabBar.mouseReleaseEvent(self, mouseEvent)
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super(QMainWindow,self).__init__()
            self.tabWidget = QTabWidget(self)
            self.setCentralWidget(self.tabWidget)
    
            self.tabBar = TabBar()
            self.tabWidget.setTabBar(self.tabBar)
            self.tabBar.middleClicked.connect(self.onTabMiddleClick)
    
        # function called with the index of the clicked Tab
        def onTabMiddleClick(self, index):
            pass
    

(In case you wonder why there is so much code for such a simple task, a click is defined as a press event followed by a release event at roughly the same spot, so the index of the pressed tab has to be the same as the released tab).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top