Изменение значения FLTK и перерисовка ждут до обратного вызова: как-нибудь обойти это?

Я новичок в графическом интерфейсе и изучаю FLTK, чтобы создать многоплатформенное приложение. В приложении пользователь нажимает кнопку и вызывает требующую много времени функцию посредством обратного вызова. Поскольку это занимает много времени, я хотел бы обновить виджет вывода с ходом выполнения функции. Таким образом, я передаю указатель на виджет Fl_Ouput и обновляю его с помощью widget->value(x) и widget->redraw(). Однако виджет перерисовывается только тогда, когда вся функция обратного вызова завершена, что делает все это бессмысленным, поскольку он не обновляет пользователя в режиме реального времени. Код имеет вид:

void calculate(Fl_Widget* widget,Fl_Output* op){

    /*function call to actual code but contains inside a loop:*/
    stringstream progress;
    progress<<p; //where p is some percentage calculated on the fly in the function
    op->value(progress.str().c_str());
    op->redraw();
}
int main(){

    /*main and GUI code*/
    Fl_Output* op = new Fl_Output(100,50,100,10,0);
    Fl_Button* go = new Fl_Button(100,100,10,10,"Go");
    go->callback((Fl_Callback*) calculate,op);
    /*rest of GUI code and main*/     
}

Моя проблема в том, что виджет, на который указывает op, не перерисовывается последовательно, когда я этого хочу, когда вызывается op->redraw(), а только после того, как остальная часть кода в calculate выполнена или, как я подозреваю, когда управление покидает функцию обратного вызова после завершения ее выполнения.

Мой вопрос: есть ли способ обновить такой виджет в режиме реального времени, когда его значение изменяется и перед выполнением какого-либо другого кода (что может быть, пока управление передается функции)? Или есть лучший способ?

Спасибо,

R.


person user3353819    schedule 26.02.2014    source источник


Ответы (1)


Я предполагаю, что вы не показали нам фактический код C++, в котором действительно проявляется проблема, поэтому я предполагаю, что вы выполняете длительную обработку в цикле графического интерфейса, что всегда плохо. идея.

Чтобы увидеть почти идиоматическое решение FLTK, проверьте пример потоков в тестовом каталоге (вам нужно загрузить исходный код FLTK — это хорошая идея, чтобы просмотреть все примеры FLTK — именно так я изучил FLTK почти 2 десятилетия назад).

Руководство FLTK затрагивает тему многопоточности на этой странице: http://www.fltk.org/doc-1.3/advanced.html .

person DejanLekic    schedule 26.02.2014
comment
Спасибо за ваш ответ... Кстати, я нашел то, что искал отдельно, это Fl::check(); который сделал работу, но я понимаю вашу точку зрения. Я вижу много литературы, в которой объясняются очень базовые принципы многопоточности на основе потоковой передачи некоторых простых функций, и я понимаю принцип мьютексирования с помощью lock() и unlock(), но не могу найти реальных примеров того, как это сделать на самом деле в практика: т.е. я не знаю, как настроить поток, который будет обрабатывать определенные (длительные) функции при нажатии определенных кнопок (например, обратные вызовы). Есть ли у вас какие-либо советы для этого? - person user3353819; 27.02.2014
comment
Снова возьмите исходный код FLTK, перейдите в тестовый каталог и проверьте файлы threads.cxx и threads.h. Это очень хороший пример того, как создать поток, выполняющий длительный процесс, и как обновить графический интерфейс. :) - person DejanLekic; 27.02.2014