当我
TAB
围绕带有标签和行编辑的表单时,我看不到 QLabel
获得任何焦点;焦点正确地传递到它旁边的行编辑,即到 QWidget
即 label.nextInFocusChain()
.
我最初想要的:在
QLineEdit.editingFinished
的插槽中,我想将焦点设置到下一个(按TAB顺序)行编辑。我做self.sender().nextInFocusChain().setFocus()
;而不是行编辑,它的标签,焦点链中的下一个,获得焦点。
调用
QLabel.setFocus()
时,焦点在标签本身;做另一个 TAB
将焦点设置到它之后的预期行编辑。为什么会这样?为什么焦点没有设置到它之后的小部件?为什么没有像 TAB
键那样设置焦点?
我检查了标签的焦点策略;他们
Qt.NoFocus
(默认)。我也把label的textInteractionFlags
设置成Qt.NoTextInteraction
也是白搭
将行编辑设置为标签的焦点代理可以满足我的要求,但我不认为这是正确的解决方案;或者我的理解有差距。
#!/usr/bin/env python3
import sys
from PySide2.QtWidgets import QApplication, QLineEdit, QWidget, \
QFormLayout, QPushButton, QMainWindow, QLabel
from PySide2.QtCore import Qt
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
txtName = QLineEdit('')
txtAge = QLineEdit('')
self.lblAge = QLabel('&Age')
self.lblAge.setBuddy(txtAge)
# This or (default) Qt.LinksAccessibleByMouse doesn't help.
# self.lblAge.setTextInteractionFlags(Qt.NoTextInteraction)
btnNext = QPushButton('N&ext')
btnNext.clicked.connect(self.moveFocus)
formLayout = QFormLayout()
formLayout.addRow('&Name', txtName)
formLayout.addRow(self.lblAge, txtAge)
formLayout.addRow(btnNext)
window = QWidget()
window.setLayout(formLayout)
self.setCentralWidget(window)
def moveFocus(self):
self.lblAge.setFocus()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
我在 ArchLinux 和 Xfce4 桌面环境上使用 Qt5 的官方 Python 绑定,即 PySide2。
widgets 的焦点策略只告诉 widget 在用户交互后是否接受焦点;事实上,文档说,例如,“小部件接受键盘焦点 by tabbing”或“by clicking”。
为伙伴设置标签时,并不意味着它可以获得焦点,也不意味着它是焦点链的一部分,也不会在它实际接收到它时(以编程方式或非编程方式)将焦点设置在该伙伴上:好友功能的唯一目的是在触发其快捷方式时将焦点设置在好友上。
显式调用
setFocus()
,尽管它的策略是 NoFocus
,但始终会使小部件获得焦点,那是因为调用已以 编程方式 完成,并且它没有从用户交互中获得焦点。另外,小部件必须能够在事件中接收焦点,即使它忽略它,这正是焦点代理的工作方式。
事实上,当用户交互(包括窗口激活)改变焦点时,Qt 根本不会调用
setFocus()
;相反,它将 QFocusEvent 发送到目标小部件,最终将传播到对象树中的父级。
不清楚您为什么要尝试根据标签设置焦点,但如果您真的需要这样做,那么您有以下选择:
setFocus()
;focusInEvent()
,并执行上述操作;使用子类方法,您甚至可以重写
mousePressEvent
处理程序,这样当用户单击标签时,它会自动将焦点设置在好友上。
同样可以通过将小部件设置为标签的焦点代理,然后将标签的焦点策略设置为
ClickFocus
.