2012-02-25 122 views
4

我想检测QTabWidget上的鼠标中点击。我期待在QWidget上有一个与鼠标事件相关的信号,但我所看到的只是方法。用于QTabWidget的PyQt鼠标事件

我是否需要子类化QTabWidget,然后重写所说的方法才能做我想做的事情,还是我错过了什么?

回答

7

您可以安装在QTabBar事件过滤器(由QTabWidget.tabBar()返回)来接收和处理按下和释放事件,或子类QTabBar重新定义mousePressEventmouseReleaseEventQTabWidget.setTabBar()更换QTabWidgetQTabBar。使用事件过滤器

  1. 示例:使用QTabBar子

    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. 例子:

    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 
    

(如果你想知道为什么有这么多的代码,例如一个简单的任务,点击被定义为新闻事件,然后在大致相同的地点发布事件,所以新闻的索引d选项卡必须与发布的选项卡相同)。

+0

+1显示如何实际复制按下和释放点击信号。如果您没有使用新旧标签索引来确定点击是否有效,那么一般方法也是使用旧点和新点的一半长度来确定它是否在一个可接受的范围内,将其称为点击: http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qpoint.html#manhattanLength – jdi 2012-02-25 17:36:42

+0

正是我期待的那种答案。没有意识到事件过滤器。感谢您提供这样详细而且解释清楚的回复。 – Mathieson 2012-02-25 22:00:21

+0

@Mathieson:如果你喜欢,你应该接受他的答案。 – jdi 2012-02-29 02:43:14