gtkProgressBar в RGtk2 - PullRequest
       29

gtkProgressBar в RGtk2

3 голосов
/ 29 сентября 2010

Я пытаюсь добавить gtkProgressBar к небольшому интерфейсу, который я создал для скрипта R (используя пакет RGtk2).

Если я сделаю что-то простое, как:

for (i in 1:50)
    {
    gtkProgressBarSetFraction(progress, i/50)
    Sys.sleep(1)
    }

все работает гладко, и бар обновляется каждую секунду.

Однако, когда я перехожу к своему фактическому коду, у меня есть цикл, в котором я делаю что-то вроде

for(i in 1:1000)
    {
    gtkProgressBarSetFraction(progress, i/1000)
    #do some heavy computation here
    }

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

Я что-то здесь упускаю?Как я могу периодически "пробуждать" интерфейс, чтобы он обновлялся?

Спасибо nico

EDIT : ОК, я решил проблему, но я все еще не 'не понимаю, что происходит.Я добавил Sys.sleep вызов после gtkProgressBarSetFraction, и теперь интерфейс обновляется счастливо.Чтобы уменьшить «потерянное время», я просто сделал Sys.sleep(0.0001) (так что для 1000 циклов у меня было бы только ~ 0,1-1 с больше вычислительного времени, что приемлемо).Кто-нибудь может объяснить, почему это происходит?

Ответы [ 2 ]

6 голосов
/ 29 сентября 2010

Для обработки одного события: gtkMainIterationDo(FALSE). Для обработки всех ожидающих событий: while(gtkEventsPending()) gtkMainIteration().

Этот код необходим из-за способа взаимодействия циклов событий R и Gtk - в каждой точке контролируется либо R, либо Gtk, и ему необходимо вручную передать управление другому. Sys.sleep - это один из способов сделать это, а эти специальные функции RGtk2 - это другой.

2 голосов
/ 29 сентября 2010

Почти все GUI сделаны с использованием концепции, называемой циклом обработки событий. Программа имеет некоторую очередь сообщений и сама бесконечно зацикливается в процессе выбора новых сообщений из очереди и их выполнения. Очередь заполняется некоторыми событиями, полученными от ОС, такими как нажатия клавиш, щелчки мыши, изменение размеров окон и т. Д., А также сообщениями, генерируемыми самой программой. Это не похоже на это, но R также имеет свой собственный цикл событий (для графики, но не только, и он несколько расширен RGtk, и, хотя это, как правило, сложно, я не буду вдаваться в подробности).
Теперь, когда вы вызываете gtkProgressBarSetFraction, индикатор выполнения не обновляется напрямую, но сообщение с запросом на перерисовку создается и помещается в очередь. Таким образом, он не действует до тех пор, пока он не будет выбран итерацией цикла событий, но этого не произойдет, пока R не завершит выполнение вашего сценария ИЛИ, когда цикл будет запущен исключительно (по внутреннему таймауту или некоторыми функциями, такими как Sys.sleep()).

...