Search code examples
pythonpyqtpyqt4qmainwindowqdockwidget

Notification when QDockWidget's tab is clicked?


I need to execute a block of code when the user clicks on the tab of a tabbified QDockWidget. So far I've been doing this via a hack using the "visibilityChanged" event but this is now causing issues (for example, if I have several tabbified dock widgets and I drag one out so that it is floating, the tabbified one underneath will fire its "visibilityChanged" event which I will mistakenly interpret as the user clicking the tab). How can I receive proper notification when a user clicks on a QDockWidgets' tab? I've experimented with the "focusInEvent" of QDockWidget but it doesn't seem to fire when the tab is clicked.


Solution

  • When you use tabifyDockWidget() method QMainWindow creates a QTabBar, this is not directly accessible but using findChild() you can get it, and then use the tabBarClicked signal

    from PyQt4 import QtCore, QtGui
    
    class MainWindow(QtGui.QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            first_dock = None
    
            for i in range(10):
                dock = QtGui.QDockWidget("title {}".format(i), self)
                dock.setWidget(QtGui.QTextEdit()) # testing
                self.addDockWidget(QtCore.Qt.TopDockWidgetArea, dock)
                if first_dock:
                    self.tabifyDockWidget(first_dock, dock)
                else:
                    first_dock = dock
                    dock.raise_()
    
            tabbar = self.findChild(QtGui.QTabBar, "")
            tabbar.tabBarClicked.connect(self.onTabBarClicked)
    
        def onTabBarClicked(self, index):
            tabbar = self.sender()
            text = tabbar.tabText(index)
            print("index={}, text={}".format(index, text))
    
    if __name__ == '__main__':
        import sys
    
        app = QtGui.QApplication(sys.argv)
        w = MainWindow()
        w.show()
        sys.exit(app.exec_())