2013-07-23 23 views
22

Trong hộp thoại, khi nhấn phím phím, tiêu điểm sẽ thay đổi thành tiện ích con khác. Trong Qt, có bất kỳ tín hiệu nào khi một tiện ích mất tiêu điểm của nó không? Tôi có thể sử dụng nó để kiểm tra xem đầu vào có hợp lệ hay không? Nếu không, tôi có thể đặt lấy nét lại và yêu cầu người dùng nhập lại không?Tín hiệu khi một tiện ích mất tiêu điểm là gì?

+0

Nếu bạn quan tâm đến một 'QLineEdit' mất tiêu điểm, tín hiệu' QLineEdit :: editingFinished() 'sẽ nắm bắt sự kiện đó. – waldyrious

Trả lời

18

Không có tín hiệu nhưng nếu bạn muốn biết khi nào tiện ích của bạn bị mất tiêu điểm, ghi đè và thực hiện lại void QWidget::focusOutEvent(QFocusEvent* event) trong tiện ích của bạn. Nó sẽ được gọi bất cứ khi nào widget của bạn bị mất tiêu điểm. Để tập trung vào một tiện ích, hãy sử dụng QWidget::setFocus(Qt::FocusReason).

Để xác nhận đầu vào trong một QLineEdit hoặc QComboBox bạn có thể phân lớp QValidator và thực hiện xác nhận của riêng bạn, hoặc sử dụng một trong những lớp con hiện có, QIntValidator, QDoubleValidator, hoặc QRegExpValidator. Đặt trình xác thực với các số QLineEdit::setValidator(const QValidator*)QComboBox::setValidator(const QValidator*) tương ứng.

Nếu bạn muốn xác nhận nội dung của một hộp thoại modal, một trong những cách sẽ được ghi đè QDialog::exec() với một thực hiện như thế này:

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

Nó sẽ không cho phép người dùng để đóng hộp thoại với OK hoặc bất kỳ nút nào khác có vai trò Đã chấp nhận trừ khi nội dung của hộp thoại được xác thực thành công. Trong ví dụ này, tôi giả định hộp thoại có QLineEdit có tên là lineEdit và chức năng validate sẽ đảm bảo rằng nội dung của nó không trống. Nếu có, nó sẽ đặt tiêu điểm thành QLineEdit và hiển thị lại hộp thoại.

+10

Có một tín hiệu - ['QApplication :: focusChanged'] (http://qt-project.org/doc/qt-5.0/qtwidgets/qapplication.html#focusChanged). – sashoalm

+0

[sashoalm] (https://stackoverflow.com/users/492336/sashoalm) 's pithy bình luận nên là câu trả lời được chấp nhận. Tất nhiên, nó không hoạt động như thế. Xem xét upvoting [câu trả lời tương tự này] (https://stackoverflow.com/a/321677/2809027) tại [câu hỏi trùng lặp này] (https://stackoverflow.com/questions/321656/get-a-notification-event-signal -when-a-qt-widget-được-tập trung) để thay thế. '' –

6

Cũng có thể (và dễ dàng hơn) để tạo ra các tín hiệu cho mình

Trong cpp (đừng quên để bao gồm các 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); 
}; 

Và để kết nối nó:

connect(new FocusWatcher(myWidget), &FocusWatcher::focusChanged, this, &View::doSomething); 
Các vấn đề liên quan