2013-07-23 11 views
22

Wenn in einem Dialogfeld die Taste Tab gedrückt wird, wechselt der Fokus zu einem anderen Widget. Gibt es in Qt ein Signal dafür, wenn ein Widget seinen Fokus verliert? Kann ich damit überprüfen, ob die Eingabe gültig ist oder nicht? Wenn nicht, kann ich den Fokus zurückstellen und den Benutzer zur erneuten Eingabe auffordern?Was ist das Signal, wenn ein Widget den Fokus verliert?

+0

Wenn Sie daran interessiert sind, dass 'QLineEdit' den Fokus verliert, erfasst das' QLineEdit :: editingFinished() 'Signal dieses Ereignis. – waldyrious

Antwort

18

Es gibt kein Signal, aber wenn Sie wissen möchten, wann Ihr Widget den Fokus verloren hat, überschreiben Sie void QWidget::focusOutEvent(QFocusEvent* event) in Ihrem Widget und implementieren es neu. Es wird immer dann aufgerufen, wenn Ihr Widget den Fokus verloren hat. Verwenden Sie QWidget::setFocus(Qt::FocusReason), um den Fokus auf ein Widget zu legen.

Zur Validierung Eingang in einem QLineEdit oder QComboBox können Sie QValidator Unterklasse und die eigenen Validator implementieren, oder eine der bestehenden Unterklassen verwenden, QIntValidator, QDoubleValidator oder QRegExpValidator. Stellen Sie den Validator mit QLineEdit::setValidator(const QValidator*) bzw. QComboBox::setValidator(const QValidator*) ein.

Wenn Sie den Inhalt eines modalen Dialogfeld überprüfen möchten, wäre eine Möglichkeit, QDialog::exec() mit einer Implementierung wie diese außer Kraft zu setzen sein:

int MyDialog::exec() { 
    while (true) { 
    if (QDialog::exec() == QDialog::Rejected) { 
     return QDialog::Rejected; 
    } 
    if (validate()) { 
     return QDialog::Accepted; 
    } 
    } 
} 

bool MyDialog::validate() { 
    if (lineEdit->text().isEmpty()) { 
    QMessageBox::critical(this, "Invalid value", "The specified value is not valid"); 
    lineEdit->setFocus(); 
    lineEdit->selectAll(); 
    return false; 
    } 
    return true; 
} 

Es wird nicht dem Benutzer ermöglichen, den Dialog mit dem OK zu schließen Schaltfläche oder eine andere Schaltfläche mit der Rolle Akzeptiert, sofern der Inhalt des Dialogfelds nicht erfolgreich validiert wurde. In diesem Beispiel nehme ich an, dass der Dialog eine QLineEdit mit dem Namen lineEdit hat und die validate-Funktion sicherstellt, dass der Inhalt nicht leer ist. Wenn dies der Fall ist, wird der Fokus auf QLineEdit gesetzt und der Dialog erneut angezeigt.

+10

Es gibt tatsächlich ein Signal - ['QApplication :: focusChanged'] (http://qt-project.org/doc/qt-5.0/qtwidgets/qapplication.html#focusChanged). – sashoalm

+0

[sashoalm] (https://stackoverflow.com/users/492336/ashoalm) sollte der prägnante Kommentar die akzeptierte Antwort sein. Natürlich funktioniert das nicht so. Erwägen Sie, [[diese ähnliche Antwort] ([https://stackoverflow.com/a/321677/2809027]) [bei dieser doppelten Frage] (https://stackoverflow.com/questions/321656/get-a-notification-event-signal) zu upvotieren -wenn-a-qt-widget-ruft-focus) statt. '' –

6

Es ist auch möglich (und einfacher), um das Signal zu erzeugen, selbst

In der CPP (nicht zu vergessen die moc enthalten)

class FocusWatcher : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit FocusWatcher(QObject* parent = nullptr) : QObject(parent) 
    { 
     if (parent) 
     parent->installEventFilter(this); 
    } 
    virtual bool eventFilter(QObject *obj, QEvent *event) override 
    { 
     Q_UNUSED(obj) 
     if (event->type() == QEvent::FocusIn) 
     emit focusChanged(true); 
     else if (event->type() == QEvent::FocusOut) 
     emit focusChanged(false); 

     return false; 
    } 

Q_SIGNALS: 
    void focusChanged(bool in); 
}; 

Und es zu verbinden:

connect(new FocusWatcher(myWidget), &FocusWatcher::focusChanged, this, &View::doSomething); 
Verwandte Themen