Есть ли альтернативное решение для вызова лямбда-функции QTimer::singleshot(0)
Я только что реализовал QLineEdit
это выбирает текст сразу после получения фокуса. Я создал производный класс и добавил
virtual void focusInEvent(QFocusEvent *event) override;
в шапку. Сначала я попытался реализовать это так:
void MyLineEdit::focusInEvent(QFocusEvent *event)
{
QLineEdit::focusInEvent(event);
selectAll();
}
но он не выделил бы текст, так как, по-видимому, некоторые вещи еще не были обработаны selectAll()
называется.
Рабочим решением является поставить selectAll()
позвонить в QTimer::singleShot
лямбда звонить с 0 секунд ожидания вот так:
void MyLineEdit::focusInEvent(QFocusEvent *event)
{
QLineEdit::focusInEvent(event);
QTimer::singleShot(0, [this]() { selectAll(); } );
}
Это позволяет все обрабатывать раньше selectAll()
вызывается и все работает нормально.
Это только один пример, я уже сталкивался с этой проблемой несколько раз. Так что мне интересно, есть ли предопределенный способ сказать Qt "Выполнить следующее, но обработать все остальное раньше"?
2 ответа
Вы могли бы сделать это:
QMetaObject::invokeMethod(this, "selectAll", Qt::QueuedConnection);
Это спорно, является ли это лучше, хотя; также это работает только для слотов и других invokables, объявленных с Q_INVOKABLE
и не для всех методов.
Стилистически я согласен с вами, что было бы неплохо иметь API для этого; QTimer::singleShot()
конструкция выглядит немного странно (но работает отлично).
В определении класса добавьте код:
signals:
void focusIn();
в функции конструктора добавьте код:
connect(this, &MyLineEdit::focusIn, this, &QLineEdit::selectAll, Qt::QueuedConnection);
в функцию focusInEvent добавьте код:
emit this->focusIn();
работать отлично!