Currently I'm having trouble with the focus of tabified QDockWidgets. Working with this small example using two tabified QDockWidgets:
from PyQt5.QtWidgets import QApplication, QMainWindow, QDockWidget, QTextEdit
from PyQt5.Qt import Qt
app = QApplication( [] )
main = QMainWindow(None, Qt.Window)
main.show()
dock1 = QDockWidget( "D1", main )
dock1.setWidget( QTextEdit( dock1 ) )
main.addDockWidget( Qt.TopDockWidgetArea, dock1 )
dock2 = QDockWidget( "D2", main )
dock2.setWidget( QTextEdit( dock2 ) )
main.tabifyDockWidget( dock1, dock2 )
exit( app.exec() )
I experienced that the QTextEdits
are not losing focus when switching to an other tab of the tabified widgets.
The second text you were writen was still in focus of the first Widget.
So, in general:
Is there a way to lose the focus of the tabified widgets, regardless if it is a QTextEdit
or some other Widget(s) (maybe even with a complex child-layout structure)?
I tried clearFocus()
on the QDockWidget
, but this just seems to work if the QDockWidget itselfe is containing the focus (not it's child).
Using setFocus()
before also doesn't seems like a good option, because the widget (or it's childs) might doesn't contain the focus in every case. So it would be unappropriate to might steal it from some other widget.
I think the best anchors to react on would be:
QDockWidget::visibilityChanged(bool visible)
(if visible == False
)QMainWindow::tabifiedDockWidgetActivated(QDockWidget *dockWidget)
and if you would somehow locate the dynamicly create QTabBar:
QTabBar::currentChanged(int index)
("There has to be a better way ...")One quite simple way to do this is to check to see if the current focus widget is a descendant of a QDockWidget
whenever the tab changes, and then reset the focus if necessary:
from PyQt5.QtWidgets import QApplication, QMainWindow, QDockWidget, QTextEdit
from PyQt5.QtCore import Qt
class DockWidget(QDockWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setWidget(QTextEdit(self))
self.visibilityChanged.connect(self.updateFocus)
def updateFocus(self, visible):
if visible:
widget = QApplication.instance().focusWidget()
while widget is not None:
if isinstance(widget, QDockWidget):
widget = None
elif widget.parentWidget() is not None:
widget = widget.parentWidget()
else:
break
if widget is None:
self.setFocus()
self.focusNextChild()
app = QApplication([''])
main = QMainWindow()
main.setCentralWidget(QTextEdit(main))
dock1 = DockWidget("D1", main)
main.addDockWidget(Qt.TopDockWidgetArea, dock1)
dock2 = DockWidget("D2", main)
main.tabifyDockWidget(dock1, dock2)
main.show()
app.exec()