【问题标题】:PyQt mouse events for QTabWidgetQTabWidget 的 PyQt 鼠标事件
【发布时间】:2012-03-15 13:50:49
【问题描述】:

我想检测 QTabWidget 上的鼠标中键点击。我原以为 QWidget 上会有一个与鼠标事件相关的信号,但我看到的只是方法。

我是否需要继承 QTabWidget 然后重写上述方法才能做我想做的事,还是我遗漏了什么?

【问题讨论】:

    标签: python pyqt qtabwidget


    【解决方案1】:

    您可以在QTabBar 上安装事件过滤器(由QTabWidget.tabBar() 返回)以接收和处理按下和释放事件,或者子类QTabBar 以重新定义mousePressEventmouseReleaseEvent 并替换@987654327 @ 的QTabWidgetQTabWidget.setTabBar()

    1. 使用事件过滤器的示例:

      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. 使用 QTabBar 子类的示例:

      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
      

    (如果你想知道为什么这么简单的任务有这么多代码,点击被定义为按下事件,然后在大致相同的位置释放事件,所以按下标签的索引必须是与已发布的选项卡相同)。

    【讨论】:

    • +1 用于展示如何通过按下和释放实际复制点击信号。如果您没有使用新旧标签索引来确定点击是否有效,一般的做法也是使用新旧点的曼哈顿长度来确定其是否在可接受的范围内称为点击: riverbankcomputing.co.uk/static/Docs/PyQt4/html/…
    • 正是我所希望的那种答案。不知道事件过滤器。感谢您提供如此详细且解释清楚的回复。
    • @jdi:感谢您的提示!仍在弄清楚这里的事情是如何运作的。否则不会知道这样做。
    • if object == self.tabWidget.tabBar() ... 真的应该有括号吗?
    • @dmd 是的,应该。 tabBar() 是一个函数调用。
    猜你喜欢
    • 1970-01-01
    • 2011-07-25
    • 2015-10-12
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 2011-12-10
    相关资源
    最近更新 更多