我正在重写 QPlainTextEdit 以成为单行编辑小部件。换句话说,我希望它看起来像 QLineEdit,但具有 QPlainTextEdit 的扩展功能,例如文本格式设置等。
到目前为止,我唯一的麻烦是,当从 QPlainTextEdit 派生的小部件处于焦点状态时,我不知道如何将焦点传递到下一个/上一个小部件。我已经开始覆盖 keyPressEvent 来捕获 Tab 键被按下,但是然后呢?如何从小部件更改焦点?
我只能想到太复杂的解决方案(例如向家长发出信号,表明焦点应该改变,但这似乎是愚蠢的矫枉过正)。我打赌这个问题一定有一个非常简单的解决方案。
我接受了thuga的回答,这是最简单的方法。然而,我还发现了另一种对于没有 tabChangesFocus 属性的小部件来说可能更通用。像这样覆盖 keyPressEvent:
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Tab:
self.parent().focusNextChild()
elif event.key() == QtCore.Qt.Key_Backtab:
self.parent().focusPrevChild()
您可以尝试以下两件事:
QAction
并将其添加到小部件中。将 QShortcut
设置为带有 QKeySequence(Qt::Key_Tab)
的操作。将动作与改变焦点的插槽连接起来。或
new QShortcut(QKeySequence(Qt::Key_Tab), widgetPtr, SLOT(changeFocus()));
所以现在不需要继承您的控件来捕获 keyPressEvent。请注意,您可能需要更改快捷方式上下文才能最符合您的要求。
我可以为这个答案做得更好。
我发现我需要将
event.ignore()
添加到分支,以防止它 also 将 \t
注入文本区域,然后我发现这就是您所需要的 all。
def keyPressEvent(self, event: QtGui.QKeyEvent) -> None:
# Implement Tab completion stuff here
# [...]
# Fall back to tabChangesFocus (must be off in QPlainTextEdit props)
if event.key() == Qt.Key_Tab: # type: ignore[attr-defined]
event.ignore() # Prevent QPlainTextEdit from entering literal Tab
return
elif event.key() == Qt.Key_Backtab: # type: ignore[attr-defined]
event.ignore() # Prevent QPlainTextEdit from blocking Backtab
return
super().keyPressEvent(event)