Qt 确定在按下按钮之前具有最后一个焦点的QWidget

Qt 确定在按下按钮之前具有最后一个焦点的QWidget,qt,focus,qdialog,Qt,Focus,Qdialog,我想在我的Qt应用程序中实现以下功能: 用户打开一个或多个“输入”小部件(一个InputWidget类的实例),每个小部件都包含一个QLineEdit小部件 用户打开“助手”对话框 用户在“帮助器”对话框中选择一个值 用户按下“助手”对话框中的“插入”按钮 从“助手”对话框中选择的值被插入到“输入”对话框的QLineEdit,该对话框在按下“插入”按钮之前具有最后一个焦点 因此,基本上,我想要的是,如果用户在下面的屏幕截图中单击“插入”,字符串“Apple”应该出现在聚焦输入对话框中。下面的

我想在我的Qt应用程序中实现以下功能:

  • 用户打开一个或多个“输入”小部件(一个
    InputWidget
    类的实例),每个小部件都包含一个
    QLineEdit
    小部件
  • 用户打开“助手”对话框
  • 用户在“帮助器”对话框中选择一个值
  • 用户按下“助手”对话框中的“插入”按钮
  • 从“助手”对话框中选择的值被插入到“输入”对话框的
    QLineEdit
    ,该对话框在按下“插入”按钮之前具有最后一个焦点
因此,基本上,我想要的是,如果用户在下面的屏幕截图中单击“插入”,字符串“Apple”应该出现在聚焦输入对话框中。下面的代码示例做了一些工作,只是字符串(通常,请参见下文)插入到了第二个字符串中

以下是创建此设置的代码示例:

从PyQt5.qtwidts导入(QApplication、QWidget、QHBoxLayout、,
QLineEdit、QLabel、QPushButton、QComboBox)
导入系统
#这是缺失的一点
def definitionwhichWidgetHadLastFocus():
对于QApplication.instance().topLevelWidgets()中的小部件:
如果isinstance(小部件、InputWidget):
#做一些奇妙的事情来确定这个小部件
#是最后一个焦点
精彩的=真实的
如果精彩的话:
返回小部件
一无所获
类BaseWidget(QWidget):
“”“基本小部件类型”“”
定义初始化(self,name):
超级(BaseWidget,self)。\uuuuu init\uuuuuuuu()
self.setWindowTitle(名称)
self.setupUi()
self.show()
def设置UI(自):
通过
类InputWidget(BaseWidget):
“”“InputWidget包含QLabel和QLineEdit小部件”“”
def设置UI(自):
self.label=QLabel(“输入字符串:”)
self.edit=QLineEdit()
布局=QHBoxLayout(自身)
layout.addWidget(self.label)
layout.addWidget(self.edit)
类HelperWidget(BaseWidget):
“”“HelperWidget包含QLineEdit和QPushButton小部件。按
该按钮将编辑小部件的内容插入到的编辑小部件中
上次激活的InputWidget“”
def设置UI(自):
self.combo=QComboBox()
self.combo.addItems([“苹果”,“梨”,“香蕉])
self.button=QPushButton(“插入”)
self.button.clicked.connect(self.insertString)
布局=QHBoxLayout(自身)
layout.addWidget(self.combo)
layout.addWidget(self.button)
def insertString(自):
widget=确定WidgetGetHadLastFocus()的位置
如果小部件:
widget.edit.insert(self.combo.currentText())
def main():
app=QApplication(sys.argv)
diag1=InputWidget(“输入对话框”)
diag2=InputWidget(“另一个输入”)
helper=HelperWidget(“helper”)
app.exec()
如果名称=“\uuuuu main\uuuuuuuu”:
main()
缺少的部分是
确定whichWidgetHadLastFocus()
函数

这个函数应该做一些很棒的事情,允许它确定哪一个“输入”是最后一个保持焦点的。目前,它从
QApplication
遍历顶级小部件列表,但顶级小部件的顺序并不反映激活顺序(通常,但并不总是显示为创建顺序)

我想到的一个想法是安装一个事件过滤器,跟踪
事件中的焦点。在我的示例中,这对于
InputWidget
类来说很容易,但是对于我的实际应用程序来说可能不太好,因为它有很多
QLineEdit
s、
qtexedit
s和所有的派生类。我不想走那条路


还有其他想法吗?

事实证明,事件过滤器的想法毕竟是可行的。我首先创建了一个事件过滤器类,如果发送对象是
QLineEdit
对象,它会发出一个信号:

从PyQt5.QtCore导入QObject、QEvent、pyqtSignal
类inputFocusFilter(QObject):
focusIn=pyqtSignal(对象)
def eventFilter(自身、小部件、事件):
如果event.type()==QEvent.FocusIn和isinstance(小部件,QLineEdit):
#发出“focusIn”信号,小部件作为其参数:
self.focusIn.emit(小部件)
返回super(inputFocusFilter,self).eventFilter(小部件,事件)
此筛选器是为自定义
QApplication
类安装的,因此创建的任何事件都会通过筛选器。信号
focusIn
连接到一个setter函数,该函数记住最后一个接收到焦点的输入小部件:

类MyApplication(QApplication):
定义初始值(self,*arg,**kwarg):
超级(MyApplication,self)。\uuuuu init\uuuuu(*arg,**kwarg)
self.\u input\u focus\u widget=None
self.event_filter=inputFocusFilter()
self.event\u filter.focusIn.connect(self.setInputFocusWidget)
self.installEventFilter(self.event\u过滤器)
def setInputFocusWidget(自我,小部件):
self.\u input\u focus\u widget=widget
def inputFocusWidget(自):
返回self.\u输入\u焦点\u小部件

main()
的第一行中使用
MyApplication
而不是
QApplication
。现在,在
HelperWidget.insertString()
中调用
确定whichWidgetHadLastFocus()
可以被
QApplication.instance().inputFocusWidget()
所取代,一切都按预期进行。

事实证明,事件过滤器的思想毕竟是一条可行之路。我首先创建了一个事件过滤器类,如果发送对象是
QLineEdit
对象,它会发出一个信号:

从PyQt5.QtCore导入QObject、QEvent、pyqtSignal
类inputFocusFilter(QObject):
focusIn=pyqtSignal(对象)
def eventFilter(自身、小部件、事件):
如果event.type()==QEven