I have multiple tabs that a user can switch between. I need a widget on a given tab to run an exit function when that tab is no longer selected. For example, if the user currently has tab_1 selected, when they switch to tab_2, tab_1 should run some exit function. Is there an event that gets called when a tab looses focus?
I can run functions when a tab is selected using QTabWidget.currentChanged. I could use a variable to keep track of the previously selected tab and select the required exit function using this but that feels clunky.
Keeping track of the "previous" tab index is the only way.
In fact, that's exactly what QTabWidget (or, to be precise, its QTabBar) does: it maintains an internal "current index" property and eventually changes it if the requested one is different, then emits the currentChanged
signal.
Since there is no way to access the previous index right before the new one is actually changed, you then need to store it on your own.
One possibility could involve a custom signal that emits the previous index, which you can then connect to a function that eventually calls the required function.
class CustomTabWidget(QTabWidget):
_prevIndex = -1
previousIndexChanged = pyqtSignal(int)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.currentIndexChanged.connect(self.emitPrevIndex)
def emitPrevIndex(self, index):
if self._prevIndex != index:
old = self._prevIndex
self._prevIndex = index
self.previousIndexChanged.emit(old)
def callExitFunction(index):
widget = tabWidget.widget(index)
if widget is not None:
# call the exit function related to that widget
tabWidget.previousIndexChanged.connect(callExitFunction)
You need to be careful and aware about some important aspects, though; specifically:
insertTab()
instead of addTab()
) at runtime;For all of the above, the _prevIndex
attribute may probably become inappropriate or even unused, unless you take proper precautions considering what follows:
_prevIndex
won't correspond to the current anymore;currentChanged
would be emitted even though no exit function should be called;_prevIndex
will be off by one position;currentChanged
will also be emitted, trying to call the exit function either on a wrong widget, or a non existent one (if the current is the last);If you really need runtime/dynamic tab movement/deletion/insertion, you should consider further precautions, possibly adding proper updates to the _prevIndex
attribute, and verifying widget existence/index.