Ich mag hatte die folgende Funktionalität in meine Qt-Anwendung implementieren:QWidget bestimmen, die zuletzt Fokus vor Taste drücken
- Benutzer öffnen eine oder mehr ‚Input‘ Widgets (Instanzen einer
InputWidget
Klasse), das jeweils eine AufnahmeQLineEdit
Widget - Benutzer öffnet ein 'Helfer' Dialog
- Benutzer einen Wert in der 'Helfer' Dialog wählt
- Benutzer drückt die 'Einfügen'
QPushButton
im 'Helfer' Dialog - Der ausgewählte Wert aus der ‚Helfer‘ Dialogeingabe ‚Dialog, der den letzten Fokus hatte, bevor das‚‘in die
QLineEdit
diesen eingefügt‘ Button‘Einfügen grundsätzlich So
, gedrückt wurde, was ich will, ist Wenn der Benutzer im folgenden Screenshot auf "Einfügen" klickt, sollte die Zeichenfolge "Apple" im fokussierten Eingabedialog erscheinen. Das folgende Codebeispiel funktioniert, nur dass die Zeichenfolge (normalerweise, siehe unten) in die zweite eingefügt wird.
Hier ist das Codebeispiel, das dieses Setup erstellt:
from PyQt5.QtWidgets import (QApplication, QWidget, QHBoxLayout,
QLineEdit, QLabel, QPushButton, QComboBox)
import sys
# this is the missing bit
def determineWhichWidgetHadLastFocus():
for widget in QApplication.instance().topLevelWidgets():
if isinstance(widget, InputWidget):
# do something wonderful to determine whether this widget
# is the one that had last focus
wonderful = True
if wonderful:
return widget
return None
class BaseWidget(QWidget):
""" Base widget type """
def __init__(self, name):
super(BaseWidget, self).__init__()
self.setWindowTitle(name)
self.setupUi()
self.show()
def setupUi(self):
pass
class InputWidget(BaseWidget):
""" InputWidget contains a QLabel and a QLineEdit widget """
def setupUi(self):
self.label = QLabel("Input string:")
self.edit = QLineEdit()
layout = QHBoxLayout(self)
layout.addWidget(self.label)
layout.addWidget(self.edit)
class HelperWidget(BaseWidget):
""" HelperWidget contains a QLineEdit and a QPushButton widget. Pressing
the button inserts the content of the edit widget into the edit widget of
the last activated InputWidget """
def setupUi(self):
self.combo = QComboBox()
self.combo.addItems(["Apple", "Pear", "Banana"])
self.button = QPushButton("Insert")
self.button.clicked.connect(self.insertString)
layout = QHBoxLayout(self)
layout.addWidget(self.combo)
layout.addWidget(self.button)
def insertString(self):
widget = determineWhichWidgetHadLastFocus()
if widget:
widget.edit.insert(self.combo.currentText())
def main():
app = QApplication(sys.argv)
diag1 = InputWidget("Input dialog")
diag2 = InputWidget("Another input")
helper = HelperWidget("Helper")
app.exec_()
if __name__ == "__main__":
main()
Der fehlende Teil ist die determineWhichWidgetHadLastFocus()
Funktion.
Diese Funktion soll etwas Wunderbares tun, das es ermöglicht, zu bestimmen, welcher 'Eingang' zuletzt der Fokus war. Derzeit durchläuft es die Liste der Top-Level-Widgets von QApplication
, aber die Reihenfolge der Top-Level-Widgets spiegelt nicht die Aktivierungsreihenfolge wider (normalerweise, aber scheint nicht immer die Reihenfolge der Erstellung zu sein).
Eine Idee, die mir einfiel, war, einen Ereignisfilter zu installieren, der die FocusIn
Ereignisse verfolgt. Das wäre für die Klasse InputWidget
in meinem Beispiel einfach, aber funktioniert möglicherweise nicht so gut für meine reale Anwendung, die viele QLineEdit
s, QTextEdit
s und abgeleiteten Klassen überall hat. Ich würde lieber nicht so gehen.
Irgendwelche anderen Ideen?