Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Gtk ProgressBar
Форум на CrossPlatform.RU > Библиотеки > GTK+
Koloyar
Доброго времени суток!

Хочу попросить совета у знающих людей, в связи с возникшей проблемой:

Пишу программу на чистом Си. Набросал простенький гтк-шный интерфейс - кнопка запуска, и несколько полей ввода данных. По нажатию кнопки вызывается функция продолжительного расчета (довольно таки долго крутящийся цикл for). Хочется чтобы в момент расчета (от 10 секунд до 5 минут в зависимости от параметров) выводилась вторая формочка с надписью уровня "подождите" и прогрессбаром, который бы двигался пропорционально итеррациям цикла. Если по какой-то причине проще было бы выводить в прогессбар лежащий на главной форме (положу туда если надо будет), то с радостью приму и такой вариант.

пример:

int long_time_func (int param1, int param2) //ф-я с долгим циклом
{
  int i;
  for(i=0; i<1000;++i)
  {
    /*действия над параметрами*/

   gtk_progress_bar_set_fraction(progressbar1, i/1000);
   gdk_flush();
  }

  return 0;
}




void on_btncalc_clicked  (GtkObject *object, gpointer user_data)  //ф-я нажатия кнопки
{
    long_time_func (pa1, pa2);
}


Естественно результатом является то, что программа подвисает на время расчета и прогрессбар не двигается, а затем, по окончанию расчета, он сразу заполняется на 100%


Очень надеюсь на вашу помощь.
RazrFalcon
Или запускать в отдельном потоке обработку. Что бы не вешать гуй.
Или обработку делать прямо во "второй формочке".
Koloyar
RazrFalcon, спасибо, что откликнулись! Пробовал запускать во втором потоке, но эффекта было 0, возможно делал что-то не верно. А в чем разница между "запускать обработку во второй формочке" и тем, что "прогрессбар может быть и на главной форме" суть не меняется, а прогресс бар не перерисовывается :( ?

Не могли бы вы указать примерную логику запуска потока с отработкой функции с долгим циклом, и отсылку из него команды для progressbar'а.
RazrFalcon
Ну если нужен гуй и сложная обработка, то обязательно нужен второй поток.
С GTK+ никогда не сталкивался.

1) Нужно создать 2-й поток, независимый от первого. Он выполнит работу, а затем должен вернуть аргументы. Это зависит от Вас конечно. Тогда гуй не зависнет.
2) Вы создаете новую форму, при создании передаете входные данные. На ней же находится прогрессбар. И в ней выполняете свою обработку и двигаете скрол бар этой же формы. Но скорее всего тоже потухнет приложение.
3) Можно сделать обработку в главном окне, а на втором окне, который будет содержать только прогрессбар, двигать его. Тогда зависнет только главная форма. Так обычно и делают. В Qt - это QProgressDialog. Что это в GTK+ без понятия.
Koloyar
RazrFalcon, логика поведения мне как раз понятно, у меня были проблемы с реализацией именно на GTK. Но в итоге я справился с проблемой, привожу примерный код: может кому еще пригодится, во всяком случае я больше нигде не встречал рассмотрения GTK progressbara в этом ключе:

void on_btncalc_clicked  (GtkObject *object, gpointer user_data)  //ф-я нажатия кнопки
{
   g_thread_create_full(thread_func,user_data,0,TRUE,FALSE,G_THREAD_PRIORITY_LOW,&error);  //порождаем поток  
}


gpointer   thread_func(gpointer data)
{
   printf("сообщение из потока:\n");

   long_time_func (pa1, pa2);         //наша ф-я с циклом

   g_thread_exit(GINT_TO_POINTER(10));  

   return NULL;
}

int long_time_func (int param1, int param2) //ф-я с долгим циклом
{
  int i;
  for(i=0; i<1000;++i)
  {
    /*действия над параметрами*/
  
      gdk_threads_enter ();  //приостанавливаем поток
        gtk_progress_bar_set_fraction(progressbar1, i/1000);     изменяем прогресбар на форме, следовательно наход. в др. потоке
        gdk_flush();  
      gdk_threads_leave ();   //запускаем поток дальше
  }
  return 0;
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2020 IPS, Inc.