2013-07-23 14 views
22

In una finestra, quando si preme il tasto discheda, i cambiamenti di messa a fuoco a un altro widget. In Qt, c'è qualche segnale per quando un widget perde il suo focus? Posso usarlo per verificare se l'input è valido o no? In caso contrario, posso impostare lo stato attivo e chiedere all'utente di reinserire?Qual è il segnale per quando un widget perde lo stato attivo?

+0

Se siete interessati a un 'QLineEdit' perdere la concentrazione, la' 'segnale QLineEdit :: editingFinished() cattura quell'evento. – waldyrious

risposta

18

Non c'è segnale, ma se vuoi sapere quando il tuo widget ha perso lo stato attivo, ridefinisci e reimplementa void QWidget::focusOutEvent(QFocusEvent* event) nel tuo widget. Sarà chiamato ogni volta che il tuo widget ha perso il focus. Per concentrarsi su un widget, utilizzare QWidget::setFocus(Qt::FocusReason).

per convalidare l'input in un QLineEdit o QComboBox si può sottoclasse QValidator e implementare il proprio validatore, o utilizzare una delle sottoclassi esistenti, QIntValidator, QDoubleValidator o QRegExpValidator. Impostare il validatore con rispettivamente QLineEdit::setValidator(const QValidator*) e QComboBox::setValidator(const QValidator*).

Se si desidera convalidare il contenuto di una finestra di dialogo modale, in un modo sarebbe quello di ignorare QDialog::exec() con un'implementazione del genere:

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; 
} 

Non permetterà all'utente di chiudere la finestra di dialogo con l'OK pulsante o qualsiasi altro pulsante con il ruolo accettato a meno che il contenuto della finestra di dialogo non venga convalidato correttamente. In questo esempio ho assumere la finestra di dialogo ha un nome QLineEditlineEdit e la funzione validate assicurerò che il suo contenuto non è vuoto. Se lo è, imposterà lo stato attivo su QLineEdit e mostrerà di nuovo la finestra di dialogo.

+10

C'è in realtà è un segnale - [ 'QApplication :: focusChanged'] (http://qt-project.org/doc/qt-5.0/qtwidgets/qapplication.html#focusChanged). – sashoalm

+0

[sashoalm] (https://stackoverflow.com/users/492336/sashoalm) 's commento concisa dovrebbe essere la risposta accettata. Certo, non funziona così. Considerare l'upvoting [questa risposta simile] (https://stackoverflow.com/a/321677/2809027) a [questa domanda duplicata] (https://stackoverflow.com/questions/321656/get-a-notification-event-signal -when-a-qt-widget-gets-focus). '' –

6

E 'anche possibile (e più facile) per creare il segnale da soli

Nel cpp (non dimenticate di includere la moc)

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); 
}; 

E per collegarlo:

connect(new FocusWatcher(myWidget), &FocusWatcher::focusChanged, this, &View::doSomething); 
Problemi correlati