Как добавить тайм-аут во всплывающий диалог FLTK
Я использую библиотеку FLTK и использовал всплывающую функцию fl_input()
от Fl_ask.h
, Я хочу функцию, которая, если пользователь не вводит и данные в течение 3 секунд, функция должна вернуться. Как я могу вернуть эту функцию без нажатия OK
или же cancel
, Есть ли в любом случае, чтобы получить ручку для этого всплывающего диалога? Это код, который я использую
const char *message = "Enter name here";
Fl::lock();
char *c = (char*)fl_input(message, "");
if(c == NULL)
c = "";
Fl::unlock();
1 ответ
Вы не можете сделать это легко, используя fl_input, потому что у окна нет дескриптора. Посмотрите на источник fl_input в src/fl_ask.cxx. Вы увидите, что он вызывает input_innards. Если вы перейдете к input_innards, вы увидите, что он вызывает innards. Если вы затем следуете внутренностям, вы найдете цикл while, который читает
while (message_form->shown()) Fl::wait();
Сделайте копию fl_ask.cxx, скажем, timed_ask.cxx. Сделайте все подпрограммы fl_ статическими. Измените fl_input следующим образом:
const char* timed_input(double timeout, const char *fmt, const char *defstr, ...) {
if (avoidRecursion) return 0;
va_list ap;
va_start(ap, defstr);
const char* r = timed_input_innards(timeout, fmt, ap, defstr, FL_NORMAL_INPUT);
va_end(ap);
return r;
}
Сделайте копию input_innards и переименуйте новую в timed_input_innards (это сделает другие fl_routines счастливыми, если вы не захотите их удалить).
static const char* timed_input_innards(double timeout, const char* fmt, va_list ap,
const char* defstr, uchar type) {
...
int r = timed_innards(timeout, fmt, ap, fl_cancel, fl_ok, 0);
...
Сделайте копию innards и переименуйте новую в timed_innards
static int timed_innards(double timeout, const char* fmt, va_list ap,
const char *b0,
const char *b1,
const char *b2)
{
...
Fl::add_timeout(timeout, hide_form, message_form);
while (message_form->shown()) Fl::wait();
...
}
Добавьте процедуру ожидания
void hide_form(void* data)
{
// You could do this or use message_form directly
Fl_Window* form = reinterpret_cast<Fl_Window*>(data);
form->hide();
}
Это приведет к тому, что message_form->selected () будет ложным, и выйдет из цикла while.