将焦点重置在列表化的停靠窗口小部件中

时间:2018-05-02 11:51:56

标签: python pyqt focus pyqt5 qdockwidget

目前我在使用表格化QDockWidgets时遇到了麻烦。 使用两个表格化的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() )

我发现切换到列表窗口小部件的其他标签时,QTextEdits并没有失去焦点。

  1. 在其中一个字段中写入文字
  2. 点击QTabBar上的其他标签
  3. 继续键盘输入
  4. 你写的第二个文字仍然是第一个Widget的焦点。

    所以,一般来说:
    有没有办法失去表格小部件的焦点,无论它是QTextEdit还是其他一些小部件(甚至可能是复杂的子布局结构)?

    我在QDockWidget上尝试clearFocus(),但是如果QDockWidget itselfe包含焦点(不是它的孩子),这似乎有用。
    之前使用setFocus()似乎也不是一个好的选择,因为小部件(或它的子节点)可能在每种情况下都不包含焦点。因此,从其他小部件中窃取它是不合适的。

    我认为最好的反应是:

    如果您以某种方式找到动态创建QTabBar:

1 个答案:

答案 0 :(得分:1)

一种非常简单的方法是在标签更改时检查当前focus widget是否为QDockWidget的后代,然后在必要时重置焦点:

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()